天天看點

[轉載]DWARF dSYM

xcode編譯生成framework

作者:吳建波(成都-N/A)

最近用XCode做了一個靜态庫,在自己電腦上别的App project中編譯使用沒有任何問題,但是傳給别的同僚使用在編譯的時候就會出現類似于下面警告。

warning: (i386) /UsersLibrary/Developer/Xcode/DerivedData/ProjectName-ebyadedaazwurqcvfzmyzzacvlbg/Build/Intermediates/ ProjectName.build/Debug-iphonesimulator/ProjectName.build/Objects-normal/i386/ClassName.o unable to open object file

通過在Google裡面搜尋,終于弄明白了,通過在XCode裡面将Generate Debug Symbol的值設為NO,重新編譯一下生成靜态庫,這次編譯出來的靜态庫再也不會産生已經警告了。這是為什麼呢?

在開始解釋原因之前,我們需要看一下什麼是 Debug Symbol / Debug Information

一、 Debug Symbol(調試符号)

首先來看看維基百科上的解釋:http://en.wikipedia.org/wiki/Debug_symbol

A debug symbol is information that expresses which programming-language constructs generated a specific piece of machine code in a given executable module. Sometimes the symbolic information is compiled together with the module's binary file, or distributed in separate file, or simply discarded during the compilation and/or linking. This information enables a person using a symbolic debugger to gain additional information about the binary, such as the names of variables and routines from the original source code. This information can be extremely helpful while trying to investigate and fix a crashing application or any other fault.

When debug symbols are embedded in the binary itself, the file can then grow significantly larger (sometimes by several megabytes). To avoid this extra size, modern compilers and early mainframe debugging systems output the symbolic information into a separate file; for Microsoft compilers, this file is called a PDB file. Some companies ship the PDB on their CD/DVD to enable troubleshooting and other companies (like Microsoft, and the Mozilla Corporation) have special online servers from which it's possible to download the debug symbols separately. 

我簡單翻譯下上面兩段話(英語比較爛,翻譯得不好,請諒解):

調試符号(debug symbol)是代表在給定的可執行的子產品中由程式設計語言産生的一段特定的機器碼的資訊。有時這些符号資訊被編譯進子產品的二進制檔案中,或者以單獨的檔案的形式進行分發,或者在編譯/連結的時候直接丢棄。這些資訊使得人們可以一種符号調試程式來擷取關于二進制檔案的額外資訊,比如變量的名稱和來自于源代碼的routines(不知道怎麼翻譯比較好)。這些資訊在我們研究和修複程式的崩潰問題或者别的錯誤的時候非常有用。

-----------------------為什麼會非常有用呢?----------------------------

因為借助符号調試程式可以将類似

Thread 0 Crashed: 0 libobjc.A.dylib 0×300c87ec 0×300bb000 + 55276 1 MobileLines 0×00006434 0×1000 + 21556 2 MobileLines 0×000064c2 0×1000 + 21698 3 UIKit 0×30a740ac 0×30a54000 + 131244

的log資訊轉換成

0 libobjc.A.dylib 0×300c87ec objc_msgSend + 20 1 MobileLines 0×00006434 -[BoardView setSelectedPiece:] (BoardView.m:321) 2 MobileLines 0×000064c2 -[BoardView touchesBegan:withEvent:] (BoardView.m:349) 3 UIKit 0×30a740ac -[UIWindow sendEvent:] + 264

-------------------這樣應該能非常明了地指出問題所在吧?-------------------

