如何使用c#从c++应用程序获得调用栈?

本文关键字:调用 应用程序 何使用 c++ | 更新日期: 2023-09-27 17:49:33

我有c#/VB。NET应用程序,用于测试用c++编写的其他应用程序。如果c++应用程序没有响应,我想从中获取callstack。我发现了用c++写的各种例子(例如dbghelp.dll CaptureStackBackTrace或Walking the callstack),但我在c#中没有发现任何东西。你能帮我一下吗?

如何使用c#从c++应用程序获得调用栈?

我可以想到一些选项,但是没有一个是使用c#的。

  1. 使用adplus或procdump创建进程转储。
  2. 使用任务管理器并右键单击创建进程转储。注意进程是32位还是64位,您需要使用相同位任务管理器进行转储。

然后使用windbg或visual studio查看转储。

您可以通过使用命令行参数调用adplus或procdump来自动在c#中进行转储。这仍然不能得到调用栈,但是如果你有一个涉及多个线程的死锁,你可能需要查看多个调用栈。

你也可以看看这个链接-但它建议你要么写一个调试器,要么找一些库来做。

http://social.msdn.microsoft.com/forums/en us/90770a1c - 7 - f83 4 f81 - 864 f - e64f3e17d02b/get -或-显示调用堆栈- -另一个进程或exe文件- - - - - - -我的应用-在c?forum=netfxbcl

另一个选择是使用c++中的"遍历调用堆栈"示例。您可以创建一个可执行文件,该文件将进程id和可能的文件名作为命令行参数(可以使用guid),然后等待该文件被写入(不好玩-但可行)。或者您可以尝试使用托管c++,并将调用包装为非托管的东西(可能更不有趣,但可能更"正确")。

这是VB。. NET实现来自我的团队成员:

  1. 下载ADPlus并添加到项目中。ADPlus包含在Windows的调试工具中。
  2. 用下面的代码调用它:

    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
    

这个调用用很少的文件创建目录。其中一个包含来自目标应用程序的调用栈。