已解決 由於鏈結順序引起的符號定位未找到問題

2021-10-17 16:11:47 字數 1839 閱讀 2263

最近在將我們的工程切換到cmake工具構建,遇到了乙個由於鏈結順序引起的問題,當時沒看出來原因,被困擾了幾個小時,特此記錄一下。

編譯報錯類似下面這樣,提示在libsum.a庫中sum函式找不到add的定義。

/usr/bin/ld: libsum.a(sum.o): in function `sum':

sum.c:(.text+0x1d): undefined reference to `add'

collect2: error: ld returned 1 exit status

怎麼會沒找到呢?我明明鏈結了libadd.a呀,難道庫有問題。

通過nm命令檢視libadd.a中的符號,如下。

add.o:

0000000000000000 t add

有add啊,但是符號值怎麼是全0?沒有寫實現嗎?

於是去看原始檔,發現其實是有實現的。

那麼問題出在**呢?

這時候乙個聲音響起,「會不會是鏈結順序不對?」,真可謂一語驚醒夢中人。

馬上把libsum.a和libadd.a的鏈結順序對換,問題果然解決了。

(其實,當時沒想起來這個原因,也是因為在切換cmake之前,這個鏈結順序也能通過編譯。很奇怪,還需要再深入看看。)

通過報錯,基本就可以看出來了,在libsum.a中使用了libadd.a中的符號,那麼鏈結時需要將libsum.a放前面,libadd.a放後面。

這個是由編譯器決定的,對於gcc來說,libsum.a放前面,libadd.a放後面,當找不到libsum.a中的符號時,它會在後面的鏈結庫中繼續查詢。

大家可以自己試試,這裡提供原始檔和編譯命令。

add.h

#

ifndef

__add_h__

#define

__add_h__

intadd

(int a,

int b);#

endif

add.c

#

include

"add.h"

intadd

(int a,

int b)

sum.h

#

ifndef

__sum_h__

#define

__sum_h__

intsum

(int a,

int b);#

endif

sum.c

#

include

"add.h"

#include

"sum.h"

intsum

(int a,

int b)

main.c

#

include

"sum.h"

#include

intmain()

首先生成add靜態庫

gcc -c add.c -o add.o

ar -rc libadd.a add.o

然後生成sum靜態庫

gcc -c sum.c -o sum.o

ar -rc libsum.a sum.o

編譯main.c(鏈結順序不對)

gcc main.c libadd.a libsum.a -o main

解決由於意外斷電引起的活動目錄服務停止問題

背景 位於集團b座的機房已經使用多年,很多硬體條件開始制約公司it的發展。6月中旬一天,由於機房空調進行維修,工人師傅冒然拉斷了電源總閘,導致機房內部分伺服器意外斷電。集團總部的兩台用活動目錄域控制器也不幸遇難。現象 負責機房的工程師在第一時間進行了及時的處理。恢復供電之後馬上啟動因斷電而停止的伺服...

解決由於意外斷電引起的活動目錄服務停止問題

背景 位於集團b座的機房已經使用多年,很多硬體條件開始制約公司it的發展。6月中旬一天,由於機房空調進行維修,工人師傅冒然拉斷了電源總閘,導致機房內部分伺服器意外斷電。集團總部的兩台用活動目錄域控制器也不幸遇難。現象 負責機房的工程師在第一時間進行了及時的處理。恢復供電之後馬上啟動因斷電而停止的伺服...

順序執行命令需要哪個符號鏈結 搭建自己的符號伺服器

看雪論壇作者id comor 注意 如果你要找的是微軟符號伺服器,不用往下看了 當發生應用異常崩潰 驅動藍屏時,無論是測試環境,還是生產環境,分析dump檔案通常是快速定位問題的乙個最佳選擇 前提是生成了dump檔案 特別是在生產環境時,既沒有原始碼又沒有偵錯程式,這時只有將日誌檔案 dump檔案拷...