Xcode中和symbols有關(guān)的幾個設(shè)置

Symbols是什么東西呢?雖然我對它沒有深入的了解,但是大概知道它的作用改鲫。摘抄《深入理解計算機(jī)系統(tǒng)》里的一些描述:

一個典型的ELF可重定位目標(biāo)文件包含下面幾個節(jié):

... ...

.symtab:一個符號表香罐,它存放在程序中定義和引用的函數(shù)和全局變量信息。一些程序員錯誤地認(rèn)為必須通過-g選項來編譯程序才能得到符號表信息音比。實際上,每個可重定位目標(biāo)文件在.symtab中都有一張符號表氢惋。然而洞翩,和編譯器中的符號表不同,.symtab符號表不包含局部變量的條目焰望。

... ...

.debug:一個調(diào)試符號表骚亿,其條目是程序中定義的局部變量和類型定義,程序中定義和引用的全局變量熊赖,以及原始的C源文件来屠。只有以-g選項調(diào)用編譯驅(qū)動程序時才會得到這張表。

... ...

為了構(gòu)造可執(zhí)行文件,鏈接器必須完成兩個主要任務(wù):

符號解析(symbol resolution)俱笛。目標(biāo)文件定義和引用符號捆姜。符號解析的目的是將每個符號引用剛好和一個符號定義聯(lián)系起來。

重定位(relocation)迎膜。編譯器和匯編器生成從地址0開始的代碼和數(shù)據(jù)節(jié)泥技。鏈接器通過把每個符號定義與一個存儲器位置聯(lián)系起來,然后修改所有對這些符號的引用磕仅,使得它們指向這個存儲器位置珊豹,從而重定位這些節(jié)。

Objective-C有一些自己的生成符號的規(guī)則榕订,比如文檔中有提到:

The dynamic nature of Objective-C complicates things slightly. Because the code that implements a method is not determined until the method is actually called, Objective-C does not define linker symbols for methods. Linker symbols are only defined for classes.

Objective-C不會為方法定義鏈接符號店茶,只會為類定義鏈接符號。

可以在終端中用nm命令查看一個可重定位文件或可執(zhí)行文件的符號表劫恒,其中加上-a參數(shù)可以顯示包括調(diào)試符號在內(nèi)的所有符號贩幻。

合理的選擇與symbols有關(guān)的設(shè)置選項,可以縮減app的大小两嘴,一定程度上能阻礙與源代碼有關(guān)的信息被攻擊者獲得段直。Xcode的build setting中,有不少與symbols有關(guān)溶诞,現(xiàn)在我來依次試驗這幾個設(shè)置選項,了解一下它們的具體作用决侈。

剛開始的時候螺垢,我使用Xcode7.2.1新建了一個工程,以下試驗均在run和DEBUG模式下進(jìn)行赖歌。


Generate Debug Symbols [GCC_GENERATE_DEBUGGING_SYMBOLS]

在Xcode7.2.1中枉圃,Generate Debug Symbols這個設(shè)置在DEBUG和RELEASE下均默認(rèn)為YES。

官方文檔對這個設(shè)置的說明:

Enables or disables generation of debug symbols.? When debug symbols are enabled, the level of detail can be controlled by the build 'Level of Debug Symbols' setting.

調(diào)試符號是在編譯時生成的庐冯。在Xcode中查看構(gòu)建過程孽亲,可以發(fā)現(xiàn),當(dāng)Generate Debug Symbols選項設(shè)置為YES時展父,每個源文件在編譯成.o文件時返劲,編譯參數(shù)多了-g和-gmodules兩項。但鏈接等其他的過程沒有變化栖茉。

Clang文檔對-g的描述是:

Generate complete debug info.

當(dāng)Generate Debug Symbols設(shè)置為YES時篮绿,編譯產(chǎn)生的.o文件會大一些,當(dāng)然最終生成的可執(zhí)行文件也大一些吕漂。

當(dāng)Generate Debug Symbols設(shè)置為NO的時候亲配,在Xcode中設(shè)置的斷點不會中斷。但是在程序中打印[NSThread callStackSymbols],依然可以看到類名和方法名吼虎,比如:

** 0 XSQSymbolsDemo ???????????????????????????????? 0x00000001000667f4 -[ViewController viewDidLoad] + 100**

在程序崩潰時犬钢,也可以得到帶有類名和方法名的函數(shù)調(diào)用棧

現(xiàn)在把Generate Debug Symbols設(shè)置回YES,開始試驗下一個設(shè)置思灰。


