我希望有一种方法在抛出异常时向用户报告堆栈跟踪。最好的方法是什么?它是否需要大量额外的代码?

回答问题:

如果可能的话,我希望它是便携的。我想让信息弹出,这样用户就可以复制堆栈跟踪,并在出现错误时通过电子邮件发送给我。


当前回答

在Windows上,查看BugTrap。它不再在原来的链接中,但在CodeProject中仍然可用。

其他回答

在Windows上,查看BugTrap。它不再在原来的链接中,但在CodeProject中仍然可用。

Unix:回溯

麦克:回溯

Windows: CaptureBackTrace

这取决于哪个平台。

在GCC上,这是非常琐碎的,更多细节请参阅这篇文章。

在MSVC上,您可以使用StackWalker库来处理Windows所需的所有底层API调用。

你必须找出将此功能集成到应用程序中的最佳方法,但你需要编写的代码量应该是最小的。

OSX的一个工作示例(现在在Catalina 10.15上测试)。显然不能移植到linux/windows。也许它会对某人有用。

在“Mew-exception”字符串中,可以使用backtrace和/或backtrace_symbols函数

#include <stdexcept>
#include <typeinfo>
#include <dlfcn.h>

extern "C" void __cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *));
static void (*__cxa_throw_orig)(void *thrown_object, std::type_info *tinfo, void (*dest)(void *));
extern "C" void luna_cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *))
{
    printf("Mew-exception you can catch your backtrace here!");
    __cxa_throw_orig(thrown_object, tinfo, dest);
}


//__attribute__ ((used))
//__attribute__ ((section ("__DATA,__interpose")))
static struct replace_pair_t {
    void *replacement, *replacee;
} replace_pair = { (void*)luna_cxa_throw, (void*)__cxa_throw };

extern "C" const struct mach_header __dso_handle;
extern "C" void dyld_dynamic_interpose(const struct mach_header*,
                               const replace_pair_t replacements[],
                               size_t count);

int fn()
{
    int a = 10; ++a;
    throw std::runtime_error("Mew!");
}

int main(int argc, const char * argv[]) {
    __cxa_throw_orig = (void (*)(void *thrown_object, std::type_info *tinfo, void (*dest)(void *)))dlsym(RTLD_DEFAULT, "__cxa_throw");

    dyld_dynamic_interpose(&__dso_handle, &replace_pair, 1);

    fn();
    return 0;
}

AFAIK libunwind非常便携,到目前为止我还没有找到更容易使用的东西。