簡體   English   中英

沒有源代碼時gdb回溯的含義

[英]Meaning of a gdb backtrace when there is not source code

我有一個崩潰的進程的gdb回溯,但是我看不到發生崩潰的特定行,因為當時源代碼不在那一刻。 我不理解上述回溯提供的某些信息。

回溯由以下幾行組成:

<path_to_binary_file>(_Z12someFunction+0x18)[0x804a378]

請注意, _Z12someFunctionint someFunction(double )名稱。

我的問題是:

+0x18是否表示從導致崩潰的匯編指令開始的_Z12someFunction地址偏移量?

如果前面的問題是肯定的,並且考慮到我使用的是32位體系結構,那么+0x18表示0x18 * 4字節?

如果以上是肯定的,我假定地址0x804a378_Z12someFunction0x18 ,對嗎?

編輯:

該錯誤是在生產機器 (未啟用內核)中發生的,並且它似乎是與時間有關的錯誤,因此重現它並不容易。 這是因為在這種情況下,我要提供的信息對我很重要。

您的大多數假設都是正確的。 +0x18確實意味着到可執行文件的偏移量(以字節為單位,與體系結構無關)。

0x804a378是發生錯誤的實際地址。

話雖如此,了解您可以采取的措施非常重要。

首先,使用-g編譯將產生調試符號。 您理所當然地剝離了那些用於生產構建的產品,但一切都沒有丟失。 如果使用原始可執行文件(即-在條帶化之前),則可以運行: addr2line -e executable

然后,您可以將gdb給您的地址(0x804a378)輸入到stdin中,而addr2line將為您提供該地址所指向的精確文件和行。

如果您有核心文件,則還可以使用無條紋的可執行文件加載該核心文件,並獲取完整的調試信息。 由於您可能正在使用優化進行構建,因此仍然有些混亂,但是某些變量仍然應該可以訪問。

最好使用調試符號進行構建並在發貨前進行剝離。 但是,即使您沒有這樣做,如果您在相同的環境上使用相同的構建工具並使用相同的構建選項再次構建相同的源代碼,那么您應該獲得具有相同符號位置的相同二進制文件。 如果該錯誤確實很難重現,則可能值得嘗試。

編輯添加

另外兩個重要的工具是c++filt 您為它提供了一個錯誤的符號,並生成了到實際源符號的C ++路徑。 它用作過濾器,因此您只需復制回溯並將其粘貼到c ++ filt中,它將為您提供相同的回溯,但更具可讀性。

第二個工具是gdb遠程調試。 這使您可以在具有帶有調試符號的可執行文件的計算機上運行gdb,但在生產計算機上運行實際的代碼。 這允許在生產環境中進行實時調試(包括附加到已經運行的進程)。

你很困惑。 您看到的是glibc的backtrace函數的backtrace輸出,而不是gdb的backtrace。

但我看不到發生崩潰的特定行,因為那時候源代碼不在那一刻

現在,您可以在gdb中加載可執行文件,並檢查地址0x804a378以獲取行號。 您可以使用list *0x804a378info symbol 0x804a378 請參閱將libc backtrace轉換為源行號如何在linux中使用addr2line命令

運行man gcc,您應該在其中看到-g選項,該選項使您可以將調試信息添加到二進制目標文件中,因此當發生崩潰並轉儲內核時,gdb可以檢測出崩潰發生的確切位置和原因,或者可以運行使用gdb或附加到該進程的過程,而無需搜索核心文件即可直接查看跟蹤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM