google breakpad for linux(2)

來源:互聯網
上載者:User

(1) overview.

  

簡述了整個breakpad工作的基本流程:

  1)程式編譯完後,先用工具事先把程式的相關debug資訊dump下來(to symbol file)。

    這些dump下來的東西主要是一些符號與源碼的對應,如各個符號在程式中對應的地址等。

    有了它,breadpad通過一個地址就能找出這個地址對應的是變數,還是函數等。

  2)把符號dump出來後,程式就可以pstrip一下,把debug資訊去除,然後發布程式。

  3)程式在啟動並執行過程中,如果發生了崩潰,程式就會進入breakpad的異常處理,這個異常處理會把當前程式的上下文,

     棧的內容,線程的資訊等,有選擇性的dump下來,儲存為一個mini dump 格式的檔案。

  4)mini dump 與symbol file結合,就可以把程式崩潰那一刻的call stack 重建出來。

(2)exception handler.
  breakpad通過響應訊號進行異常處理,Linux下,程式崩潰能被捕的訊號有幾種:
  SIGSEGV,SIGABRT,SIGFPE,SIGILL,SIGBUS.
  breadpad 在初始化的時候,就給程式設定了這些訊號的回調。
  具體可以參看:src/client/linux/handler/exception_handler.cc
  這裡代碼比較少,結構也很清晰,欲深究的讀者可以去讀代碼,作者在檔案裡畫了一個這樣流程圖:

  

 

 由上可知,在處理signal的時候,breakpad 調用clone()建立了一個新的進程(clone一個新進程使得接下來的操作能夠在一個相對穩定的環境裡進行)。

 然後在這個新的進程裡通過ptrace與父進程進行互動,把一些context,stack等,以mini dump 的形式儲存下來。

 所以,整個breakpad在client端的運行流程是比較簡單的。

 

3)mini dump file format.

  client 程式崩潰之後中,dump出來的內容主要包含以下幾個內容:

    a)當前cput context.這裡主要是一堆寄存器中的內容,cpu的狀態字等。

      有了它們我們就可以知道當前是在哪線程上運行,運行到了哪裡,堆棧的指標等。

      這裡主要與當前的硬體體系相關。

    b)關於每個線程的資訊。這裡就與具體的作業系統相關了。

       Linux下的話,LinuxPtraceDumper這個類中有說明:

         關於線程的資訊來自於/proc/$pid/status/,主要包括:tgid,ppid,pid.

         此外還有棧的內容,以及與一些與線程相關的寄存器等。

         具體細節可以參看:src/client/linux/minidump_writer.cpp.

    c)被各線程當作棧用的記憶體地區,這個裡的東西是重建call stack的關鍵資料所在,

       這裡的資料往往佔據了最後dump 檔案的大部分。

    d)載入進來的各個模組的列表。

      這裡主要包括:檔案的名字(.dll,.so,.exe etc),模組所佔用的記憶體地區,以前可能存在的debug資訊等。

      這裡的內容,並不保證都能擷取的了。

 

   以上這些程式運行時的細節內容,都是以後重建call stack時用來與symbol file進行匹配的關鍵資料。

 

4) symbol file

  符號檔案是一個包含程式源碼與可執行檔裡的機器碼相對應的東西。

  gcc編譯器開了-g進行編譯時間,會產生一堆的用於debug的資訊,這些資訊能通常以某種格式(DWARF,STABS)組織起來,存放在可執行檔的某個段位裡。

  這些debug資訊主要是:machine code to source mapping data。

  breakpad所產生的symbol file就是來自這些debug資訊。

  所不同的只是:

        1)它更簡單,資料量少

        2)它不放在可執行程式中。

  對於很多怕泄密的產品來說,第二點尤為重要,它避免了產品的源碼資訊向外暴露。

  下面具體來說一下,這個symbol file中都儲存了些什麼:

    1)全部內容都是ascii文本。

    2)每一行就是一條記錄,每條記錄中有多個欄位,每個欄位以空格分開。

    3)每條記錄的開頭是一個串字元,這個字元標記這條記錄是什麼類型的記錄。

       但Line record除外,這種類型的記錄,預設省略掉標記符,也就是如果有一行沒有標記類型,這一行就是一個Line record.

    4)記錄中有些欄位是10進位或16進位的字串,16進位也沒有以0x開頭,要分清某個數字具體是哪種進位,就要看這些數字是在哪種記錄裡,

       屬於哪個欄位,這些都是規定死了的。

    具體都有哪些欄位,請看:

     

  

  這裡結合一些具體的例子:

    檔案記錄:

    

   函數類型:

    

 

   行記錄,函數記錄:

   

  

   具體其中每條記錄的各個欄位代表什麼意思,可以參看這裡:

   https://code.google.com/p/google-breakpad/wiki/SymbolFiles

  

  就我自己使用過程中的研究來看,breakpad最麻煩的工作在於write dump & dump symbol, 這兩部分工作都很與具體的細節相關,

  如Dwarf的格式,mini dump 的格式,進程的cpu context,stack 等,一系列與程式運行很相關的底層知識。

  因此必須對Linux作業系統,程式編譯等有一定功力才能看懂這些細節。

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.