Ejemplo n.º 1
0
 internal State(ClrRuntime runtime, IDebugControl debugControl)
 {
     Runtime               = runtime;
     DebugControl          = debugControl;
     Todo                  = new Queue <MethodInfo>();
     HandledMetadataTokens = new HashSet <uint>();
 }
Ejemplo n.º 2
0
 public string Execute(IDebugClient Client, IDebugControl Control, string Command)
 {
     try
     {
         Clear();
         Client.SetOutputMask(SupportedMasks);
         Client.SetOutputCallbacks(this);
         //Application.DoEvents();
         //DEBUG_STATUS status;
         //Control.GetExecutionStatus(out status);
         //DebugApi.WriteLine("Execution status {0}", status.ToString());
         Control.Execute(DEBUG_OUTCTL.THIS_CLIENT |
                         DEBUG_OUTCTL.NOT_LOGGED, Command, DEBUG_EXECUTE.NOT_LOGGED |
                         DEBUG_EXECUTE.NO_REPEAT);
         //int res = 0;
         //do
         //{
         //    res = Control.WaitForEvent(DEBUG_WAIT.DEFAULT, 10000);
         //    if(res == 1) WinApi.SetStatusBarMessage("10 seconds elapsed");
         //    //DebugApi.DebugWriteLine("10 seconds elapsed");
         //} while (res == 1  /* ResultCom.S_FALSE */);
     }
     finally
     {
         Client.SetOutputCallbacks(null);
     }
     return(Text);
 }
Ejemplo n.º 3
0
        public Debugger(IDebugClient5 client, IDebugControl control)
        {
            _client  = client;
            _control = control;

            client.SetOutputCallbacks(this);
        }
Ejemplo n.º 4
0
        public DataTarget LoadFullDumpWithDbgEng(GCMode gc = GCMode.Workstation)
        {
            Guid guid = new Guid("27fe5639-8407-4f47-8364-ee118fb08ac8");
            int  hr   = DebugCreate(guid, out IntPtr pDebugClient);

            if (hr != 0)
            {
                throw new Exception($"Failed to create DebugClient, hr={hr:x}.");
            }

            IDebugClient  client  = (IDebugClient)Marshal.GetTypedObjectForIUnknown(pDebugClient, typeof(IDebugClient));
            IDebugControl control = (IDebugControl)client;

            string dumpPath = BuildDumpName(gc, true);

            hr = client.OpenDumpFile(dumpPath);
            if (hr != 0)
            {
                throw new Exception($"Failed to OpenDumpFile, hr={hr:x}.");
            }

            hr = control.WaitForEvent(DEBUG_WAIT.DEFAULT, 10000);

            if (hr != 0)
            {
                throw new Exception($"Failed to attach to dump file, hr={hr:x}.");
            }

            Marshal.Release(pDebugClient);
            return(DataTarget.CreateFromDbgEng(pDebugClient));
        }
Ejemplo n.º 5
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="ExecuteWrapper" /> class.
        /// </summary>
        /// <param name="client">The client.</param>
        public ExecuteWrapper(IDebugClient client, IDebugControl control)
        {
            _client  = client;
            _control = control;

            client.GetOutputCallbacks(out _old); // todo: error check
            client.SetOutputCallbacks(this);
        }
Ejemplo n.º 6
0
        internal static IDebugControl GetDebugControl(this IntPtr debugClient)
        {
            if (_debugControl == null)
            {
                _debugControl = (IDebugControl)debugClient.GetIUnknown();
            }

            return(_debugControl);
        }
Ejemplo n.º 7
0
        public dbgeng()
        {
            var     guid = new Guid("27fe5639-8407-4f47-8364-ee118fb08ac8");
            HResult hr   = DebugCreate(guid, out pDebugClient);

            if (!hr.IsOK)
            {
                throw new Exception(string.Format("Failed to create DebugClient, hr={0:x}.", hr));
            }

            client  = (IDebugClient)Marshal.GetTypedObjectForIUnknown(pDebugClient, typeof(IDebugClient));
            control = (IDebugControl)Marshal.GetTypedObjectForIUnknown(pDebugClient, typeof(IDebugControl));
        }
Ejemplo n.º 8
0
        public static bool CheckActiveTarget(IDebugControl dbgControl)
        {
            dbgControl.GetDebuggeeType(out DEBUG_CLASS debugClass, out DEBUG_CLASS_QUALIFIER qualifier);

            if (debugClass != DEBUG_CLASS.USER_WINDOWS ||
                (debugClass == DEBUG_CLASS.USER_WINDOWS && qualifier == DEBUG_CLASS_QUALIFIER.USER_WINDOWS_SMALL_DUMP))
            {
                dbgControl.Output(DEBUG_OUTPUT.NORMAL, $"The current target is not a user-mode target.\n");
                dbgControl.Output(DEBUG_OUTPUT.NORMAL, $"DebuggeeType: {debugClass}, {qualifier}.\n");
                return(false);
            }

            return(true);
        }
