我希望有一种方法在抛出异常时向用户报告堆栈跟踪。最好的方法是什么?它是否需要大量额外的代码?
回答问题:
如果可能的话,我希望它是便携的。我想让信息弹出,这样用户就可以复制堆栈跟踪,并在出现错误时通过电子邮件发送给我。
我希望有一种方法在抛出异常时向用户报告堆栈跟踪。最好的方法是什么?它是否需要大量额外的代码?
回答问题:
如果可能的话,我希望它是便携的。我想让信息弹出,这样用户就可以复制堆栈跟踪,并在出现错误时通过电子邮件发送给我。
当前回答
如果你使用的是Boost 1.65或更高版本,你可以使用Boost::stacktrace:
#include <boost/stacktrace.hpp>
// ... somewhere inside the bar(int) function that is called recursively:
std::cout << boost::stacktrace::stacktrace();
其他回答
在Windows上,查看BugTrap。它不再在原来的链接中,但在CodeProject中仍然可用。
Poppy不仅可以收集堆栈跟踪,还可以收集参数值、局部变量等等——所有导致崩溃的东西。
我也有类似的问题,尽管我喜欢可移植性,但我只需要gcc支持。在gcc中,execinfo.h和回溯调用是可用的。为了要求函数名,Bingmann先生编写了一段很好的代码。为了在异常上转储反向跟踪,我创建了一个异常,该异常在构造函数中打印反向跟踪。如果我期望这与库中抛出的异常一起工作,则可能需要重新构建/链接,以便使用回溯异常。
/******************************************
#Makefile with flags for printing backtrace with function names
# compile with symbols for backtrace
CXXFLAGS=-g
# add symbols to dynamic symbol table for backtrace
LDFLAGS=-rdynamic
turducken: turducken.cc
******************************************/
#include <cstdio>
#include <stdexcept>
#include <execinfo.h>
#include "stacktrace.h" /* https://panthema.net/2008/0901-stacktrace-demangled/ */
// simple exception that prints backtrace when constructed
class btoverflow_error: public std::overflow_error
{
public:
btoverflow_error( const std::string& arg ) :
std::overflow_error( arg )
{
print_stacktrace();
};
};
void chicken(void)
{
throw btoverflow_error( "too big" );
}
void duck(void)
{
chicken();
}
void turkey(void)
{
duck();
}
int main( int argc, char *argv[])
{
try
{
turkey();
}
catch( btoverflow_error e)
{
printf( "caught exception: %s\n", e.what() );
}
}
使用gcc 4.8.4编译和运行这个函数会产生一个反向跟踪,其中包含了非常整洁的c++函数名:
stack trace:
./turducken : btoverflow_error::btoverflow_error(std::string const&)+0x43
./turducken : chicken()+0x48
./turducken : duck()+0x9
./turducken : turkey()+0x9
./turducken : main()+0x15
/lib/x86_64-linux-gnu/libc.so.6 : __libc_start_main()+0xf5
./turducken() [0x401629]
如果你使用的是Boost 1.65或更高版本,你可以使用Boost::stacktrace:
#include <boost/stacktrace.hpp>
// ... somewhere inside the bar(int) function that is called recursively:
std::cout << boost::stacktrace::stacktrace();
我想添加一个标准库选项(即跨平台),如何生成异常回溯,这已经在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"