2014-03-06 65 views
1

我正在试验入口点并得到段错误。gcc:使用nostdlib进行编译时出现分段错误

prog.c中:

int main() { 
    return 0; 
} 

编译和与链接:

gcc -Wall prog.c -nostdlib -c -o prog.o 
ld prog.o -e main -o prog.out 

objdump的:

Sections: 
Idx Name   Size  VMA    LMA    File off Algn 
0 .text   0000000b 00000000004000b0 00000000004000b0 000000b0 2**2 
       CONTENTS, ALLOC, LOAD, READONLY, CODE 
1 .eh_frame  00000038 00000000004000c0 00000000004000c0 000000c0 2**3 
       CONTENTS, ALLOC, LOAD, READONLY, DATA 
2 .comment  0000001c 0000000000000000 0000000000000000 000000f8 2**0 
       CONTENTS, READONLY 

Disassembly of section .text: 
00000000004000b0 <main>: 
4000b0: 55      push %rbp 
4000b1: 48 89 e5    mov %rsp,%rbp 
4000b4: b8 00 00 00 00   mov $0x0,%eax 
4000b9: 5d      pop %rbp 
4000ba: c3      retq 

Valgrind的输出:

Access not within mapped region at address 0x0 

回答

6

retq从堆栈的顶端获取返回地址并从那里执行......问题在于,根据Linux执行二进制文件的方式,参数的数量在堆栈上并且执行转移到地址0x1(如果没有参数给出)

设置使用gdb一些哑元(套ARGS XYZ)

你可以编译和调试信息(-g)链接,然后使用gdb的 设置在retq指令断点(宽* 0x4000ba )并运行程序

执行最后的指令并观察SIGSEGV地址对应的参数个数+ 1

程序应该用系统调用退出,不retq

看到 http://eli.thegreenplace.net/2012/08/13/how-statically-linked-programs-run-on-linux/ 一些有用的背景资料

+0

谢谢,但我怎么能退出(),而不包括STDLIB? – dimid

+0

我设法退出使用程序集系统调用,但我想知道是否有一个纯粹的C解决方案。 http://pastebin.com/nteHpCmZ – dimid

+1

@Dimid“纯C”解决方案不能存在,因为你*必须*执行'exit'系统调用,并且纯C中没有办法做到这一点。 –

相关问题