Debug Information Level [CLANG_DEBUG_INFORMATION_LEVEL]

在Xcode 7.2.1中玷犹,Debug Information Level的默認(rèn)值為Compiler default,還有一個選項是Line tables only官辈。

官方文檔的描述是:

Toggles the amount of debug information emitted when debug symbols are enabled.? This can impact the size of the generated debug information, which can matter in some cases for large projects (such as when using LTO).

當(dāng)我把Debug Information Level設(shè)置為Line tables only的時候箱舞,然后構(gòu)建app,每個源文件在編譯時拳亿,都多了一個編譯參數(shù):-gline-tables-only

Clang的文檔中這樣解釋-gline-tables-only:

Generate line number tables only.

This kind of debug info allows to obtain stack traces with function names, file names and line numbers (by such tools as gdb or addr2line). It doesn’t contain any other data (e.g. description of local variables or function parameters).

這種類型的調(diào)試信息允許獲得帶有函數(shù)名晴股、文件名和行號的函數(shù)調(diào)用棧,但是不包含其他數(shù)據(jù)(比如局部變量和函數(shù)參數(shù))肺魁。

所以當(dāng)Debug Information Level設(shè)置為Line tables only的時候电湘,斷點依然會中斷,但是無法在調(diào)試器中查看局部變量的值:

現(xiàn)在把Debug Information Level設(shè)置回Compiler default鹅经,然后試驗下一個設(shè)置寂呛。


Strip Linked Product [STRIP_INSTALLED_PRODUCT]

在Xcode7.2.1中,Strip Linked Product在DEBUG和RELEASE下均默認(rèn)為YES瘾晃。

這是一個讓我困惑了很久的設(shè)置選項贷痪。當(dāng)我把這一設(shè)置選項改為NO的時候,最終構(gòu)建生成的app大小沒有任何變化蹦误,這讓我覺得很奇怪劫拢。

原來,Strip Linked Product也受到Deployment Postprocessing設(shè)置選項的影響强胰。在Build Settings中舱沧,我們可以看到,Strip Linked Product是在Deployment這欄中的偶洋,而Deployment Postprocessing相當(dāng)于是Deployment的總開關(guān)熟吏。

Xcode7.2.1中,Deployment Postprocessing在DEBUG和RELEASE下均默認(rèn)為NO玄窝。

現(xiàn)在我們把Deployment Postprocessing設(shè)置為YES牵寺,對比Strip Linked Product設(shè)為YES和NO的這兩種情況,發(fā)現(xiàn)當(dāng)Strip Linked Product設(shè)為YES的時候恩脂,app的構(gòu)建過程多了這樣兩步:

在app構(gòu)建的開始缸剪,會生成一些.hmap輔助文件;(為什么會多出這一步我好像還不太清楚)

在app構(gòu)建的末尾东亦,會執(zhí)行Strip操作杏节。

當(dāng)Strip Linked Product設(shè)為YES的時候唬渗,運(yùn)行app,斷點不會中斷奋渔,在程序中打印[NSThread callStackSymbols]也無法看到類名和方法名:

** 0? XSQSymbolsDemo? ? ? ? ? ? ? ? ? ? ? 0x000000010001a7f4 XSQSymbolsDemo + 26612**

而在程序崩潰時镊逝,函數(shù)調(diào)用棧中也無法看到類名和方法名,注意右上角變成了unnamed_function:

繼續(xù)保持Strip Linked Product和Deployment Postprocessing為YES嫉鲸,下面來看看Strip Style設(shè)置選項撑蒜。


Strip Style [STRIP_STYLE]

在Xcode7.2.1中,Strip Style在DEBUG和RELEASE下均默認(rèn)All Symbols玄渗。

官方文檔中對Strip Style的描述:

Defines the level of symbol stripping to be performed on the linked product of the build.? The default value is defined by the target's product type. [STRIP_STYLE]

All Symbols - Completely strips the binary, removing the symbol table and relocation information. [all, -s]

Non-Global Symbols - Strips non-global symbols, but saves external symbols. [non-global, -x]

Debugging Symbols - Strips debugging symbols, but saves local and global symbols. [debugging, -S]

選擇不同的Strip Style時座菠,app構(gòu)建末尾的Strip操作會被帶上對應(yīng)的參數(shù)。

如果選擇debugging symbols的話藤树,函數(shù)調(diào)用棧中浴滴,類名和方法名還是可以看到的。

