linux – 如何在进程信号处理程序(armv7-uclibc)中获得适当的回
我已经多次谷歌为信号处理程序中的backtrace()找到正确的解决方案,并尝试了几乎所有的东西,但我无法在我的信号处理程序中成功获得回溯 – 这不是SIGUSR1处理程序.
>在uclibc config中启用UCLIBC_HAS_BACKTRACE = y并编译它 但是,我无法从信号处理程序中获得完整的回溯. 如果我使用target-gdb二进制文件并使用gdb –pid命令附加进程,我就可以正确地获得完整的回溯. 另外,我试过pstack但是(pstack-1.2 – 尝试了手臂补丁,但它很可怕……没有打印)不是很有帮助. 有什么建议? 1)Makefile中的编译器选项 CFLAGS = -g -fexceptions -funwind-tables -Werror $(WARN)… 2)代码 代码非常简单. #define CALLSTACK_SIZE 10 static void print_stack(void) { int i,nptrs; void *buf[CALLSTACK_SIZE + 1]; char **strings; nptrs = backtrace(buf,CALLSTACK_SIZE); printf("%s: backtrace() returned %d addressesn",__func__,nptrs); strings = backtrace_symbols(buf,nptrs); if(strings == NULL) { printf("%s: no backtrace capturedn",__func__); return; } for(i = 0; i < nptrs; i++) { printf("%sn",strings[i]); } free(strings); } ... static void sigHandler(int signum) { printf("%s: signal %dn",__FUNCTION__,signum); switch(signum ) { case SIGUSR2: // told to quit print_stack(); break; default: break; } } 解决方法
仔细阅读
signal(7)和
signal-safety(7).
信号处理程序仅限于(直接或间接)调用异步信号安全功能(实际上,仅大多数syscalls(2))和backtrace(3)甚至printf(3)或malloc(3)或免费不是异步信号安全.所以你的代码是不正确的:信号处理程序sigHandler正在调用printf并间接(通过print_stack)释放它们并且它们不是异步信号安全的. 因此,您唯一的选择是使用gdb调试器. 了解更多关于POSIX signal.h&实际上,信号处理程序可以做的几乎唯一合理的事情是设置一些全局,线程局部或静态易失性sig_atomic_t flag,必须在别处进行测试.它也可以直接write(2)到pipe(7)的几个字节,你的应用程序将在别处读取(例如,在它的事件循环中,如果它是一个GUI应用程序). 您也可以使用Ian Taylor的 请注意,内核在处理信号时为sigreturn(2)设置了一个调用帧(在call stack中). 您也可以使用(特别是如果您的应用程序是单线程的)sigaltstack(2)具有备用信号堆栈.我不确定它会有所帮助. 如果您有事件循环,则可以考虑使用特定于Linux的signalfd(2)并请求您的事件循环轮询它.对于SIGTERM或SIGQUIT或SIGALRM,这是一个非常有用的技巧. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |