1

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

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

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

如何控制调试器引擎?

脚本 DbgHostLib

第一篇文章解释了如何打开转储文件并对其进行处理,第二篇文章解释了如何附加到进程并对其进行处理。二是使用一些网络自动化软件。第二个正是我想做的。

所以这是我到目前为止的代码,我只添加了重要的代码,其余的代码只是用于 UI。

    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 出现访问冲突。我即将放弃这一点并转向更常见的方法,但我希望有人能提供一些指导,帮助我克服这个障碍。

4

1 回答 1

0

我发现了同样的问题。我只是理解这个链接。我使用带有 C# 的 DebugDiag 1.2 进行自动转储。注意,请忽略“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());
于 2013-06-18T15:35:53.383 回答