Ejemplo n.º 9
0
        public void Execute(CommandExecutionContext context)
        {
            _context = context;

            ClrMethod method = context.Runtime.GetMethodByAddress(InstructionPointer);
            if (method == null)
            {
                context.WriteError("There is no managed method at the address {0:x16}.", InstructionPointer);
                return;
            }

            _sourceFileCache = new Dictionary<string, string[]>();
            using (var target = context.CreateTemporaryDbgEngTarget())
            {
                _control = (IDebugControl)target.DebuggerInterface;
                DisassembleMethod(method);
            }
        }
Ejemplo n.º 10
0
        public void Execute(CommandExecutionContext context)
        {
            _context = context;

            ClrMethod method = context.Runtime.GetMethodByAddress(InstructionPointer);

            if (method == null)
            {
                context.WriteError("There is no managed method at the address {0:x16}.", InstructionPointer);
                return;
            }

            _sourceFileCache = new Dictionary <string, string[]>();
            using (var target = context.CreateTemporaryDbgEngTarget())
            {
                _control = (IDebugControl)target.DebuggerInterface;
                DisassembleMethod(method);
            }
        }
Ejemplo n.º 11
0
        public Debugger LaunchProcess(string commandLine, string workingDirectory)
        {
            IDebugClient5 client  = CreateIDebugClient();
            IDebugControl control = (IDebugControl)client;

            if (string.IsNullOrEmpty(workingDirectory))
            {
                workingDirectory = Environment.CurrentDirectory;
            }

            string env = GetEnvironment();
            DEBUG_CREATE_PROCESS_OPTIONS options = new DEBUG_CREATE_PROCESS_OPTIONS();

            options.CreateFlags = (DEBUG_CREATE_PROCESS)1;
            int hr = client.CreateProcessAndAttach2(0, commandLine, ref options, (uint)Marshal.SizeOf(typeof(DEBUG_CREATE_PROCESS_OPTIONS)), workingDirectory, env, 0, DEBUG_ATTACH.DEFAULT);

            if (hr < 0)
            {
                throw new Exception(Debugger.GetExceptionString("IDebugClient::CreateProcessAndAttach2", hr));
            }

            Debugger debugger = new Debugger(client, control);

            hr = client.SetEventCallbacks(debugger);
            if (hr < 0)
            {
                throw new Exception(Debugger.GetExceptionString("IDebugClient::SetEventCallbacks", hr));
            }

            hr = client.SetOutputCallbacks(debugger);
            if (hr < 0)
            {
                throw new Exception(Debugger.GetExceptionString("IDebugClient::SetOutputCallbacks", hr));
            }

            return(debugger);
        }
Ejemplo n.º 12
0
        public Debugger(IDebugClient5 client, IDebugControl control)
        {
            _client = client;
            _control = control;

            client.SetOutputCallbacks(this);
        }
Ejemplo n.º 13
0
 public DbgEngStream(IDebugClient client)
 {
     m_client = client;
     m_control = (IDebugControl)client;
 }
Ejemplo n.º 14
0
 internal DebuggerOutput(IDebugClient client)
 {
     this.client  = client;
     this.control = (IDebugControl)client;
 }
Ejemplo n.º 15
0
 public DbgEngStream(IDebugClient client)
 {
     m_client  = client;
     m_control = (IDebugControl)client;
 }
