2014-03-06 64 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中沒有辦法做到這一點。 –

相關問題