c - 一步一步的C编译导致segfault

标签 c linux compilation ld

我正在尝试理解 C 编译

鉴于 main.c 中的这个简单的 C 代码:

int main() {
    int a;
    a = 42;
    return 0;
}

我执行了以下操作:
cpp main.c main.i
/usr/lib/gcc/x86_64-linux-gnu/9/cc1 main.i -o main.s
as -o main.o main.s
ld -o main.exe main.o

执行 main.exe 时,出现段错误。

在这个例子中我怎样才能得到一个好的内存寻址?

最佳答案

当我在 x86_64 Ubuntu 19.10 系统上尝试您的问题中的命令序列时,我收到来自 ld 的警告:

ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000

这表明出现了问题。

错误意味着链接器没有找到符号 _start并改为使用默认地址。当运行你的程序时,它会尝试在这个显然无效的地址执行代码。

从 C 代码编译的可执行程序不仅仅包含您的代码。编译器指示链接器添加 C 运行时库和启动代码。启动代码负责初始化和调用您的 main功能。

运行例如
gcc -v -o main.exe main.o

查看哪些其他文件被添加到您的程序中。在我的系统上,这显示了一些名称以 crt 开头的文件。这意味着“C 运行时”。

如果您不使用 gcc链接您的程序,但使用 ld直接,您必须以类似于编译器自动执行的方式手动添加所有必需的目标文件。

关于c - 一步一步的C编译导致segfault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60502962/

相关文章:

C 编程错误 : Reading from a . txt 文件

c - 对于 64 位操作系统,内存泄漏是否仍然相关?

c - undefined reference : linking libraries when compiling a simple GTK+ 3. 0 Windows 上的 C 程序

c# - Unity iOS编译: Cross Compilation job Mono.WebBrowser.dll failed错误

c - make 如何知道要更新哪些文件

printf 可以改变它的参数吗?

c++ - write(2) 的最佳缓冲区大小

限制在 NVIDIA Jetson TX2 上运行 GStreamer 的协商问题

python - pyenv tcshell eval pyenv int 响应非法变量名

linux - 半开套接字上的 select() 不会在 close() 上返回?