我希望有一种方法在抛出异常时向用户报告堆栈跟踪。最好的方法是什么?它是否需要大量额外的代码?
回答问题:
如果可能的话,我希望它是便携的。我想让信息弹出,这样用户就可以复制堆栈跟踪,并在出现错误时通过电子邮件发送给我。
我希望有一种方法在抛出异常时向用户报告堆栈跟踪。最好的方法是什么?它是否需要大量额外的代码?
回答问题:
如果可能的话,我希望它是便携的。我想让信息弹出,这样用户就可以复制堆栈跟踪,并在出现错误时通过电子邮件发送给我。
当前回答
我想添加一个标准库选项(即跨平台),如何生成异常回溯,这已经在c++ 11中可用:
使用std::nested_exception和std::throw_with_nested
这不会给你一个堆栈unwind,但在我看来是次好的事情。 StackOverflow在这里和这里都有描述,如何在不需要调试器或繁琐的日志记录的情况下,通过简单地编写一个适当的异常处理程序重新抛出嵌套异常,就可以在代码中对异常进行回溯。
由于可以对任何派生异常类执行此操作,因此可以向这样的回溯添加大量信息! 你也可以看看我在GitHub上的MWE,在那里回溯看起来是这样的:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
其他回答
Cpp-tool ex_diag -重量轻,多平台,最小的资源使用,简单和灵活的跟踪。
Andrew Grant的回答并不能帮助获得抛出函数的堆栈跟踪,至少在GCC中是这样,因为throw语句本身并不能保存当前的堆栈跟踪,并且catch处理程序届时将无法再访问堆栈跟踪。
解决这个问题的唯一方法(使用GCC)是确保在抛出指令的点生成堆栈跟踪,并将其与异常对象一起保存。
当然,此方法要求抛出异常的每个代码都使用特定的exception类。
2017年7月11日更新:对于一些有用的代码,看看cahit beyaz的答案,它指向http://stacktrace.sourceforge.net -我还没有使用它,但它看起来很有前途。
下面的代码在抛出异常后立即停止执行。您需要设置一个windows_exception_handler和一个终止处理程序。我在MinGW 32bits中进行了测试。
void beforeCrash(void);
static const bool SET_TERMINATE = std::set_terminate(beforeCrash);
void beforeCrash() {
__asm("int3");
}
int main(int argc, char *argv[])
{
SetUnhandledExceptionFilter(windows_exception_handler);
...
}
检查下面的windows_exception_handler函数代码: http://www.codedisqus.com/0ziVPgVPUk/exception-handling-and-stacktrace-under-windows-mingwgcc.html
如果你使用的是Boost 1.65或更高版本,你可以使用Boost::stacktrace:
#include <boost/stacktrace.hpp>
// ... somewhere inside the bar(int) function that is called recursively:
std::cout << boost::stacktrace::stacktrace();
我推荐http://stacktrace.sourceforge.net/项目。它支持Windows, Mac OS和Linux