【问题标题】:Linking two object files together causes segmentation fault 11将两个目标文件链接在一起会导致分段错误 11
【发布时间】:2017-02-03 06:33:34
【问题描述】:

我正在试验外部变量和各种链接方法,以更好地理解链接过程。

我有三个文件:

foo.c:

#include "foo.h"
int a = 4;

test.c:

#include <stdio.h>

#include "foo.h"
int main(int, char**);
int mymain();

int mymain() {
    main(0, 0);
    printf("test\r\n");
    return 0;
}
int main(int argc, char** argv) {
    printf("extern a has %d\r\n", a);
    return 0;
}

foo.h:

extern int a; // defined in foo.c

如果我将每个文件一起构建并在编译时使用 gcc 进行链接,如下所示:

gcc *.c -o final.bin

我可以执行 final.bin 为:

./final.bin

得到预期的输出

extern a has 4

但是,如果我分别编译(但不链接)test.c 和 foo.c,然后尝试在运行时将目标文件链接在一起以生成二进制文件,我会收到分段错误 11(从我可以收集一些通用的内存损坏错误,例如正常的段错误(?)

这是我用来分别编译和链接的makefile。注意我正在指定我自己的入口点并链接到 libc 以获取 printf()...

all: test.o foo.o
    @echo "Making all..."
    ld test.o foo.o -o together.bin -lc -e _mymain

test.o: test.c
    @echo "Making test..."
    gcc -c test.c -o test.o

foo.o: foo.c
    @echo "Making foo..."
    gcc -c foo.c -o foo.o

运行“together.bin”时的输出:

./together.bin 
extern a has 4
test
Segmentation fault: 11

也许我对“mymain”的函数签名是错误的?我的猜测是我的“myentry”用法有问题。

另外,如果有人对链接器和加载器如何工作的好书有任何建议,我当然在市场上想要一本。我听说过关于“链接器和加载器”的各种说法,所以我正在等待更多的意见,然后再特别投入时间阅读那本书。

感谢您对此提供的任何帮助...我对链接器的理解至少可以说是低于标准的。

【问题讨论】:

  • 这两种构建程序的方式比“将目标文件链接在一起”与“将源文件链接在一起”有更多的区别!
  • -e 链接器选项指向的函数比标准的 C main 具有更多的职责。入口点通常从 C 运行时链接进来,它负责为可执行文件设置和拆除支持结构,与动态链接器紧密耦合。您可能在 ld.so 的某个地方崩溃了,因为它预计某些结构会在关闭时存在。您可以使用 gdb 验证并检查堆栈跟踪。

标签: c linker segmentation-fault extern


【解决方案1】:

除非你有充分的理由这样做,否则只需使用 gcc 链接:

$ gcc test.o foo.o "-Wl,-e,_mymain" -o ./final.bin; ./final.bin 
extern a has 4
test

gcc 调用 ld ---不过,参数比您在示例中提供的参数多。如果您想确切了解 gcc 如何调用 ld,请使用 -v 选项。示例:

$ gcc -v test.o foo.o "-Wl,-e,_mymain" -o ./final.bin
Apple LLVM version 8.0.0 (clang-800.0.38)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -o ./final.bin test.o foo.o -e _mymain -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a

【讨论】:

  • 感谢您的回复 - 这解决了我的问题。我假设某些 gcc 调用链接器以某种方式这样做......我想知道为什么。当我有机会时,我会更多地阅读链接器。我会接受你的解决方案作为答案,但我的代表少于 15 个,所以我不能这样做。
猜你喜欢
  • 1970-01-01
  • 2015-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 2013-05-10
  • 1970-01-01
  • 2018-06-28
相关资源
最近更新 更多