2012-11-02 28 views
5

我試圖調試錯誤版本的函數被調用導致段錯誤的問題。我正在編譯的代碼是機器生成的,並且包含一個名爲'times'的函數,它實現了兩個參數的複數乘法。此代碼在鏈接到更高級別的對象文件之前被編譯爲.o。C程序鏈接到錯誤版本的函數

運行此代碼時,segfaults和gdb指示它在glibc的'times'版本中,它甚至沒有使用相同數量的參數。這個代碼中沒有#include的實例。

將時間的名稱更改爲times1可解決問題。這不是一個長期的解決方案,儘管由於代碼的機器生成特性以及手動編輯此函數的名稱始終沒有吸引力。

整個混亂編譯清洗與牆壁,所以我不知道在哪裏看。任何想法如何解決這個問題?

Compile chain: 
    gcc -Wall -I. -g --shared -o dpd.o -fPIC *.c (mahine generated code here) 
    gcc -g --std=c99 -c -fpic getData.c -I/usr/local/include -L/usr/local/lib -lmatio -I/usr/local/include/iverilog -I$(MATLAB) 
    gcc -g -shared -o getData.vpi getData.o $(MATLAB)/dpd.o -lvpi -lmatio -L/usr/local/lib 
+3

將多個C文件編譯爲單個'.o'並不常見。如果'times.c'是在這個組中編譯的幾個C文件之一,它可以解釋這個問題。 – Gene

+1

'#include'只能引入聲明;它無法控制鏈接。如果聲明一個名爲'times'的函數然後調用它,編譯器將生成一個對象文件,該文件在其符號表中包含對該名稱的引用,然後鏈接器將在生成最終可執行文件時搜索該名稱的定義。在libc中有一個'times'函數,這就是鏈接器找到的。 – Wyzard

+0

基因 - 您可否詳細說明您的評論? times.c確實是一個單獨的C文件,它被編譯到單個對象中。你爲什麼期望這會導致問題?實際上我只對這個.o感興趣的一個入口點,'時代'不是其中之一。即它應該是完全內部的並且不被視爲高層的動態符號。有沒有辦法告訴gcc這件事? –

回答

0

所以這個問題的真正答案是將-fno-builtin-times扔給gcc。這可以毫不費力地避免這個問題。

這當然假設您不能將名稱times更改爲與glibc提供的功能不衝突的名稱。

3

C僅使用函數的名稱作爲標識符,因此任何兩個具有相同名稱的(導出)函數都會發生衝突。正常的做法是將所有導出的名稱前綴放在一個唯一的前綴中。另一種選擇是使用C++作爲「更好的C」,並簡單地使用C++編譯器構建C代碼,從而利用C++名稱修改。

+0

不應該在這種情況下鏈接器與「重複符號」窒息? – 2012-11-02 22:55:51

+0

除非您強制將其拖入兩個具有相同符號的不同.o文件中。 – bmargulies

+0

@ H2CO3 UNIX連接器*在主可執行文件和共享庫(這裏是'libc.so.6')中定義相同的符號時,永遠不會抱怨 - 這種符號插入相當常見並且通常非常有用。 –