提问人:Aliasgar 提问时间:10/18/2021 最后编辑:Peter CordesAliasgar 更新时间:8/4/2022 访问量:386
glibc:无法获取某些部分的展开信息
glibc: unable to get unwind information for certain sections
问:
我目前面临 glibc v2.22 的问题,我无法获得正确的放松信息。 当有 SIGABRT 应用程序时,它从 glibc 调用中止函数。它应该使用在构建中启用的展开信息。但是,它正在扫描堆栈(如屏幕截图中地址下方的红线所示)并提供误导性信息,如所附的屏幕截图所示(使用哨兵分析转储)。
这里,称为 which does which 然后中止主应用程序。在分析转储时,do_crash 函数调用 which 从未在主应用程序的堆栈中。do_crash
assert(0)
_fini
我已经通过使用 为 glibc 启用了 unwind。我也尝试过使用诸如 and 之类的标志,但它也没有用。CFLAGS += "-funwind-tables"
-rdynamic
-fno-omit-frame-pointer
我在这里遗漏了什么吗?如何获得信号的完整回溯,尤其是 SIGABRT?
提前致谢
答:
当有 SIGABRT 应用程序时,它正在从 glibc 调用中止函数
这不是真的,除非您明确注册它,否则不会发生这种情况。
我已经使用 CFLAGS += “-funwind-tables” 为 glibc 启用了 unwind
它告诉编译器添加信息,它不会“启用展开”。使用 -funwind-tables 编译时究竟会发生什么?
在这里,调用了 do_crash assert(0),然后中止了主应用程序。
这与接收 SIGABRT 信号无关。
我在这里遗漏了什么吗?
我相信你做出了错误的假设——某些东西被调用了 SIGABRT,SIGABRT 被发送到断言,即被调用.默认情况下,SIGABRT 上不会调用任何内容,并且程序在接收 SIGABRT 时终止(请参阅 ),只是终止程序而不引发 SIGABRT,并引发信号,而不是接收信号。abort()
SIGABRT
man 7 signal
assert
abort()
SIGABRT
如何获得信号的完整回溯,尤其是 SIGABRT?
注册一个将执行此操作的处理程序。请参 阅如何在程序崩溃时自动生成堆栈跟踪 。
#include <execinfo.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void handler(int sig) {
void *array[10];
size_t size;
size = backtrace(array, 10);
backtrace_symbols_fd(array, size, STDERR_FILENO);
_Exit(1);
}
int main(int argc, char **argv) {
signal(SIGABRT, handler); // install our handler
raise(SIGABRT);
}
如果你想打印堆栈跟踪,那就完全不同了,你会覆盖 glibc 处理程序 for assert 来做到这一点:assert()
#include <assert.h>
#include <execinfo.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void print_trace(void) {
void *array[10];
size_t size;
size = backtrace(array, 10);
backtrace_symbols_fd(array, size, STDERR_FILENO);
}
// based on https://code.woboq.org/userspace/glibc/assert/assert.c.html
void __assert_fail(const char *assertion, const char *file, unsigned int line, const char *function) {
extern const char *__progname;
fprintf(stderr, "%s%s%s:%u: %s%sAssertion `%s' failed.\n",
__progname, __progname[0] ? ": " : "",
file, line,
function ? function : "", function ? ": " : "",
assertion);
print_trace();
abort();
}
int main() {
assert(0);
}
评论
Here, do_crash is called which does assert(0) which then aborts the main application
glibc 源代码中没有。那么您的应用程序是否正在接收 SIGABRT,或者您的代码正在执行?do_crash
assert(0)