gpt4 book ai didi

c++ - backtrace_symbols 无法打印导致信号的函数

转载 作者:太空狗 更新时间:2023-10-29 20:41:27 27 4
gpt4 key购买 nike

我正在为我的 C++ 应用程序实现一个简单的崩溃记录器:

static void handler(int, siginfo_t * info, void *) {
void *array[1000];

switch (info->si_signo) {
case SIGILL:
Logger() << "Received SIGILL";
break;
case SIGSEGV:
Logger() << "Received SIGSEGV";
break;
case SIGBUS:
Logger() << "Received SIGBUS";
break;
case SIGSYS:
Logger() << "Received SIGSYS";
break;
default:
break;
}

// get void*'s for all entries on the stack
const size_t size = backtrace(array, 1000);

// print out all the frames
char ** symbols = backtrace_symbols(array, size);
for(size_t i = 0; i < size; ++i)
{
Logger() << symbols[i];
}

free(symbols);
exit(EXIT_FAILURE);
}

struct sigaction SignalAction;
SignalAction.sa_flags = SA_SIGINFO;
SignalAction.sa_sigaction = handler;
sigemptyset(&SignalAction.sa_mask);
sigaction(SIGSEGV, &SignalAction, NULL);
sigaction(SIGBUS, &SignalAction, NULL);
sigaction(SIGILL, &SignalAction, NULL);

我还没有在 Linux 上测试它,但是在 OS X 上,我感兴趣的特定跟踪项,即引起信号的那个,没有被打印(条目号2):

: " Received SIGSEGV" 
: " 0 App 0x0000000100253d15 _ZL7handleriP9__siginfoPv + 229"
: " 1 libsystem_platform.dylib 0x00007fff8ff0f5aa _sigtramp + 26"
: " 2 ??? 0x000000000000000c 0x0 + 12"
: " 3 App 0x000000010000dfa7 _ZN11CMainWindow13initShortcutsEv + 231"
: " 4 App 0x000000010000d059 _ZN11CMainWindowC2EP7QWidget + 1001"
: " 5 App 0x00000001000091d9 main + 6217"
: " 6 App 0x00000001000070a5 _start + 227"
: " 7 App 0x0000000100006fc1 start + 33"

为什么会这样,我可以解决这个问题吗?

P. S. 这是一个调试版本。没有实际的段错误,它是用 raise(SIGSEGV) 模拟的。 raise 是从一个方法中调用的,而该方法又是从 MainWindow::initShortcuts 中调用的。

最佳答案

使用信号处理程序构建崩溃记录器的想法存在根本性缺陷。来自 sigaction man page 的“注意”部分:

The following functions are either reentrant or not interruptible by signals and are async-signal safe. Therefore applications may invoke them, without restriction, from signal-catching functions:

[… async-signal safe function list omitted …]

All functions not in the above lists are considered to be unsafe with respect to signals. That is to say, the behaviour of such functions when called from a signal handler is undefined. In general though, signal handlers should do little more than set a flag; most other actions are not safe.

没有backtrace() , backtrace_symbols() , free() , 或 exit()在信号处理程序中调用是安全的。几乎可以肯定,你的 Logger 中的东西或 operator<<也是不安全的。

至于为什么信号触发函数不在回溯中,这显然是由内核如何设置信号处理程序上下文引起的。回溯是通过检查由调用语句和函数序言构造的堆栈帧来获得的。信号处理程序不会像普通函数调用一样被调用,因此没有特别的理由期望栈帧链会被正确设置。

事实上,可以使信号处理程序在与普通代码完全不同的堆栈上运行。参见 sigaltstack() .

关于c++ - backtrace_symbols 无法打印导致信号的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21302960/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com