/// <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);
     }
 }
Пример #2
0
 public static bool HasSymbols(this DkmModuleInstance moduleInstance)
 {
     using (ComPtr <IDiaSymbol> sym = moduleInstance.TryGetSymbols())
     {
         return(sym.Object != null);
     }
 }
Пример #3
0
        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);
        }
Пример #4
0
        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)));
                }
            }
        }
Пример #5
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);
     }
 }
Пример #9
0
 void IDkmModuleInstanceLoadNotification.OnModuleInstanceLoad(
     DkmModuleInstance moduleInstance,
     DkmWorkList workList,
     DkmEventDescriptorS eventDescriptor
     )
 {
     OnModuleLoad(moduleInstance, workList);
 }
Пример #10
0
        public string GetModuleName(uint moduleId)
        {
            return(ExecuteOnDkmInitializedThread(() =>
            {
                DkmModuleInstance module = GetModule(moduleId);

                return GetModuleName(module);
            }));
        }
Пример #11
0
        /// <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);
        }
Пример #12
0
        public Tuple <DateTime, ulong> GetModuleTimestampAndSize(uint moduleId)
        {
            return(ExecuteOnDkmInitializedThread(() =>
            {
                DkmModuleInstance module = GetModule(moduleId);

                return Tuple.Create(DateTime.FromFileTimeUtc((long)module.TimeDateStamp), (ulong)module.Size);
            }));
        }
Пример #13
0
        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);
                }
            }
        }
Пример #14
0
 void IDkmModuleInstanceUnloadNotification.OnModuleInstanceUnload(
     DkmModuleInstance moduleInstance,
     DkmWorkList workList,
     DkmEventDescriptor eventDescriptor
     )
 {
     // Implementing IDkmModuleInstanceUnloadNotification
     // (with Synchronized="true" in .vsdconfigxml) prevents
     // caller from unloading modules while binding.
 }
Пример #15
0
 void IDkmModuleSymbolsLoadedNotification.OnModuleSymbolsLoaded(
     DkmModuleInstance moduleInstance,
     DkmModule module,
     bool isReload,
     DkmWorkList workList,
     DkmEventDescriptor eventDescriptor
     )
 {
     OnModuleLoad(moduleInstance, workList);
 }
Пример #16
0
        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);
        }
Пример #17
0
        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();
            }
        }
Пример #18
0
        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);
        }
Пример #19
0
        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);
        }
Пример #20
0
            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());
            }
Пример #21
0
        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);
        }
Пример #22
0
        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);
        }
Пример #23
0
        public object GetModuleDiaSession(uint moduleId)
        {
            return(ExecuteOnDkmInitializedThread(() =>
            {
                try
                {
                    DkmModuleInstance module = GetModule(moduleId);

                    return module.Module.GetSymbolInterface(Marshal.GenerateGuidForType(typeof(IDiaSession)));
                }
                catch
                {
                    return null;
                }
            }));
        }
Пример #24
0
        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);
                }
            }
        }
Пример #25
0
        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);
            }
        }
Пример #27
0
        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);
        }
Пример #28
0
        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));
        }
Пример #29
0
        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);
        }
Пример #30
0
 // 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);
 }