编译LLVM IR生成的程序运行时出现段错误,如何解决?
问题解决与分析
改用以下链接命令:
ld -o output main.o -L /lib/gcc/x86_64-linux-gnu /lib/x86_64-linux-gnu/crti.o /lib/x86_64-linux-gnu/crtn.o /lib/x86_64-linux-gnu/crt1.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc
替代原命令:
ld -o output main.o -e main
后程序可正常运行,说明这些crt相关文件、动态链接器以及libc库是生成可执行文件并正常运行的必需组件。
问题重现步骤
1. 编写LLVM IR代码
仅实现返回退出码15的逻辑:
; ModuleID = 'main.ll' source_filename = "main" ; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) define i32 @main() local_unnamed_addr #0 { main: ret i32 15 } attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
2. 编译生成目标文件
使用LLVM 17的llc工具将IR转换为.o目标文件:
llc-17 -filetype=obj main.ll -o main.o
3. 链接生成可执行文件
使用ld(也尝试过ld.lld)执行链接操作:
ld -o output main.o -e main
运行错误与调试信息
运行生成的output程序时触发段错误(Segmentation fault),以下是相关调试细节:
objdump -D main.o输出
反汇编目标文件的结果:
main.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <main>: 0: b8 0f 00 00 00 mov $0xf,%eax 5: c3 ret
file output输出
查看可执行文件属性:
output: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
GDB调试信息
启动gdb ./output并执行run命令后:
Starting program: /.../output Program received signal SIGSEGV, Segmentation fault. 0x0000000000000001 in ?? ()
执行bt(栈回溯)命令:
#0 0x0000000000000001 in ?? () #1 0x00007fffffffdce6 in ?? () #2 0x0000000000000000 in ?? ()
执行info registers(查看寄存器状态)命令:
rax 0xf 15 rbx 0x0 0 rcx 0x0 0 rdx 0x0 0 rsi 0x0 0 rdi 0x0 0 rbp 0x0 0x0 rsp 0x7fffffffd8d8 0x7fffffffd8d8 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 r13 0x0 0 r14 0x0 0 r15 0x0 0 --Type <RET> for more, q to quit, c to continue without paging--c rip 0x1 0x1 eflags 0x10202 [ IF RF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 k0 0x0 0 k1 0x0 0 k2 0x0 0 k3 0x0 0 k4 0x0 0 k5 0x0 0 k6 0x0 0 k7 0x0 0
内容的提问来源于stack exchange,提问作者user15137953
相关产品推荐
相关产品推荐

