/// <summary> /// <see cref="IDkmModuleInstanceUnloadNotification"/> is implemented by components that want to listen /// for the ModuleInstanceUnload event. When this notification fires, the target process /// will be suspended and can be examined. ModuleInstanceUnload is sent when the monitor /// detects that a module has unloaded from within the target process. /// </summary> public void OnModuleInstanceUnload(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptor eventDescriptor) { if (moduleInstance is DkmClrModuleInstance clrModuleInstance) { _listener.OnManagedModuleInstanceUnloaded(clrModuleInstance); } }
public static bool HasSymbols(this DkmModuleInstance moduleInstance) { using (ComPtr <IDiaSymbol> sym = moduleInstance.TryGetSymbols()) { return(sym.Object != null); } }
internal static ulong?TryGetFunctionAddressAtDebugEnd(DkmModuleInstance moduleInstance, string name, out string error) { try { var functionSymbol = TryGetDiaFunctionSymbol(moduleInstance, name, out error); if (functionSymbol == null) { return(null); } var functionEndSymbol = TryGetDiaSymbol(functionSymbol, SymTagEnum.SymTagFuncDebugEnd, null, out error); if (functionEndSymbol == null) { ReleaseComObject(functionSymbol); return(null); } uint rva = functionEndSymbol.relativeVirtualAddress; ReleaseComObject(functionEndSymbol); ReleaseComObject(functionSymbol); return(moduleInstance.BaseAddress + rva); } catch (Exception ex) { error = "TryGetFunctionAddressAtDebugEnd() Unexpected error: " + ex.ToString(); } return(null); }
public static ComPtr <IDiaSymbol> TryGetSymbols(this DkmModuleInstance moduleInstance) { if (moduleInstance.Module == null) { return(new ComPtr <IDiaSymbol>()); } IDiaSession diaSession; try { diaSession = (IDiaSession)moduleInstance.Module.GetSymbolInterface(typeof(IDiaSession).GUID); } catch (InvalidCastException) { // GetSymbolInterface will throw this if it did locate a symbol provider object, but QueryInterface for the GUID failed with E_NOINTERFACE. // Since this means that we cannot use the symbol provider for anything useful, treat it as absence of symbol information. return(new ComPtr <IDiaSymbol>()); } using (ComPtr.Create(diaSession)) { IDiaEnumSymbols exeSymEnum; diaSession.findChildren(null, SymTagEnum.SymTagExe, null, 0, out exeSymEnum); using (ComPtr.Create(exeSymEnum)) { if (exeSymEnum.count != 1) { return(new ComPtr <IDiaSymbol>()); } return(ComPtr.Create(exeSymEnum.Item(0))); } } }
public void GetModuleVersion(uint moduleId, out int major, out int minor, out int revision, out int patch) { int tempMajor = 0, tempMinor = 0, tempRevision = 0, tempPatch = 0; ExecuteOnDkmInitializedThread(() => { DkmModuleInstance module = GetModule(moduleId); if (module.Version != null) { tempMajor = (int)(module.Version.ProductVersionMS / 65536); tempMinor = (int)(module.Version.ProductVersionMS % 65536); tempRevision = (int)(module.Version.ProductVersionLS / 65536); tempPatch = (int)(module.Version.ProductVersionLS % 65536); } else { tempMajor = tempMinor = tempRevision = tempPatch = 0; } }); major = tempMajor; minor = tempMinor; revision = tempRevision; patch = tempPatch; }
/// <summary> /// <see cref="IDkmModuleInstanceLoadNotification"/> is implemented by components that want to listen /// for the ModuleInstanceLoad event. When this notification fires, the target process /// will be suspended and can be examined. ModuleInstanceLoad is fired when a module is /// loaded by a target process. Among other things, this event is used for symbol /// providers to load symbols, and for the breakpoint manager to set breakpoints. /// ModuleInstanceLoad fires for all modules, even if there are no symbols loaded. /// </summary> void IDkmModuleInstanceLoadNotification.OnModuleInstanceLoad(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptorS eventDescriptor) { if (moduleInstance is DkmClrModuleInstance clrModuleInstance) { _listener.OnManagedModuleInstanceLoaded(clrModuleInstance); } }
public void OnModuleInstanceLoad(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptorS eventDescriptor) { if (moduleInstance.Name.Contains("mono-2.0")) { _enabled = true; } }
void IDkmModuleInstanceUnloadNotification.OnModuleInstanceUnload(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptor eventDescriptor) { if (moduleInstance is DkmClrModuleInstance clrModuleInstance) { Contract.ThrowIfNull(_encService); _encService.OnManagedModuleInstanceUnloaded(clrModuleInstance.Mvid); } }
void IDkmModuleInstanceLoadNotification.OnModuleInstanceLoad( DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptorS eventDescriptor ) { OnModuleLoad(moduleInstance, workList); }
public string GetModuleName(uint moduleId) { return(ExecuteOnDkmInitializedThread(() => { DkmModuleInstance module = GetModule(moduleId); return GetModuleName(module); })); }
/// <summary> /// Gets the version information. /// </summary> /// <param name="address">The address.</param> /// <param name="version">The version.</param> public void GetVersionInfo(ulong address, out VersionInfo version) { DkmModuleInstance module = Process.GetRuntimeInstances() .SelectMany(ri => ri.GetModuleInstances()) .FirstOrDefault(m => m.BaseAddress <= address && address < m.BaseAddress + m.Size); string versionString = module?.Version?.FileVersionString; version = ExtractVersion(versionString); }
public Tuple <DateTime, ulong> GetModuleTimestampAndSize(uint moduleId) { return(ExecuteOnDkmInitializedThread(() => { DkmModuleInstance module = GetModule(moduleId); return Tuple.Create(DateTime.FromFileTimeUtc((long)module.TimeDateStamp), (ulong)module.Size); })); }
void IDkmModuleSymbolsLoadedNotification.OnModuleSymbolsLoaded(DkmModuleInstance moduleInstance, DkmModule module, bool isReload, DkmWorkList workList, DkmEventDescriptor eventDescriptor) { var process = moduleInstance.Process; var engines = process.DebugLaunchSettings.EngineFilter; if (engines == null || !engines.Contains(AD7Engine.DebugEngineGuid)) { return; } var pyrtInfo = process.GetPythonRuntimeInfo(); var nativeModuleInstance = moduleInstance as DkmNativeModuleInstance; if (nativeModuleInstance != null) { if (PythonDLLs.CTypesNames.Contains(moduleInstance.Name)) { pyrtInfo.DLLs.CTypes = nativeModuleInstance; var traceHelper = process.GetDataItem <TraceManagerLocalHelper>(); if (traceHelper != null) { traceHelper.OnCTypesLoaded(nativeModuleInstance); } } else if (PythonDLLs.GetPythonLanguageVersion(nativeModuleInstance) != PythonLanguageVersion.None) { if (IsModuleCompiledWithPGO(moduleInstance)) { pyrtInfo.DLLs.Python = null; var pgoWarnMsg = DkmCustomMessage.Create(process.Connection, process, Guid.Empty, (int)VsPackageMessage.WarnAboutPGO, moduleInstance.Name, null); pgoWarnMsg.SendToVsService(Guids.CustomDebuggerEventHandlerGuid, IsBlocking: true); return; } } } if (process.GetPythonRuntimeInstance() != null) { return; } if (pyrtInfo.DLLs.Python != null && pyrtInfo.DLLs.Python.HasSymbols()) { if (process.LivePart == null || pyrtInfo.DLLs.DebuggerHelper != null) { CreatePythonRuntimeInstance(process); } else { InjectHelperDll(process); } } }
void IDkmModuleInstanceUnloadNotification.OnModuleInstanceUnload( DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptor eventDescriptor ) { // Implementing IDkmModuleInstanceUnloadNotification // (with Synchronized="true" in .vsdconfigxml) prevents // caller from unloading modules while binding. }
void IDkmModuleSymbolsLoadedNotification.OnModuleSymbolsLoaded( DkmModuleInstance moduleInstance, DkmModule module, bool isReload, DkmWorkList workList, DkmEventDescriptor eventDescriptor ) { OnModuleLoad(moduleInstance, workList); }
public static ComPtr <IDiaSymbol> GetSymbols(this DkmModuleInstance moduleInstance) { var result = TryGetSymbols(moduleInstance); if (result.Object == null) { Debug.Fail("Failed to load symbols for module " + moduleInstance.Name); throw new InvalidOperationException(); } return(result); }
void IDkmModuleInstanceLoadNotification.OnModuleInstanceLoad(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptorS eventDescriptor) { var nativeModuleInstance = moduleInstance as DkmNativeModuleInstance; if (nativeModuleInstance != null && PythonDLLs.CTypesNames.Contains(moduleInstance.Name)) { var pyrtInfo = moduleInstance.Process.GetPythonRuntimeInfo(); pyrtInfo.DLLs.CTypes = nativeModuleInstance; nativeModuleInstance.FlagAsTransitionModule(); } }
public static void VscxOnModuleInstanceLoad(this DkmProcess process, DkmModuleInstance module, DkmWorkList workList) { AutoAttachToChildHandler handler = process.GetDataItem <AutoAttachToChildHandler>(); if (handler == null || module.TagValue != DkmModuleInstance.Tag.NativeModuleInstance) { return; } handler.OnModuleInstanceLoad((DkmNativeModuleInstance)module, workList); }
void IDkmModuleInstanceLoadNotification.OnModuleInstanceLoad(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptorS eventDescriptor) { var module = moduleInstance as DkmClrModuleInstance; Debug.Assert(module != null); // <Filter><RuntimeId RequiredValue="DkmRuntimeId.Clr"/></Filter> should ensure this. if (module == null) { // Only interested in managed modules. return; } OnModuleLoad(module.Process, module); }
bool IDkmModuleUserCodeDeterminer.IsUserCode(DkmModuleInstance moduleInstance) { var processData = DebugHelpers.GetOrCreateDataItem <NullcRemoteProcessDataItem>(moduleInstance.Process); if (processData != null) { if (moduleInstance.LoadContext == "nullc embedded code") { return(true); } } return(moduleInstance.IsUserCode()); }
private void RemoveDataItemIfNecessary(DkmModuleInstance moduleInstance) { // If the module is not a managed module, the module change has no effect. var module = moduleInstance as DkmClrModuleInstance; if (module == null) { return; } // Drop any context cached on the AppDomain. var appDomain = module.AppDomain; RemoveDataItem(appDomain); }
void IDkmModuleModifiedNotification.OnModuleModified(DkmModuleInstance moduleInstance) { // If the module is not a managed module, the module change has no effect. var module = moduleInstance as DkmClrModuleInstance; if (module == null) { return; } // Drop any context cached on the AppDomain. var appDomain = module.AppDomain; RemoveDataItem(appDomain); }
public object GetModuleDiaSession(uint moduleId) { return(ExecuteOnDkmInitializedThread(() => { try { DkmModuleInstance module = GetModule(moduleId); return module.Module.GetSymbolInterface(Marshal.GenerateGuidForType(typeof(IDiaSession))); } catch { return null; } })); }
void IDkmModuleSymbolsLoadedNotification.OnModuleSymbolsLoaded(DkmModuleInstance moduleInstance, DkmModule module, bool isReload, DkmWorkList workList, DkmEventDescriptor eventDescriptor) { var process = moduleInstance.Process; var engines = process.DebugLaunchSettings.EngineFilter; if (engines == null || !engines.Contains(Guids.PythonDebugEngineGuid)) { return; } var pyrtInfo = process.GetPythonRuntimeInfo(); var nativeModuleInstance = moduleInstance as DkmNativeModuleInstance; if (nativeModuleInstance != null) { if (PythonDLLs.CTypesNames.Contains(moduleInstance.Name)) { pyrtInfo.DLLs.CTypes = nativeModuleInstance; var traceHelper = process.GetDataItem <TraceManagerLocalHelper>(); if (traceHelper != null) { traceHelper.OnCTypesLoaded(nativeModuleInstance); } } } if (process.GetPythonRuntimeInstance() != null) { return; } if (pyrtInfo.DLLs.Python != null && pyrtInfo.DLLs.Python.HasSymbols()) { if (process.LivePart == null || pyrtInfo.DLLs.DebuggerHelper != null) { CreatePythonRuntimeInstance(process); } else { InjectHelperDll(process); } } }
public string GetModuleSymbolName(uint moduleId) { return(ExecuteOnDkmInitializedThread(() => { DkmModuleInstance module = GetModule(moduleId); DkmSymbolFileId symbolFileId = module.SymbolFileId; if (symbolFileId.TagValue == DkmSymbolFileId.Tag.PdbFileId) { DkmPdbFileId pdbFileId = (DkmPdbFileId)symbolFileId; return pdbFileId.PdbName; } return module.FullName; })); }
void IDkmModuleInstanceLoadNotification.OnModuleInstanceLoad(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptorS eventDescriptor) { var process = moduleInstance.Process; var engines = process.DebugLaunchSettings.EngineFilter; if (engines == null || !engines.Contains(AD7Engine.DebugEngineGuid)) { return; } if (moduleInstance.RuntimeInstance == process.GetNativeRuntimeInstance()) { new LocalComponent.NativeModuleInstanceLoadedNotification { ModuleInstanceId = moduleInstance.UniqueId }.SendLower(process); } }
internal static IDiaSymbol TryGetDiaSymbols(DkmModuleInstance moduleInstance, out string error) { if (moduleInstance == null) { error = $"TryGetDiaSymbols() Module instance is null"; return(null); } if (moduleInstance.Module == null) { error = $"TryGetDiaSymbols() Module is null"; return(null); } IDiaSession diaSession; try { diaSession = (IDiaSession)moduleInstance.Module.GetSymbolInterface(typeof(IDiaSession).GUID); } catch (InvalidCastException) { error = $"TryGetDiaSymbols() diaSession InvalidCastException"; return(null); } diaSession.findChildren(null, SymTagEnum.SymTagExe, null, 0, out IDiaEnumSymbols exeSymEnum); if (exeSymEnum.count != 1) { error = $"TryGetDiaSymbols() exeSymEnum.count {exeSymEnum.count} != 1"; ReleaseComObject(diaSession); return(null); } var symbol = exeSymEnum.Item(0); ReleaseComObject(exeSymEnum); ReleaseComObject(diaSession); error = null; return(symbol); }
private void OnModuleLoad(DkmModuleInstance moduleInstance, DkmWorkList workList) { var module = moduleInstance as DkmClrModuleInstance; Debug.Assert(module != null); // <Filter><RuntimeId RequiredValue="DkmRuntimeId.Clr"/></Filter> should ensure this. if (module == null) { // Only interested in managed modules. return; } if (module.Module == null) { // Only resolve breakpoints if symbols have been loaded. return; } OnModuleLoad(module.Process, module, OnFunctionResolved(workList)); }
internal static IDiaSymbol TryGetDiaFunctionSymbol(DkmModuleInstance moduleInstance, string name, out string error) { var moduleSymbols = TryGetDiaSymbols(moduleInstance, out error); if (moduleSymbols == null) { return(null); } var functionSymbol = TryGetDiaSymbol(moduleSymbols, SymTagEnum.SymTagFunction, name, out error); if (functionSymbol == null) { ReleaseComObject(moduleSymbols); return(null); } ReleaseComObject(moduleSymbols); return(functionSymbol); }
// For PGO-enabled binaries, their symbol information is unreliable, often in dangerous ways (e.g. FuncDebugStart/End is basically garbage // for split functions, and locals can be messed up), so we do not support Python built with PGO (currently only 2.7.3 and below). private static bool IsModuleCompiledWithPGO(DkmModuleInstance moduleInstance) { using (var moduleSym = moduleInstance.GetSymbols()) { var compSyms = moduleSym.Object.GetSymbols(SymTagEnum.SymTagCompiland, null); try { foreach (var compSym in compSyms) { var blockSyms = compSym.Object.GetSymbols(SymTagEnum.SymTagBlock, null); try { foreach (var blockSym in blockSyms) { using (var parentSym = ComPtr.Create(blockSym.Object.lexicalParent)) { uint blockStart = blockSym.Object.relativeVirtualAddress; uint funcStart = parentSym.Object.relativeVirtualAddress; uint funcEnd = funcStart + (uint)parentSym.Object.length; if (blockStart < funcStart || blockStart >= funcEnd) { return(true); } } } } finally { foreach (var blockSym in blockSyms) { blockSym.Dispose(); } } } } finally { foreach (var funcSym in compSyms) { funcSym.Dispose(); } } } return(false); }