首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >glibc:无法获得某些部分的信息。

glibc:无法获得某些部分的信息。
EN

Stack Overflow用户
提问于 2021-10-18 10:20:27
回答 1查看 139关注 0票数 0

我目前面临着glibc v2.22的问题,在那里我无法获得适当的展开信息。当有SIGABRT应用程序时,它将从glibc调用abort函数。它应该使用在构建中启用的展开信息。但是,它正在扫描堆栈(如屏幕快照中地址下面的红线所示),并提供所附屏幕快照中显示的误导性信息(使用哨兵分析转储)。

在这里,do_crash被调用,它执行assert(0),然后中止主应用程序。在分析转储时,do_crash函数调用_fini,这个_fini从来不在主应用程序的堆栈中。

我已经通过使用CFLAGS += "-funwind-tables"为glibc启用了展开。我也尝试过使用-rdynamic-fno-omit-frame-pointer等标志,但这也没有用。

我是不是漏掉了什么?如何获得信号的完全回溯,特别是SIGABRT?

提前感谢

EN

回答 1

Stack Overflow用户

发布于 2022-08-04 09:15:28

当有SIGABRT应用程序时,它从glibc调用中止函数。

这不是真的,这种情况不会发生,除非您显式地注册了它。

i通过使用CFLAGS +=启用了glibc的展开

它告诉编译器添加信息,而不是“启用展开”。What exactly happens when compiling with -funwind-tables?

在这里,

调用了do_crash,它确实断言(0),然后中止主应用程序。

这与接收SIGABRT信号无关。

,我是不是漏掉了什么?

我相信你做了错误的假设--在SIGABRT上调用了一些东西,SIGABRT是在断言上发送的,而abort()是在SIGABRT上调用的。在SIGABRT上不调用任何东西,程序在默认情况下接收到SIGABRT时被终止(请参见man 7 signal),assert只是终止程序而不引发SIGABRT,而abort()则引发SIGABRT信号,而不是接收它。

如何获得信号的完全回溯,特别是SIGABRT?

注册一个将执行此操作的处理程序。见How to automatically generate a stacktrace when my program crashes

代码语言:javascript
复制
#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);
}

如果您想要在assert()上打印堆栈跟踪,这是完全不同的,并且您将覆盖glibc处理程序来执行断言:

代码语言:javascript
复制
#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);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69614422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档