Ejemplo n.º 16
0
        /// <summary>
        /// See https://github.com/goldshtn/msos/commit/705d3758d15835d2520b31fcf3028353bdbca73b#commitcomment-12499813
        /// and https://github.com/Microsoft/dotnetsamples/blob/master/Microsoft.Diagnostics.Runtime/CLRMD/ClrMemDiag/Debugger/IDebugControl.cs#L126-L156
        /// </summary>
        private void PrintAssemblyCode(ClrMethod method, IList<ILToNativeMap> ilMaps, ClrRuntime runtime, IDebugControl debugControl)
        {
            // This is the first instruction of the JIT'ed (or NGEN'ed) machine code.
            ulong startAddress = ilMaps.Select(entry => entry.StartAddress).Min();

            // Unfortunately there's not a great way to get the size of the code, or the end address.
            // You are supposed to do code flow analysis like "uf" in windbg to find the size, but
            // in practice you can use the IL to native mapping:
            ulong endAddress = ilMaps.Select(entry => entry.EndAddress).Max();

            var bufferSize = 500; // per-line
            var lineOfAssembly = new StringBuilder(bufferSize);
            ulong startOffset = startAddress, endOffset;
            uint disassemblySize;
            do
            {
                var flags = DEBUG_DISASM.EFFECTIVE_ADDRESS;
                var result = debugControl.Disassemble(startOffset, flags, lineOfAssembly, bufferSize, out disassemblySize, out endOffset);
                startOffset = endOffset;
                logger?.Write(lineOfAssembly.ToString());

                if (lineOfAssembly.ToString().Contains(" call ") == false)
                    continue;

                var methodCallInfo = GetCalledMethodFromAssemblyOutput(runtime, lineOfAssembly.ToString());
                if (string.IsNullOrWhiteSpace(methodCallInfo) == false)
                    logger?.WriteLine(LogKind.Info, $"  {methodCallInfo}");
            } while (disassemblySize > 0 && endOffset <= endAddress);
            logger?.WriteLine();
        }
        /// <summary>
        /// See https://github.com/goldshtn/msos/commit/705d3758d15835d2520b31fcf3028353bdbca73b#commitcomment-12499813
        /// and https://github.com/Microsoft/dotnetsamples/blob/master/Microsoft.Diagnostics.Runtime/CLRMD/ClrMemDiag/Debugger/IDebugControl.cs#L126-L156
        /// </summary>
        private void PrintAssemblyCode(ClrMethod method, IList <ILToNativeMap> ilMaps, ClrRuntime runtime, IDebugControl debugControl)
        {
            // This is the first instruction of the JIT'ed (or NGEN'ed) machine code.
            ulong startAddress = ilMaps.Select(entry => entry.StartAddress).Min();

            // Unfortunately there's not a great way to get the size of the code, or the end address.
            // You are supposed to do code flow analysis like "uf" in windbg to find the size, but
            // in practice you can use the IL to native mapping:
            ulong endAddress = ilMaps.Select(entry => entry.EndAddress).Max();

            var   bufferSize = 500; // per-line
            var   lineOfAssembly = new StringBuilder(bufferSize);
            ulong startOffset = startAddress, endOffset;
            uint  disassemblySize;

            do
            {
                var flags  = DEBUG_DISASM.EFFECTIVE_ADDRESS;
                var result = debugControl.Disassemble(startOffset, flags, lineOfAssembly, bufferSize, out disassemblySize, out endOffset);
                startOffset = endOffset;
                logger?.Write(lineOfAssembly.ToString());

                if (lineOfAssembly.ToString().Contains(" call ") == false)
                {
                    continue;
                }

                var methodCallInfo = GetCalledMethodFromAssemblyOutput(runtime, lineOfAssembly.ToString());
                if (string.IsNullOrWhiteSpace(methodCallInfo) == false)
                {
                    logger?.WriteLine(BenchmarkLogKind.Info, $"  {methodCallInfo}");
                }
            } while (disassemblySize > 0 && endOffset <= endAddress);
            logger?.WriteLine();
        }
Ejemplo n.º 18
0
 public DebugEngineStream(IDebugClient debugClient)
 {
     this.debugClient  = debugClient;
     this.debugControl = (IDebugControl)debugClient;
 }
Ejemplo n.º 19
0
 public DebugEngineStream(IDebugClient client)
 {
     _client  = client;
     _control = (IDebugControl)client;
 }
Ejemplo n.º 20
0
 public CommandExecutor(IDebugControl control)
 {
     _control = control;
 }
