我正在嘗試使用extern和各種鏈接方法來更好地理解鏈接過程。將兩個目標文件鏈接在一起會導致分段錯誤11
我有三個文件:
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(從我可以收集的是一些通用的內存損壞錯誤,如正常的段錯誤(?)
這是我用來編譯和鏈接分開的生成文件。請注意,我指定我自己的入口點和鏈接對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'用法有些問題。另外,如果任何人有任何關於連接器和裝載機如何工作的好書的建議,我當然是在一個市場上。我聽說過有關「連接器和裝載器」的各種各樣的事情,所以我在等待更多意見之前,特別是在我的書中投入時間。
感謝您對此提供的任何幫助...我對連接器的理解不足爲奇。
構建程序的這兩種方式在「將目標文件鏈接在一起」與「將源文件鏈接在一起」方面有很多不同之處! – immibis
'-e'鏈接器選項指向的函數比標準C'main'更具責任。入口點通常由C運行時鏈接,它負責設置和拆除可執行文件的支持結構,並與動態鏈接器緊密結合。你可能會在ld.so的某個地方崩潰,因爲它希望某些結構可以通過關閉來存在。您可以使用gdb驗證並檢查堆棧跟蹤。 – zneak