當調試符号被嵌入進二進制檔案本身的時候,檔案的尺寸會顯著地增長(不難了解吧?檔案中放入了額外的資訊,自然就大了)。為了避免這個額外的檔案尺寸(為什麼要避免,應該不難了解吧),現在的編譯器(新的,和老舊的相對)和早期的大型機調試系統将符号資訊輸出到單獨的檔案中(為什麼要輸出到單獨的檔案中?調試符号資訊對于普通的使用者是沒有用的,它隻對開發人員追蹤問題有用,嵌入到二進制檔案中隻會增大檔案尺寸,延長使用者下載下傳的時間,而且也會暴露你程式的内部資訊,如果你想保護你的代碼不被别人猜到,你應該考慮不要在二進制檔案中包含調試資訊)。比如微軟的編譯器,這個檔案叫做PDB檔案,有的公司通過CD/DVD的方式來傳輸,有的公司提供線上的伺服器單獨進行下載下傳,通過PDB檔案,你可以進行程式故障診斷(發現程式出錯的地方)。

通過上面簡單的介紹,我想大家應該對Debug Symbol應該已經有了個大概的認識了。

二、DWARF

接下來我們看看DWARF是什麼。  官方網站:http://dwarfstd.org/

官方網站對DWARF的簡單介紹:

DWARF is a debugging file format used by many compilers and debuggers to support source level debugging. It addresses the requirements of a number of procedural languages, such as C, C++, and Fortran, and is designed to be extensible to other languages. DWARF is architecture independent and applicable to any processor or operating system. It is widely used on Unix, Linux and other operating systems, as well as in stand-alone environments.  

DWARF是一種被衆多編譯器和調試器使用的用于支援源代碼級别調試的調試檔案格式。它滿足了許多程式語言的需求,比如C,C++和Fortran,而且被設計成可拓展到其它語言。DWARF是平台獨立的且适用于任何處理器任何作業系統。 DWARF廣泛應用于Unix,Linux和其它作業系統,以及獨立的環境中。

為了更好地了解DWARF,可以閱讀下這篇文章:http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/  由于篇幅的原因原文就不貼過來了,直接簡單翻譯下。

從2008-02-27開始, STABS(一種調試資料格式)被蘋果Apple棄用。XCode項目build setting中DEBUG_INFORMATION_FORMAT預設的STABS被取代。

通過STABS, 你可以建立帶有調試符号(debugging symbols)的程式的release版本,拷貝一份可執行程式MyApp.app/Contents/MacOS/MyApp儲存起來, 而把此可執行檔案除去調試符号用于分發(strip the executable for shipping), 然後用未除去調試符号的可執行程式來進行崩潰分析。和STABS不同, DWARF不将調試符号包含到可執行檔案自身裡面,而是僅在可執行檔案裡包含對中間對象檔案的引用( references to the intermediate object files),而這些中間對象檔案中則包含着調試符号。通常你可以在build/MyApp.build目錄的子目錄下找到這些中間對象檔案(.o files,如果你使用XCode,這些檔案則通常在/Developer/XCode/DerivedData/MyApp-****/Build/Intermediates目錄下)。如果你在使用DWARF編譯後删除這些對象檔案,你将不能對你的代碼進行單步調試。 (如果你使用<code>stabs</code>, 這些對象檔案則是完全無用的.) 如果你把調試符号從你的程式中除去(strip debugging symbols from your app),你也不能進行單步調試,因為可執行檔案中已經不存在對中間對象檔案的引用了。

三、dSYM

為了避免進行stripping操作後調試符号的丢失,你可以使用<code>dwarf-with-dsym選項</code>. DWARF with dSYM 選項在标準的DWARF之外執行一個額外的步驟:建立一個單獨的MyApp.app.dSYM檔案,這個檔案包含你的程式的所有調試符号(這個檔案其實是一個包,可以通過右鍵-&gt;顯示包内容進行檢視)。事實上,DWARF with dSYM選項允許你對你進行單步調試而不管可執行程式是否被剝離了調試資訊(stripped)。這是可能的,這是因為gdb将會在你的程式的目錄下查找<code>.dSYM</code>檔案。它不需要知道對象檔案(object files)的名字或者路徑。如果你不除去調試符号 (strip debugging symbols), 你可以使用.o或者<code>.dSYM</code>檔案來調試。

繼續閱讀