我希望有一种方法在抛出异常时向用户报告堆栈跟踪。最好的方法是什么?它是否需要大量额外的代码?
回答问题:
如果可能的话,我希望它是便携的。我想让信息弹出,这样用户就可以复制堆栈跟踪,并在出现错误时通过电子邮件发送给我。
我希望有一种方法在抛出异常时向用户报告堆栈跟踪。最好的方法是什么?它是否需要大量额外的代码?
回答问题:
如果可能的话,我希望它是便携的。我想让信息弹出,这样用户就可以复制堆栈跟踪,并在出现错误时通过电子邮件发送给我。
当前回答
Cpp-tool ex_diag -重量轻,多平台,最小的资源使用,简单和灵活的跟踪。
其他回答
在使用g++的Linux上检查这个库
https://sourceforge.net/projects/libcsdbg
它为你做了所有的工作
Andrew Grant的回答并不能帮助获得抛出函数的堆栈跟踪,至少在GCC中是这样,因为throw语句本身并不能保存当前的堆栈跟踪,并且catch处理程序届时将无法再访问堆栈跟踪。
解决这个问题的唯一方法(使用GCC)是确保在抛出指令的点生成堆栈跟踪,并将其与异常对象一起保存。
当然,此方法要求抛出异常的每个代码都使用特定的exception类。
2017年7月11日更新:对于一些有用的代码,看看cahit beyaz的答案,它指向http://stacktrace.sourceforge.net -我还没有使用它,但它看起来很有前途。
我也有类似的问题,尽管我喜欢可移植性,但我只需要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]
在Windows上,查看BugTrap。它不再在原来的链接中,但在CodeProject中仍然可用。
这取决于哪个平台。
在GCC上,这是非常琐碎的,更多细节请参阅这篇文章。
在MSVC上,您可以使用StackWalker库来处理Windows所需的所有底层API调用。
你必须找出将此功能集成到应用程序中的最佳方法,但你需要编写的代码量应该是最小的。