關(guān)于duplicate symbol的思考

關(guān)于duplicate symbol的思考

iOS 開發(fā)中經(jīng)常會遇到duplicate symbol這個問題丙者,在編譯鏈接的時候就會出現(xiàn)哥纫。相信有經(jīng)驗的開發(fā)都知道是怎么回事。那今天要講的就是編譯器在link時的一個坑召川!

講個故事

最近在我們在發(fā)布SDK的時候南缓,測試和預發(fā),以及灰度都做完了荧呐。在正式發(fā)布的時候直接閃退了汉形。看到這個問題直接一臉懵逼坛增!

在SDK中获雕,我們接入了人臉識別的SDK,在APP里面接入的時候收捣,出現(xiàn)了閃退届案。掛在了RSA驗簽上,為什么同樣的SDK會在正式發(fā)布的時候必閃退呢罢艾?由于涉及些公司安全東西楣颠,本篇是個閹割版尽纽,就不說解決過程了,我直接告訴結(jié)果了童漩!

iOS系統(tǒng)API中并沒有提供RSA公鑰驗簽的算法API弄贿。既然掛在了這里,懷疑是扣了openssl的部分代碼矫膨,進行了修改差凹。APP里面也接入了openssl,然后在編譯鏈接的時候侧馅,實際的RSA調(diào)用函數(shù)是外面的openssl的RSA危尿,導致了crash。

探索

既然是兩個庫里面同時存在同樣的symbol馁痴,為什么不報duplicate symbol的錯誤谊娇?我們下面寫個demo進行測試下。

一罗晕、建立兩個測試Library(LinkLibraryA和LinkLibraryB)和一個demo工程济欢。

  • LinkLibraryA
//.h
#ifndef LinkLibraryA_h
#define LinkLibraryA_h

#include <stdio.h>

void sameMethod();

#endif /* LinkLibraryA_h */

//.c
void sameMethod()
{
    printf("==== Library A ====");
}

  • LinkLibraryB
//.h
#ifndef LinkLibraryB_h
#define LinkLibraryB_h

#include <stdio.h>

void sameMethod();

#endif /* LinkLibraryB_h */

//.c
void sameMethod()
{
    printf("==== Library B ====");
}

  • demo
//mian.c
#include <stdio.h>

#include "LinkLibraryA.h"

int main(int argc, const char * argv[]) {
    
    sameMethod();
    return 0;
}

二、測試過程

直接編譯發(fā)現(xiàn)xcode并沒有報duplicate symbol錯誤小渊。

測試1——先鏈接LinkLibraryA再鏈接LinkLibraryB

運行結(jié)果:==== Library A ====

測試2——先鏈接LinkLibraryB再鏈接LinkLibraryA

運行結(jié)果:==== Library B ====

通過以上兩個測試法褥,我們可以發(fā)現(xiàn),存在同樣的symbol粤铭,link的時候是不報錯的挖胃!而且執(zhí)行結(jié)果是依賴于靜態(tài)庫ld的順序的!

進一步測試

  • 修改下LinkLibraryB
//.h
#ifndef LinkLibraryB_h
#define LinkLibraryB_h

#include <stdio.h>

int sameMethod();

void testMethod(int a);

#endif /* LinkLibraryB_h */

//.c
int sameMethod()
{
    printf("==== Library B ====");
    return 1;
}

void testMethod(int a)
{
    printf("==== test link===");
}

sameMethod增加一個返回值梆惯,增加另個一入?yún)⑹莍nt的testMethod的函數(shù)酱鸭。

  • 修改下demo測試代碼
//main.c
#include <stdio.h>

#include "LinkLibraryB.h"

int main(int argc, const char * argv[]) {
    
    testMethod(sameMethod());
    
    return 0;
}

在main函數(shù)里面,我們在testMethod方法中垛吗,將sameMethod當入?yún)魅搿?/p>

測試1——先鏈接LinkLibraryA再鏈接LinkLibraryB

運行結(jié)果:編譯不通過凹髓!報duplicate symbol _sameMethod

測試2——先鏈接LinkLibraryB再鏈接LinkLibraryA

運行結(jié)果:=== Library B ======== test link===

總結(jié)

通過以上測試可以發(fā)現(xiàn),如果linker解決unresolved symbols時怯屉,如果已經(jīng)找到symbol蔚舀,那么將不再去其他靜態(tài)庫里面尋找。

后面兩組測試锨络,第一組報錯了赌躺,是因為ld LinkLibraryA的時候已經(jīng)發(fā)現(xiàn)sameMethod,但是需要解決testMethod的symbol羡儿,接著ld LinkLibraryB的時候礼患,LinkLibraryB里面的LinkLibraryB.o中找到了testMethod,但是,又一次發(fā)現(xiàn)了sameMethod缅叠,所以報錯了悄泥!(后來,我把testMethod換成單獨的文件去寫肤粱,無論先鏈接誰弹囚,都是編譯不報錯的,但是邏輯和上面說的一樣领曼,從側(cè)面也說明了linker優(yōu)先尋找本靜態(tài)庫的符號鸥鹉,如果找到將不再去其他靜態(tài)庫進行尋找)

如果在other linker flags里面添加-all_load那么也就正常報錯了,也就是我們所說的linker不允許存在重復的符號庶骄!

思考

通過以上測試宋舷,我們發(fā)現(xiàn)了在接入靜態(tài)庫的時候,容易出現(xiàn)此類問題瓢姻。所以,我覺得以下幾個點音诈,大家還是需要關(guān)注下:

  • C沒有函數(shù)重載幻碱,哪怕你參數(shù)多一個,編譯鏈接的時候细溅,也不會報錯褥傍。因此,命名應有一套規(guī)范喇聊,防止和外面的C函數(shù)進行沖突

這點我覺得可以參考OC的方法恍风,加上前綴。

  • C函數(shù)不對外開放的函數(shù)誓篱,盡量加上static朋贬,限制它的作用域
  • 對于接入的多個SDK依賴共同的SDK,請一定要仔細確認版本窜骄。

以上問題锦募,大家注意下,希望大家別再踩了這個坑邻遏!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糠亩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子准验,更是在濱河造成了極大的恐慌赎线,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糊饱,死亡現(xiàn)場離奇詭異垂寥,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門矫废,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盏缤,“玉大人,你說我怎么就攤上這事蓖扑“ν” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵律杠,是天一觀的道長潭流。 經(jīng)常有香客問我,道長柜去,這世上最難降的妖魔是什么灰嫉? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮嗓奢,結(jié)果婚禮上讼撒,老公的妹妹穿的比我還像新娘。我一直安慰自己股耽,他們只是感情好根盒,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著物蝙,像睡著了一般炎滞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诬乞,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天册赛,我揣著相機與錄音,去河邊找鬼震嫉。 笑死森瘪,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的责掏。 我是一名探鬼主播柜砾,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼换衬!你這毒婦竟也來了痰驱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤瞳浦,失蹤者是張志新(化名)和其女友劉穎担映,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叫潦,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡蝇完,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片短蜕。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡氢架,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出朋魔,到底是詐尸還是另有隱情岖研,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布警检,位于F島的核電站近零,受9級特大地震影響趾撵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剑令,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一桌硫、第九天 我趴在偏房一處隱蔽的房頂上張望瑰艘。 院中可真熱鬧绪抛,春花似錦莹捡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至移国,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間道伟,已是汗流浹背迹缀。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蜜徽,地道東北人祝懂。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像拘鞋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子盆色,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容