【问题标题】:How to generate stack trace from SEH exception如何从 SEH 异常生成堆栈跟踪
【发布时间】: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


【解决方案1】:

我认为您可以为此使用Boost.Stacktrace

#include <boost/stacktrace.hpp>

int seh_filter_func(EXCEPTION_POINTERS *xp)
{
    const auto stack = to_string( boost::stacktrace::stacktrace() );
    LOG( "%s", stack.c_str() );

    return 1;
}

【讨论】:

    猜你喜欢
    • 2011-01-05
    • 2017-08-06
    • 2010-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多