Search code examples
c#vb.netcallstackdbghelp

How can I get callstack from C++ application using C#?


I have C#/VB.NET application which tests other application written in C++. If C++ application doesn't respond, I want to get callstack from it. I found various examples written in C++ (e.g. dbghelp.dll CaptureStackBackTrace or Walking the callstack), but I found nothing in written C#. Can you help me, please?


Solution

  • Here is VB.NET implementation from my team member:

    1. Download ADPlus and add it into project. The ADPlus is included in Debugging Tools for Windows.
    2. Call it with following code:

      Public Shared Sub DumpCallStack(processID As Integer, outputFolder As String)
      
          Const serverSymbolPath As String = "http://msdl.microsoft.com/download/symbols"
          Const localSymbolFolder As String = "c:\temp\localSymbols"
          Dim symbolFolderPath As String = String.Format("SRV*{0}* {1}", serverSymbolPath, localSymbolFolder)
      
          Directory.CreateDirectory(localSymbolFolder)
          Directory.CreateDirectory(outputFolder)
      
          Dim arguments As String = String.Format("/c Cscript //nologo ""{0}"" -quiet -quick -NoTlist -p {1} -dbg ""{2}"" -yp ""{3}"" -o ""{4}""",
                                  "c:\Adplus\x64\adplus.vbs",
                                  processID,
                                  "CDB.exe",
                                  symbolFolderPath,
                                  outputFolder)
      
          Dim pro As Process = New Process()
          pro.StartInfo.FileName = "cmd.exe"
          pro.StartInfo.Arguments = arguments
          pro.StartInfo.UseShellExecute = False
          pro.StartInfo.EnvironmentVariables("_NT_SYMBOL_PATH") = symbolFolderPath
      
          pro.Start()
      
          'wait up to 1 minute for the cmd.exe to exit
          pro.WaitForExit(60000)
      
          'Wait up to 1 minute for the windgb.exe to exit
          WaitForProcessExit("cdb", 60000)
      End Sub
      
      Private Shared Sub WaitForProcessExit(processName As String, milliseconds As Integer)
          Dim pros As Process() = Process.GetProcessesByName(processName)
          If pros Is Nothing Then Return
      
          For Each pro As Process In pros
              pro.WaitForExit(milliseconds)
          Next
      End Sub
      

    This call creates directory with few files. One of them contains callstacks from target application.