Ubuntu下手动链接的可执行文件存在却无法运行
问题原因与解决方案
核心原因
你遇到的问题本质是动态链接器路径不匹配:
- Ubuntu x86_64系统的默认动态链接器路径是
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2,但你用ld -lc链接出来的程序指定了解释器/lib/ld64.so.1——这是BSD类系统的动态链接器路径,Ubuntu上根本不存在这个文件。 - shell提示"文件不存在"其实是误导,真实情况是系统找不到程序依赖的动态链接器,而非程序本身不存在。
另外,直接用ld -lc链接C标准库还缺少C运行时的启动代码(crt1.o、crti.o、crtn.o),这些代码负责初始化程序环境、调用main函数前的准备工作,缺失的话即使链接器路径正确也可能运行异常。
解决方案
方案1:用gcc代替ld链接(推荐)
gcc会自动处理所有C标准库的链接细节,包括正确的动态链接器路径和启动代码,只需执行:
gcc -o helloworld helloworld.o
方案2:手动用ld指定正确参数(适合需要自定义链接的场景)
如果你坚持要用ld,需要手动指定动态链接器路径和C运行时启动文件:
ld -dynamic-linker /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 \ -o helloworld helloworld.o \ /usr/lib/x86_64-linux-gnu/crt1.o \ /usr/lib/x86_64-linux-gnu/crti.o \ -lc \ /usr/lib/x86_64-linux-gnu/crtn.o
-dynamic-linker:指定Ubuntu使用的正确动态链接器路径- crt1/crti/crtn:提供C运行时的启动与收尾代码,必须在
-lc前后按顺序链接
为什么去掉puts、不用-lc就正常?
此时你的程序是纯汇编静态程序,没有依赖任何动态库,不需要动态链接器介入,系统可以直接加载执行,因此不会出现找不到解释器的问题。
内容的提问来源于stack exchange,提问作者FalcoGer
相关产品推荐
相关产品推荐

