【发布时间】:2015-01-03 14:00:22
【问题描述】:
我正在使用 Win32 SEH 捕获异常:
try
{
// illegal operation that causes access violation
}
__except( seh_filter_func(GetExceptionInformation()) )
{
// abort
}
过滤器函数的样子:
int seh_filter_func(EXCEPTION_POINTERS *xp)
{
// log EIP, other registers etc. to file
return 1;
}
到目前为止,这有效,xp->ContextRecord->Eip 中的值告诉我哪个函数导致了访问冲突(实际上 - ntdll.dll!RtlEnterCriticalSection ,EDX 的值告诉我这个函数是用一个虚假的参数调用的)。
但是,这个函数在很多地方被调用,包括从其他 WinAPI 函数中调用,所以我仍然不知道哪个代码负责使用虚假参数调用这个函数。
是否有任何代码可以根据EXCEPTION_POINTERS 中的信息或其他信息来生成导致 EIP 现在所在位置的函数调用链的跟踪? (不能在外部调试器下运行程序)。
只要 EIP 值就可以了,因为我可以在链接器映射和符号表中查找它们,尽管如果有一种方法可以自动将它们映射到符号名称会更好。
我在这个项目中使用 C++Builder 2006,尽管 MSVC++ 解决方案可能仍然有效。
【问题讨论】:
-
dbghelp.dll 是一个很棒的库。我们使用它,但这里有一些事情需要考虑。如果您的进程由于堆损坏而崩溃,则 dbghelp 可能无法为目标文件符号表分配内存。考虑在崩溃之前初始化 dbghelp。您需要使用您的软件提供调试信息。对于一些可能存在问题的安全敏感软件。
-
另一个选项是使用 MS minidump 文件。这些基本上将堆栈(如果需要,还可以更多)内存写入小型转储文件。 MS 调试器可以使用 minidump 文件向您显示代码中的堆栈回溯。
-
@PaulMcKenzie 正是我要找的东西,你。我希望这篇文章能以某种方式存档,以防链接稍后失效而其他人也想要同样的东西。
-
@brianbeuning 谢谢,minidump 还生成了包含一些有用信息的文件,尽管我似乎无法从中获取调用堆栈,它只是为我的代码显示“外部代码”。使用 VS2013 Express 查看转储
标签: c++ windows stack-trace seh