2014-12-25 82 views
3

我在我的項目中使用breakpad來處理崩潰並生成堆棧跟蹤。 在堆棧跟蹤中,函數調用stackwalker發現的信息的方式有很多種。過程這裏Finding_the_caller_frame描述:由實測值堆掃描 堆棧跟蹤:堆棧掃描vs調用框架與給定的指令指針在上下文中

    • 由實測值調用幀信息
    • 由實測值:在上下文

    給出指令指針什麼`它們之間的差別?更重要的是他們如何在調試方面提供幫助?

    Thread 0 (crashed) 
        0 test_google_breakpad!crash [test_breakpad.cpp : 17 + 0x4] 
         r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c 
         r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000 
         sp = 0xbea2cb50 lr = 0x00009025 pc = 0x00008f84 
        Found by: given as instruction pointer in context 
        1 test_google_breakpad!main [test_breakpad.cpp : 25 + 0x3] 
         r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c 
         r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000 
         sp = 0xbea2cb50 pc = 0x00009025 
        Found by: call frame info 
        2 libc.so + 0x164e5 
         r4 = 0x00008f64 r5 = 0xbea2cc34 r6 = 0x00000001 r7 = 0xbea2cc3c 
         r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000 
         sp = 0xbea2cc18 pc = 0x400c34e7 
        Found by: call frame info 
    
  • 回答

    3

    指令指針方法意味着有在函數的內存位置已經指向一個CPU寄存器,因此沒有必要搜索功能。這是找到當前堆棧幀的最簡單也是最可靠的方法。

    接下來使用調用框架技術,您可以通過查看存儲返回地址的堆棧內存中的位置來查找當前函數的調用方。這是「返回」用於查找其返回目的地的確切技術。這種技術可以被鏈接,因爲每個先前的調用也將其返回值放在堆棧上。這非常可靠,但是如果某些堆棧內存被損壞(可能是堆棧溢出,可能是指令寫入錯誤)並且一個或多個返回地址被刪除,則可能會失敗。

    最後,最不可靠的技術就是在堆棧內存中搜索任何看起來像函數地址的東西。這可以幫助您從損壞的堆棧中恢復,但很難將函數地址之外的數據(包括函數指針!)告訴它,因此這是猜測。然而,如果你找到一個,如果你發現一些未被丟棄的堆棧,你可以經常鏈接回調用框架技術。