Ejemplo n.º 21
0
        private static int ConnectDebuggerLiveHelper(DebugUtilities debugUtilities, uint processID, bool passive, out SimpleDebugger debuggerInformation)
        {
            int hr;

            IDebugControl       debugControl       = null;
            IDebugSystemObjects debugSystemObjects = null;

            SimpleOutputHandler debuggerOutputCallbacks = null;
            SimpleEventHandler  debuggerEventCallbacks  = null;

            debuggerInformation = null;

            hr = SimpleOutputHandler.Install(debugUtilities, out debuggerOutputCallbacks);
            if (hr != S_OK)
            {
                goto Error;
            }

            hr = SimpleEventHandler.Install(debugUtilities, out debuggerEventCallbacks);
            if (hr != S_OK)
            {
                goto ErrorWithDetach;
            }

            DEBUG_ATTACH attachFlags = passive ? DEBUG_ATTACH.NONINVASIVE | DEBUG_ATTACH.NONINVASIVE_NO_SUSPEND : DEBUG_ATTACH.INVASIVE_RESUME_PROCESS;

            hr = debugUtilities.DebugClient.AttachProcess(0, processID, attachFlags);
            if (hr != S_OK)
            {
                goto ErrorWithDetach;
            }

            while (debuggerEventCallbacks.SessionIsActive == false)
            {
                hr = debugControl.WaitForEvent(DEBUG_WAIT.DEFAULT, 50);
                if (FAILED(hr))
                {
                    goto ErrorWithDetach;
                }
            }

            bool foundMatchingProcess = false;
            uint numProcesses;

            debugSystemObjects.GetNumberProcesses(out numProcesses);
            uint[] systemProcessIDs = new uint[numProcesses];
            uint[] engineProcessIDs = new uint[numProcesses];
            hr = debugSystemObjects.GetProcessIdsByIndex(0, numProcesses, engineProcessIDs, systemProcessIDs);
            for (uint i = 0; i < numProcesses; ++i)
            {
                if (systemProcessIDs[i] == processID)
                {
                    foundMatchingProcess = true;
                    hr = debugSystemObjects.SetCurrentProcessId(engineProcessIDs[i]);
                    if (FAILED(hr))
                    {
                        debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! Failed to set the active process! hr={0:x8}", hr));
                        goto ErrorWithDetach;
                    }
                    break;
                }
            }
            if (foundMatchingProcess == false)
            {
                hr = E_FAIL;
                debuggerOutputCallbacks.AddNoteLine(String.Format(CultureInfo.InvariantCulture, "ERROR! The debugger engine could not find the requested process ID ({0})!", processID));
                goto ErrorWithDetach;
            }

            debuggerInformation = new SimpleDebugger(debugUtilities, processID, passive, debuggerOutputCallbacks, debuggerEventCallbacks);

            goto Exit;

ErrorWithDetach:
            debugUtilities.DebugClient.DetachProcesses();
            debugUtilities.DebugClient.EndSession(DEBUG_END.ACTIVE_DETACH);
Error:
            if (debuggerEventCallbacks != null)
            {
                debuggerEventCallbacks.Dispose();
            }
            if (debuggerOutputCallbacks != null)
            {
                debuggerOutputCallbacks.Dispose();
            }
Exit:
            return(hr);
        }
Ejemplo n.º 22
0
            internal DbgEngController(string dbgengPath, string dumpPath, string sosPath)
            {
                Trace.TraceInformation($"DbgEngController: {dbgengPath} {dumpPath} {sosPath}");
                _converter = new CharToLineConverter((text) => {
                    Trace.TraceInformation(text);
                });
                IntPtr dbgengLibrary = DataTarget.PlatformFunctions.LoadLibrary(dbgengPath);
                var    debugCreate   = SOSHost.GetDelegateFunction <DebugCreateDelegate>(dbgengLibrary, "DebugCreate");

                if (debugCreate == null)
                {
                    throw new DiagnosticsException($"DebugCreate export not found");
                }
                Guid    iid = _iidClient;
                HResult hr  = debugCreate(ref iid, out object client);

                if (hr != HResult.S_OK)
                {
                    throw new DiagnosticsException($"DebugCreate FAILED {hr:X8}");
                }
                Client  = (IDebugClient)client;
                Control = (IDebugControl)client;
                Symbols = (IDebugSymbols2)client;

                hr = Client.SetOutputCallbacks(this);
                if (hr != HResult.S_OK)
                {
                    throw new DiagnosticsException($"SetOutputCallbacks FAILED {hr:X8}");
                }

                // Automatically enable/adjust symbol server support. Override the default cache path so
                // the cache isn't created in the debugger binaries .nuget package cache directory.
                string cachePath = Path.Combine(Environment.GetEnvironmentVariable("PROGRAMDATA"), "dbg", "sym");
                string sympath   = $"{Path.GetDirectoryName(dumpPath)};cache*{cachePath};SRV*https://msdl.microsoft.com/download/symbols";

                hr = Symbols.SetSymbolPath(sympath);
                if (hr != HResult.S_OK)
                {
                    Trace.TraceError($"SetSymbolPath({sympath}) FAILED {hr:X8}");
                }

                // Load dump file
                hr = Client.OpenDumpFile(dumpPath);
                if (hr != HResult.S_OK)
                {
                    throw new DiagnosticsException($"OpenDumpFile({dumpPath} FAILED {hr:X8}");
                }
                ProcessEvents();

                // Load the sos extensions
                hr = Control.Execute(DEBUG_OUTCTL.ALL_CLIENTS, $".load {sosPath}", DEBUG_EXECUTE.DEFAULT);
                if (hr != HResult.S_OK)
                {
                    throw new DiagnosticsException($"Loading {sosPath} FAILED {hr:X8}");
                }

                // Initialize the extension host
                hr = HostServices.Initialize(sosPath);
                if (hr != HResult.S_OK)
                {
                    throw new DiagnosticsException($"HostServices.Initialize({sosPath}) FAILED {hr:X8}");
                }

                var symbolService = Host.Services.GetService <ISymbolService>();

                Trace.TraceInformation($"SymbolService: {symbolService}");
            }