没有定义的弱符号的行为
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
.
- 如果没有(甚至是空的)实现,这种弱符号的合法使用是什么?
- 为什么链接器使用
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 它存在(例如,因为它比“旧”方式更快或更好做事)。
根据我的搜索,弱符号可用于提供库函数的可覆盖默认实现。但是,也允许仅声明弱符号,而无需定义。引用 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
.
- 如果没有(甚至是空的)实现,这种弱符号的合法使用是什么?
- 为什么链接器使用
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 它存在(例如,因为它比“旧”方式更快或更好做事)。