【发布时间】:2019-12-14 21:37:01
【问题描述】:
Boost 有boost::stacktrace::stacktrace() 可用于获取回溯。这在异常、错误等非信号处理上下文中通常很有用。
但是从信号处理程序中调用是否安全?即,它不执行任何异步信号不安全活动?该示例确实从信号处理程序中使用它,这可能意味着它是安全的。但我在其文档中找不到任何关于 async-signal-safety 的内容。
【问题讨论】:
Boost 有boost::stacktrace::stacktrace() 可用于获取回溯。这在异常、错误等非信号处理上下文中通常很有用。
但是从信号处理程序中调用是否安全?即,它不执行任何异步信号不安全活动?该示例确实从信号处理程序中使用它,这可能意味着它是安全的。但我在其文档中找不到任何关于 async-signal-safety 的内容。
【问题讨论】:
警告 编写信号处理程序需要高度重视!信号处理程序中只允许少数系统调用,因此没有跨平台的方式来打印堆栈跟踪而不会有死锁的风险。解决问题的唯一方法 - 将原始堆栈跟踪转储到文件/套接字并在程序重新启动时对其进行解析。
警告 并非所有平台都提供了以异步信号安全方式获取堆栈跟踪的方法。在此类平台上不会保存任何堆栈跟踪。
紧接着是:
#include <signal.h> // ::signal, ::raise
#include <boost/stacktrace.hpp>
void my_signal_handler(int signum) {
::signal(signum, SIG_DFL);
boost::stacktrace::safe_dump_to("./backtrace.dump");
::raise(SIGABRT);
}
接下来是使用示例,以及如何进行启动检查
namespace boost {
namespace stacktrace {
std::size_t safe_dump_to(void *, std::size_t);
std::size_t safe_dump_to(std::size_t, void *, std::size_t);
std::size_t safe_dump_to(const char *);
std::size_t safe_dump_to(std::size_t, std::size_t, const char *);
std::size_t safe_dump_to(platform_specific_descriptor);
std::size_t safe_dump_to(std::size_t, std::size_t,
platform_specific_descriptor);
}
}
【讨论】:
safe_-family 的函数被记录为
是的,是的。
因为,boost库中提供的用于转储回溯的函数是boost::stacktrace::safe_dump_to。
而safe_dump_to 的documentation 明确指出Async-Handler-Safety: Safe
【讨论】: