使用C#中的DbgHost.exe COM对象

时间:2012-11-25 00:14:13

标签: c# debugging com windbg

我公司的应用程序有一些响应/稳定性/内存问题。我正在尝试编写一个小助手应用程序,可以帮助我们识别这些问题。我希望这个应用程序能够在命令上生成转储并进行一些基本的自动调试,首先我试图获取目标应用程序中所有线程的所有堆栈跟踪。

所以我已经研究了一个星期左右,我找到了几种添加调试功能的方法。我发现的一些选项是使用ICorDebug,DbgEng.dll和DbgHost.exe。我真的很想使用DbgHost.exe,因为它让我能够将LeakTrack.dll注入目标进程以跟踪内存分配。

我的问题是我似乎无法让它工作,我无法在网上找到关于这两个对象DbgControl和DbgObj的任何非常好的信息。我找到了以下链接:

How to control a debugger engine?

Scripting DbgHostLib

第一篇文章解释了如何打开一个转储文件并用它做什么,第二篇文章解释了如何附加到一个进程并用它做什么。第二种是使用一些Web自动化软件。第二个正是我想要做的。

所以这是我的代码到目前为止,我只是添加了重要的代码,其余的代码只是用户界面的粘合剂。

    private void OnAttach(uint? targetProcessId)
    {
        if (targetProcessId == null || targetProcessId.Value == default(uint))
        {
            return;
        }

        Process targetProcess = Process.GetProcessById((int)targetProcessId.Value);
        if (targetProcess.HasExited)
        {
            return;
        }

        DbgControl dbgControl = new DbgControl();
        dbgControl.AttachToProcess((int)targetProcessId.Value, @"C:\scripts", @"C:\symcache", null);
        try
        {
            DbgObj dbgObj = new DbgObj();
            Debug.WriteLine(dbgObj.ThreadInfo.Count);
            foreach (ProcessThread processThread in targetProcess.Threads)
            {
                IDbgThread dbgThread = dbgObj.GetThreadBySystemID(processThread.Id);
                foreach (IDbgStackFrame dbgStackFrame in dbgThread.StackFrames)
                {
                    Debug.WriteLine(dbgStackFrame.InstructionAddress);
                }
            }
        }
        finally
        {
            dbgControl.DetachFromProcess();
        }
    }

    private void OnOpen(string dumpFilePath)
    {
        if (!File.Exists(dumpFilePath))
        {
            return;
        }

        DbgControl dbgControl = new DbgControl();
        DbgObj dbgObj = dbgControl.OpenDump(dumpFilePath, @"C:\symcache", @"C:\symcache", null);

        Debug.WriteLine(dbgObj.ThreadInfo.Count);
    }

所以OnOpen的东西有效,OnAttach的东西没有。 OnAttach代码成功附加到进程,我创建一个DbgObj甚至转储线程计数,但是当我尝试获取线程对象时它失败了。我明白了:

The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT))

当我检查EventVwr.exe时,我收到以下条目:

Faulting application name: Dbghost.exe, version: 1.2.0.52, time stamp: 0x4e164226
Faulting module name: Dbghost.exe, version: 1.2.0.52, time stamp: 0x4e164226
Exception code: 0xc0000005
Fault offset: 0x0001907d
Faulting process id: 0x2300
Faulting application start time: 0x01cdcaa0cdffbb1a
Faulting application path: C:\Program Files\DebugDiag\x86Support\Dbghost.exe
Faulting module path: C:\Program Files\DebugDiag\x86Support\Dbghost.exe
Report Id: 0bb5082a-3694-11e2-a454-d4bed9031bdf

因此DbgHost.exe遭到访问冲突。我即将放弃这个并继续采用更常见的方法,但我希望有人能提供一些指导,帮助我克服这条路。

1 个答案:

答案 0 :(得分:0)

我发现了同样的问题。 我理解这个link。我使用DebugDiag 1.2和C#进行自动转储。注意,请忽略“test.dmp”,当前我不能指定文件名,它不是我们真正需要它的主要功能。

这是我们正在寻找的代码。这是C#的一个例子。

C#代码:

int pid = 1234; //process id that you need to dump
string dumpPath;
dumpPath = @"C:\Programs\test.dmp";
DbgControl dbgControl = new DbgControl();
dbgControl.AttachToProcess(pid, @"C:\Programs\InjectLeakTrack.vbs", @"C:\", dumpPath);
DbgObj dbgObj = new DbgObj();
dbgObj.DumpPath = @"C:\";
dbgObj.CreateDumpForProcessID(pid, "No reason", false, true);
dbgControl.DetachFromProcess();

对于InjectLeakTrack.vbs,我们只需要这个。

Sub Debugger_OnInitialBreakpoint()
   Debugger.InjectLeakTrack
End Sub

我们还将C#用于自动分析师。 C#代码:

DbgControl dbgControl = new DbgControl();
DbgObj g_Debugger = dbgControl.OpenDump(dumpPath, @"c:\symbols", @"c:\symbols", null);
dynamic g_UtilExt = g_Debugger.GetExtensionObject("CrashHangExt", "Utils");
dynamic g_VMInfo = g_Debugger.GetExtensionObject("MemoryExt", "VMInfo");
dynamic g_LeakTrackInfo = g_VMInfo.LeakTrackInfo;
Console.Write(g_LeakTrackInfo.IsLeakTrackLoaded());