没有定义的弱符号的行为

Behaviour of weak symbol without definition

根据我的搜索,弱符号可用于提供库函数的可覆盖默认实现。但是,也允许仅声明弱符号,而无需定义。引用 Wikipedia,

When linking a binary executable, a weakly declared symbol does not need a definition. In comparison, (by default) a declared strong symbol without a definition triggers an undefined symbol link error.

例如,以下程序可以很好地编译为可执行文件,但会在运行时导致分段错误:

void __attribute__((weak)) test(void);

int main(void) {
    test();
}

readelf和gdb确认函数的GOT入口为0x0.

What would be a legitimate use of such weak symbols without (even an empty) implementation?

定义了的函数可以调用,否则不能调用:

#include <stdio.h>
void __attribute__((weak)) test(void);

int main(void) {
    if (&test == NULL) {
      printf("test() is not defined\n");
    } else {
      printf("test() is defined, calling it now ...\n");
      test();
    }
    return 0;
}

Why does the linker use 0x0 as a placeholder, instead of issuing a diagnostic message?

链接器无法判断某个定义在运行时是否可用。

将函数声明为弱外部符号的全部原因是如果您希望能够将该函数的存在作为可选处理。

如果您希望链接器在未定义 test() 时发出诊断,则不要将其声明为 weak 符号。

更新:

What would be some other ways to use this without resorting to the LD_PRELOAD trick?

LD_PRELOAD与此无关

想象一下您的可执行文件可以与新旧版本的 some_library.so 一起使用。新版本定义了 somefunc(),并且您想调用该函数 IFF 它存在(例如,因为它比“旧”方式更快或更好做事)。