使用c#远程向WinDbg发送命令
本文关键字:命令 WinDbg 使用 | 更新日期: 2023-09-27 17:51:01
在我的应用程序中,WinDbg启动了,我想知道是否有任何方法可以通过WinDbg发送某些命令(例如从c#应用程序发送字母k(以显示调用堆栈)?
我已经阅读了一些使用user32.dll的功能,可以帮助这一点,但我不清楚如何继续并将其包含在我的应用程序。
任何帮助都将是非常感激的。
史蒂夫如果你想完全控制调试引擎,那么你应该使用暴露的COM接口将它托管在你的c#应用程序中。
您可以在WinDbg安装目录中找到自动化调试引擎的示例代码(例如C:'Program Files (x86)'Windows Kits'8.1'Debuggers'x64'sdk'samples)。这篇博客文章展示了如何使用API(在C中)获得堆栈跟踪,因此您不必在发出k
命令后解析输出。
最困难的部分是在c#中为所有暴露的对象找到/创建所有的IDebug* [ComImport]
接口。但是一旦你有了它们,你可以这样做:
internal static class WinDbgBase
{
// STDAPI DebugCreate(__in REFIID InterfaceId, __out PVOID* Interface);
[DllImport("dbgeng.dll", EntryPoint = "DebugCreate", CallingConvention = CallingConvention.StdCall)]
public static extern int DebugCreate([In] ref System.Guid InterfaceId, ref System.IntPtr Interface);
}
Guid uuidof_IDebugClient4 = new Guid("{ca83c3de-5089-4cf8-93c8-d892387f2a5e}");
IntPtr pObj = IntPtr.Zero;
int hr = WinDbgBase.DebugCreate(ref uuidof_IDebugClient4, ref pObj);
IDebugClient4 _client = (IDebugClient4)Marshal.GetTypedObjectForIUnknown(pObj, typeof(IDebugClient4));
// QueryInterface the other objects
IDebugControl4 _control = (IDebugControl4)_client;
_client.AttachProcess(0, ProcessId, DEBUG_ATTACH.DEBUG_ATTACH_DEFAULT);
_control.WaitForEvent(DEBUG_WAIT.DEBUG_WAIT_DEFAULT, Win32.INFINITE);
...
如果您正在处理托管目标,那么甚至可以加载SOS扩展,获得托管堆栈(如前所述),然后将其与本机堆栈跟踪合并,以便您可以显示包含所有本机到托管转换的完整堆栈。
引用-所有调试器COM对象列表
无需发送按键。有一个更可靠的方法:参见.ocommand
的WinDbg帮助。它的工作原理是通过OutputDebugString发送命令,它是。net中的Debug. writeline()(调试构建)或Trace.WriteLine()(发布构建)。
当您自己启动调试器时,您可能希望在启动时立即执行.ocommand
,您可以通过添加-c
命令行开关来执行:
windbg.exe -p <PID> -c ".ocommand <Magic>;g"
这种方法是一种快捷的方法。@joshpoley的答案是,如果你想要一个长期稳定的解决方案,更清洁的方法。
注意,对于。net,本机调用栈k
可能不是你想要的。试试SOS扩展的!clrstack
或!dumpstack
(您可以根据您的。net版本使用.loadby sos clr
或.loadby sos mscorwks
加载)。