为何GCC加-static编译后仍未链接libc的system函数?
为什么静态编译后可执行文件里没有system函数?
这是因为GCC链接器默认会做函数级的垃圾代码消除(Garbage Collection of Sections)——它只会把你的代码直接或间接用到的函数链接进最终的可执行文件里。
你测试代码里根本没调用system,也没有任何代码依赖这个函数,所以链接器会直接跳过它,不会把它塞进可执行文件。而你能看到的printf、memcpy、strcmp,要么是你代码里直接调用了(比如printf),要么是被printf这类你用到的函数间接依赖了,所以才被链接进来。
解决办法
要让system被静态链接进来,有几个简单的方法:
- 显式调用system:在代码里加一行
system(NULL);(哪怕是个空调用,只要编译器能看到这个引用就行),重新编译后就能在GDB里找到它了。 - 强制链接器保留system符号:编译时加上链接器选项
-Wl,-u,system,这会告诉链接器把system当作一个未定义的符号,必须从libc里把它链接进来。比如:gcc -g -static -Wl,-u,system t.c -o t - 关闭链接时的垃圾代码消除:用
-Wl,--no-gc-sections选项,这会禁止链接器删除未被使用的代码段,但会导致可执行文件体积暴涨(因为会把整个libc都塞进去),不推荐除非必要。
内容的提问来源于stack exchange,提问作者Abhishek Ghosh
相关产品推荐
相关产品推荐

