Mac OSX上未捕获异常时的回溯
Backtracing when uncaught exception on Mac OSX
我正在Mac OSX Lion上进行一些C++编程,希望在崩溃或异常时打印出堆栈跟踪。在下面的讨论中,我尝试了MacPort的gcc47和苹果的llvm-gcc42。
我开始使用glog,因为它可以打印出漂亮的堆栈痕迹。如果我通过访问空指针让程序崩溃,那么打印以下堆栈跟踪看起来很好:
*** Aborted at 1333289352 (unix time) try "date -d @1333289352" if you are using GNU date ***
PC: @ 0x1091a9137 C::h()
*** SIGSEGV (@0x0) received by PID 29623 (TID 0x7fff722d4960) stack trace: ***
@ 0x7fff8cabdcfa _sigtramp
@ 0x1091a9138 C::h()
@ 0x1091a9112 C::g()
@ 0x1091a90ef C::f()
@ 0x1091a903a main
Segmentation fault: 11
然而,如果我抛出异常导致程序崩溃,那么打印出来的堆栈跟踪就不太有用了:
terminate called after throwing an instance of 'std::runtime_error'
what(): Haha
*** Aborted at 1333289406 (unix time) try "date -d @1333289406" if you are using GNU date ***
PC: @ 0x7fff8450f82a __kill
*** SIGABRT (@0x7fff8450f82a) received by PID 52106 (TID 0x7fff722d4960) stack trace: ***
@ 0x7fff8cabdcfa _sigtramp
Abort trap: 6
我在一个CentOS系统上尝试了同样的方法,它打印出了合理的堆栈跟踪和未捕获的异常,所以这应该不是glog的问题。
所以我的问题是:有没有办法让glog打印出未捕获异常的堆栈跟踪?
简而言之:试着安装libunvent并重建googleglog,看看这是否能解决您的问题。这种依赖关系似乎是在撰写本文时由OSX SDK提供的。
从stacktrace.cc
(后来移到utilities.h
):
// There are three different ways we can try to get the stack trace:
//
// 1) Our hand-coded stack-unwinder. This depends on a certain stack
// layout, which is used by gcc (and those systems using a
// gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
// It uses the frame pointer to do its work.
//
// 2) The libunwind library. This is still in development, and as a
// separate library adds a new dependency, abut doesn't need a frame
// pointer. It also doesn't call malloc.
//
// 3) The gdb unwinder -- also the one used by the c++ exception code.
// It's obviously well-tested, but has a fatal flaw: it can call
// malloc() from the unwinder. This is a problem because we're
// trying to use the unwinder to instrument malloc().
在后一个文件中:
#if defined(HAVE_LIB_UNWIND)
# define STACKTRACE_H "stacktrace_libunwind-inl.h"
#elif !defined(NO_FRAME_POINTER)
# if defined(__i386__) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_x86-inl.h"
# elif defined(__x86_64__) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_x86_64-inl.h"
# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2
# define STACKTRACE_H "stacktrace_powerpc-inl.h"
# endif
#endif
#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H)
# define STACKTRACE_H "stacktrace_generic-inl.h"
#endif
#if defined(STACKTRACE_H)
# define HAVE_STACKTRACE
#endif
使用libunfold进行重建应该可以使其优先于堆栈跟踪。如果这不能解决问题,那么应该通知这两个工具背后的程序员。
从OS X 10.6开始,NSException类有一个-callStackSymbols
和一个-callStackReturnAddresses
方法,该方法应允许您检索抛出异常时的堆栈轨迹。如果您想对非异常错误使用相同的机制,请参阅Apple文档中的"控制程序对异常的响应"。我还没有在C++异常中尝试过,但文档声称,至少在64位运行时,Objective-C和C++异常是可互操作的,所以这至少值得一试。
相关文章:
- 当类定义不可见时捕获异常
- 来自 Android 应用程序内部的 boost 类型的 boost::wrapexcept<boost::system::system_error> 的未捕获异常
- 如何通过 pybind11 从 python 中的C++中捕获异常?
- 信号后未捕获异常
- 捕获异常后如何退出程序执行
- C++ 捕获异常后进行清理的标准方法是什么?
- 使用模板类引发和捕获异常
- E/libc++abi:终止于类型为google::protobuf::FatalException的未捕获异常
- 如果在生成 std::thread 后引发,则未捕获异常
- C++ 未捕获异常,程序将终止并中止
- C++程序在第一次尝试时会给出垃圾,但如果它捕获异常并重试,则会给出适当的值
- 仅捕获异常就可以检测所有二进制文件在C 中读取错误是否足够
- 如何捕获 I/O 异常(确切地说是 I/O,而不是 std::exception)
- 为什么捕获异常播放允许尾括号
- throw() 函数应该总是在异常时展开堆栈并允许捕获异常还是必须调用 std::terminate ?
- 寻求与类型为 std::invalid_argument 的未捕获异常相关的运行时错误的建议: stoi:无转换
- 如何从调用函数中捕获异常
- 当用户在字符数组中输入整数值时捕获异常
- C++按值捕获异常时的示例是不好的
- Mac OSX上未捕获异常时的回溯