【问题标题】:gcc: segmentation fault when compiling with nostdlibgcc:使用 nostdlib 编译时出现分段错误
【发布时间】:2014-03-06 21:52:46
【问题描述】:

我正在试验入口点并遇到了段错误。

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

【问题讨论】:

    标签: c gcc linker segmentation-fault


    【解决方案1】:

    retq 从栈顶取返回地址并从那里执行...问题是根据Linux执行二进制的方式,参数个数在栈上,执行转移到地址0x1(如果没有给出了论据)

    使用 gdb 设置一些虚拟参数 (set args x y z)

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

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

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

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

    【讨论】:

    • 谢谢,但是我如何在不包含 stdlib 的情况下退出()?
    • 我设法使用带有程序集的系统调用退出,但我想知道是否有纯 c 解决方案。 pastebin.com/nteHpCmZ
    • @Dimid 不能存在“纯 C”解决方案,因为您必须执行 exit 系统调用,而在纯 C 中没有办法做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    相关资源
    最近更新 更多