如果我們構(gòu)建的不是一個app岁钓,而是一個靜態(tài)庫升略,需要注意,靜態(tài)庫是不可以strip all的屡限。這時構(gòu)建會失敗品嚣。想想符號在重定位時的作用,如果構(gòu)建的靜態(tài)庫真的能剝離所有符號钧大,那么它也就沒法被鏈接了翰撑。

現(xiàn)在我們保持Deployment Postprocessing為YES,Strip Linked Product改回NO啊央,Strip Style改回All Symbols眶诈,接下來看下一個設(shè)置。


Strip Debug Symbols During Copy [COPY_PHASE_STRIP]

網(wǎng)上有很多文章劣挫,以為Strip Debug Symbols During Copy開啟的時候,app中的調(diào)試符號會被剝離掉东帅。我感覺他們混淆了Strip Linked Product和Strip Debug Symbols During Copy的用法压固。

文檔上的描述是:

Activating this setting causes binary files which are copied during the build (e.g., in a Copy Bundle Resources or Copy Files build phase) to be stripped of debugging symbols.? It does not cause the linked product of a target to be stripped (use Strip Linked Product for that).

Strip Debug Symbols During Copy中的During Copy是什么意思呢?我覺得可能是app中引入的某些類型的庫靠闭,在app的構(gòu)建過程中需要被復(fù)制一次帐我。雖然我暫時沒找全究竟什么樣的“庫”需要在app構(gòu)建時被復(fù)制,但是我發(fā)現(xiàn)愧膀,當(dāng)app中包含extension或者watch app的時候拦键,構(gòu)建過程中會有Copy的步驟:

當(dāng)我將app(而非extension)的Strip Debug Symbols During Copy設(shè)置為YES之后,在這句copy的命令中會多出-strip-debug-symbols參數(shù)檩淋。

但是這里芬为,strip并不能成功萄金,并且出現(xiàn)了warning:

warning: skipping copy phase strip, binary is code signed: /Users/xsq/Library/Developer/Xcode/DerivedData/XSQSymbolsDemo-cysszdsykroyyddkvvyffgboglvo/Build/Products/Debug-iphoneos/Today.appex/Today

這似乎是由于app中的today extention已經(jīng)經(jīng)過了code sign,導(dǎo)致無法被篡改引起的警告媚朦。

那么如果略過code sign的過程氧敢,是否就能成功strip呢?我想使用模擬器調(diào)試可以略過code sign過程询张,于是便在模擬器上試了試孙乖。果然這個warning消失了义矛。

Strip Debug Symbols During Copy設(shè)置為YES時汹买,打開對應(yīng).app文件的“顯式包內(nèi)容”,可以看到工坊,/PlugIns/Today.appex文件的大小變小了蜗帜。(不過這些只能在使用模擬器時奏效)

Strip Debug Symbols During Copy置為YES的時候恋拷,today extension中的斷點將不會中斷,但是打印[NSThread callStackSymbols]時的類名和方法名還是可以看見的钮糖。

現(xiàn)在我們把Strip Debug Symbols During Copy設(shè)置回NO梅掠,來看看下一個設(shè)置。


Debug Information Format [DEBUG_INFORMATION_FORMAT]

Xcode7.2.1中店归,Debug Information Format在DEBUG下默認(rèn)為DWARF阎抒,在RELEASE下默認(rèn)為DWARF with dSYM File。

官方文檔的解釋是:

This setting controls the format of debug information used by the developer tools. [DEBUG_INFORMATION_FORMAT]

DWARF - Object files and linked products will use DWARF as the debug information format. [dwarf]

DWARF with dSYM File - Object files and linked products will use DWARF as the debug information format, and Xcode will also produce a dSYM file containing the debug information from the individual object files (except that a dSYM file is not needed and will not be created for static library or object file products). [dwarf-with-dsym]

當(dāng)Debug Information Format為DWARF with dSYM File的時候消痛,構(gòu)建過程中多了一步Generate dSYM File:

最終產(chǎn)出的文件也多了一個dSYM文件且叁。

不過,既然這個設(shè)置叫做Debug Information Format秩伞,所以首先得有調(diào)試信息逞带。如果此時Generate Debug Symbols選擇的是NO的話,是沒法產(chǎn)出dSYM文件的纱新。

dSYM文件的生成展氓,是在Strip等命令執(zhí)行之前。所以無論Strip Linked Product是否開啟脸爱,生成的dSYM文件都不會受影響遇汞。

