You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅导出程序中已使用函数的动态符号?

问题描述

在x86_64 Linux环境中,我使用-rdynamic作为gcc的链接器选项,导出程序中已使用的符号,以便程序发生SEGV或其他异常时,通过glibc的backtrace()生成回溯信息排查问题。程序依赖静态库,这些库中可能包含未使用的函数,而这些未使用函数又依赖其他静态库。程序和库编译时使用-ffunction-sections,链接器使用-Wl,--gc-sections -Wl,--as-needed,此前该参数组合可正常编译,无引用错误。

但升级到binutils-2.22后,突然出现引用错误,必须包含未使用函数依赖的所有库才能编译通过。推测当前链接器的行为是:只要目标文件中至少有一个函数被引用,就会将该文件内所有函数标记为必需。gold、mold等其他链接器也有相同行为,这应该是标准行为,而binutils-2.22之前的ld.bfd未按此规则工作,但那个旧行为刚好符合我的需求。

现在我想复现2.22之前的行为,打算通过-Wl,--dynamic-list手动指定要导出的符号,但不知道如何获取已使用函数的列表?

※ 这看似是XY问题,实际需求是生成带函数名的回溯信息,-rdynamic只是权宜之计。我需要程序发生SEGV时生成回溯,目前通过预加载libSegFault.so实现,它会调用backtrace(),否则我直接使用libbacktrace即可。

最小复现示例

main.c

extern int give_747(void);

int main(void) {
    return give_747();
}

lib1.c(未使用)

int return_123 (void) {
    return 123;
}

lib2.c

#include <execinfo.h>
#include <stdlib.h>
#include <unistd.h>
#include <backtrace.h>

extern int return_123(void);

static int cb (void *data, uintptr_t pc,
    const char *filename, int lineno, const char *function) {
    printf("%s:%d(%s)[%p]\n", filename, lineno, function, (void*)pc);
}

int give_747(void) {
    void *bt[4] = {0};
    static struct backtrace_state *bts = NULL;

    backtrace(bt, 4);
    printf("backtrace_symbols_fd():\n");
    backtrace_symbols_fd(bt, 4, STDOUT_FILENO);

    printf("\nlibbacktrace:\n");
    bts = backtrace_create_state(NULL, 0, NULL, NULL);
    backtrace_full(bts, 0, cb, NULL, NULL);
    printf("\n");

    return 747;
}

int return_246(void) {
    int tmp = return_123();
    return tmp+tmp;
}

Makefile

main: main.o lib2.a
        $(CC) -Wl,--gc-sections -Wl,--as-needed $^ -o $@ -L/path/to/libbacktrace/lib -lbacktrace

maindyn: main.o lib2.a
        $(CC) -Wl,--gc-sections -Wl,--as-needed -rdynamic $^ -o $@ -L/path/to/libbacktrace/lib -lbacktrace

%.o: %.c
        $(CC) -I/path/to/libbacktrace/include -ggdb -O3 -ffunction-sections -c $< -o $@

lib1.a: lib1.o
        ar curs $@ $^

lib2.a: lib2.o
        ar curs $@ $^

链接错误输出

cc -Wl,--gc-sections -rdynamic main.o lib2.a -o maindyn -L/path/to/libbacktrace/lib -lbacktrace
lib2.a(lib2.o): In function `return_246':
/home/syukri/playground/gcsections/lib2.c:30: undefined reference to `return_123'
collect2: error: ld returned 1 exit status
make: *** [maindyn] Error 1

内容的提问来源于stack exchange,提问作者syockit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 11:33:15