gpt4 book ai didi

linux - 如何在进程信号处理程序(armv7-uclibc)中获得正确的回溯?

转载 作者:IT王子 更新时间:2023-10-29 01:08:29 30 4
gpt4 key购买 nike

我已经在谷歌上搜索了很多次以在信号处理程序中找到 backtrace() 的正确解决方案并尝试了几乎所有方法,但我无法在我的信号处理程序中成功获得回溯 - 这不是 SIGUSR1 处理程序。

  • 在 uclibc 配置中启用 UCLIBC_HAS_BACKTRACE=y 并编译它
  • 已验证 libubacktrace.so 已创建
  • 使用以下选项编译了我的应用程序二进制文件-G-动态-fexception 或 -funwind-tables
  • 二进制文件本身似乎被“剥离”了

但是,我无法从信号处理程序中获得完整的回溯。只打印了我在信号处理程序中调用的函数地址。

如果我使用 target-gdb 二进制文件并使用 gdb --pid 命令附加进程,我能够正确获得完整的回溯。

此外,我尝试了 pstack,但(pstack-1.2 - 尝试了 arm-patch 但它太可怕了......没有打印)不是很有帮助。

有什么建议吗?


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 addresses\n", __func__, nptrs);

strings = backtrace_symbols(buf, nptrs);

if(strings == NULL) {
printf("%s: no backtrace captured\n", __func__);
return;
}

for(i = 0; i < nptrs; i++) {
printf("%s\n", strings[i]);
}

free(strings);
}

...
static void sigHandler(int signum)
{
printf("%s: signal %d\n", __FUNCTION__, signum);
switch(signum ) {
case SIGUSR2:
// told to quit
print_stack();
break;
default:
break;
}
}

最佳答案

仔细阅读 signal(7)signal-safety(7) .

信号处理程序仅限于调用(直接或间接)async-signal-safe-functions(实际上,大多数只调用 syscalls(2))和 backtrace(3)甚至 printf(3)malloc(3)free 不是异步信号安全的。所以你的代码不正确:信号处理程序 sigHandler 正在调用 printf 并间接地(通过 print_stack)free 并且它们不是异步信号安全的。

所以你唯一的选择是使用 gdb 调试器。

阅读有关 POSIX 的更多信息 signal.h & signal concepts .实际上,信号处理程序可以做的几乎唯一明智的事情就是设置一些全局的、线程局部的或静态的 volatile sig_atomic_t flag ,必须在别处进行测试。也可以直接write(2)几个字节到 pipe(7) ,您的应用程序将在其他地方读取(例如,如果它是 GUI 应用程序,则在其事件循环中)。

您也可以使用 Ian Taylor 的 libbacktrace from inside GCC (假设您的程序是使用调试信息编译的,例如使用 -g)。它不能保证在信号处理程序中工作(因为它不仅仅使用异步信号安全函数),但它实际上非常有用。

注意内核正在为 call stack 设置一个调用帧(在 sigreturn(2) 中)处理信号时。

您也可以使用(特别是如果您的应用程序是单线程的)sigaltstack(2)有一个备用信号堆栈。我不确定这是否有帮助。

如果你有一个事件循环,你可以考虑使用 Linux 特定的 signalfd(2)并要求您的事件循环轮询它。对于 SIGTERMSIGQUITSIGALRM 这是一个非常有用的技巧。

关于linux - 如何在进程信号处理程序(armv7-uclibc)中获得正确的回溯?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29982643/

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