不過正如文檔中所說,無法為靜態(tài)庫生成dSYM文件簿废。即便為給一個靜態(tài)庫的Debug Information Format設(shè)置為DWARF with dSYM File空入,構(gòu)建過程中依然不會有生成dSYM文件的步驟。


一種配置方案

了解了每個設(shè)置的意思族檬,個人覺得對于一個普通的app來說可以這樣配置這些設(shè)置:

Generate Debug Symbols:DEBUG和RELEASE下均設(shè)為YES(和Xcode默認(rèn)一致)歪赢;

Debug Information Level:DEBUG和RELEASE下均設(shè)為Compiler default(和Xcode默認(rèn)一致);

Deployment Postprocessing:DEBUG下設(shè)為NO单料,RELEASE下設(shè)為YES埋凯,這樣RELEASE模式下就可以去除符號縮減app的大械懵ァ(但是似乎設(shè)置為YES后,會牽涉一些和bitcode有關(guān)的設(shè)置递鹉,對于bitcode暫時還不太了解(′?_?`))盟步;

Strip Linked Product:DEBUG下設(shè)為NO,RELEASE下設(shè)為YES躏结,用于RELEASE模式下縮減app的大腥磁獭;

Strip Style:DEBUG和RELEASE下均設(shè)為All Symbols(和Xcode默認(rèn)一致)媳拴;

Strip Debug Symbols During Copy:DEBUG下設(shè)為NO黄橘,RELEASE下設(shè)為YES;

Debug Information Format:DEBUG下設(shè)為DWARF屈溉,RELEASE下設(shè)為DWARF with dSYM File塞关,dSYM文件需要用于符號化crash log(和Xcode默認(rèn)一致);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末子巾,一起剝皮案震驚了整個濱河市帆赢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌线梗,老刑警劉巖椰于,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仪搔,居然都是意外死亡瘾婿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門烤咧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來偏陪,“玉大人,你說我怎么就攤上這事煮嫌〉亚” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵昌阿,是天一觀的道長饥脑。 經(jīng)常有香客問我,道長宝泵,這世上最難降的妖魔是什么好啰? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任轩娶,我火速辦了婚禮儿奶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鳄抒。我一直安慰自己闯捎,他們只是感情好椰弊,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瓤鼻,像睡著了一般秉版。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茬祷,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天清焕,我揣著相機(jī)與錄音,去河邊找鬼祭犯。 笑死秸妥,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沃粗。 我是一名探鬼主播粥惧,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼最盅!你這毒婦竟也來了突雪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涡贱,失蹤者是張志新(化名)和其女友劉穎咏删,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盼产,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饵婆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了戏售。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侨核。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖灌灾,靈堂內(nèi)的尸體忽然破棺而出搓译,到底是詐尸還是另有隱情,我是刑警寧澤锋喜,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布些己,位于F島的核電站,受9級特大地震影響嘿般,放射性物質(zhì)發(fā)生泄漏段标。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一炉奴、第九天 我趴在偏房一處隱蔽的房頂上張望逼庞。 院中可真熱鬧,春花似錦瞻赶、人聲如沸赛糟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽璧南。三九已至掌逛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間司倚,已是汗流浹背豆混。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留动知,地道東北人崖叫。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像拍柒,于是被迫代替她去往敵國和親心傀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

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

  • 其實被這個問題困擾了好久拆讯,不過秉承著三分鐘熱度的新年新氣象脂男,還是要多弄懂一點(⊙_⊙)ゞ Symbols是什么東西...
    賣萌涼閱讀 55,142評論 22 164
  • 【轉(zhuǎn)載】曾夢想仗劍走天涯 1.Xcode IDE概覽 說明:從左到右,依次是“導(dǎo)航窗格(Navigator)->邊...
    06a6a973d7ab閱讀 3,834評論 2 20
  • 1.Xcode IDE概覽 說明:從左到右种呐,依次是“導(dǎo)航窗格(Navigator)->邊列(Gutter)->焦點...
    小地閱讀 5,363評論 0 9
  • 參考文章鏈接:關(guān)于Xcode編譯性能優(yōu)化的研究工作總結(jié) 一宰翅、編譯時長優(yōu)化Architectures 在Build ...
    夏天的風(fēng)_song閱讀 1,744評論 0 2
  • 人的一生會遇到各色各樣的人,我相信與每個人的相遇都不像是表面上那么簡單爽室,上天讓我們相遇便是有他的理由汁讼,讓我們分道...
    eve的秘密閱讀 583評論 0 1