我有C#/ VB.NET应用程序,它测试用C ++编写的其他应用程序。如果C ++应用程序没有响应,我想从中获取callstack。我发现了用C ++编写的各种示例(例如dbghelp.dll CaptureStackBackTrace或Walking the callstack),但我在C#中没有发现任何内容。你能帮帮我吗?
答案 0 :(得分:0)
我可以想到几个选项,但没有一个使用c#。
然后使用windbg或visual studio查看转储。
您可以通过使用命令行参数调用其中任何一个来自动执行adplus或procdump在c#中获取转储。这仍然没有得到你的callstack,但如果你有一个涉及多个线程的死锁,你可能需要查看多个callstack。
您也可以查看此链接 - 但它建议您需要编写调试器或找到一些可以执行此操作的库。
另一个选择是在c ++中使用“Walking the callstack”示例。您可以创建一个可执行文件,其中包含一个进程ID,可能还有一个文件名作为命令行参数(可以使用guid),然后等待该文件被写入(不好玩 - 但可行)。或者你可以尝试使用托管c ++并将调用包装到非托管的东西(可能更不好玩,但可能更“正确”)。
答案 1 :(得分:0)
以下是我的团队成员的VB.NET实现:
使用以下代码调用它:
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
此调用创建包含少量文件的目录。其中一个包含来自目标应用程序的callstack。