2012-11-25 95 views
1

我的公司有一個應用程序,它有一些響應/穩定性/內存問題。我正在嘗試編寫一個幫助我們識別這些問題的小幫手應用程序。我希望此應用程序能夠根據命令生成轉儲並進行一些基本的自動調試,首先我要獲取目標應用程序中所有線程的所有堆棧跟蹤。使用C#的DbgHost.exe COM對象#

所以我一直在研究這一個星期左右,我發現了幾種添加調試功能的方法。我發現的一些選項是使用ICorDebug,DbgEng.dll和DbgHost.exe。我真的很想使用DbgHost.exe,因爲它使我能夠將LeakTrack.dll注入到目標進程中以跟蹤內存分配。

我的問題是,我似乎無法得到它的工作,我無法找到關於這兩個對象,DbgControl和DbgObj的任何真正的好信息。我發現下面的鏈接:

How to control a debugger engine?

Scripting 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越來越訪問衝突。我即將放棄這一點,繼續採用更常見的方法,但我希望有人有一些指導,可以幫助我克服這一難題。

回答

0

我發現了同樣的問題。 我只是明白這個link。我將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#code:

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());