2011-01-06 23 views
5

我有一個非常複雜的跨平臺應用程序。最近,我和我的團隊一直在進行壓力測試,並且遇到過幾次崩潰(以及隨之而來的核心轉儲)。其中一些核心轉儲非常精確,並向我顯示發生崩潰的確切位置,其中包含大約10個或更多的堆棧幀。其他人有時只有一個堆棧框架?是唯一的象徵!如何增加Linux核心轉儲匹配符號的概率?

我想知道的是:

  1. 是否有增加核心轉儲在正確的方向指向的概率的方法嗎?
  2. 爲什麼報告的堆棧幀數不一致?
  3. 任何最佳實踐建議管理核心轉儲。

以下是我編譯的二進制文件(在釋放模式):

  1. 編譯器和平臺:G ++用glibc-2.3.2-95.50在CentOS 3.6 x86_64的 - 這可以幫助我保持與舊的兼容性Linux版本。
  2. 所有文件都使用-g標誌進行編譯。
  3. 調試符號從最終的二進制文件中剝離並保存在一個單獨的文件中。
  4. 當我有一個核心轉儲時,我使用GDB和創建核心的可執行文件以及符號文件。 GDB從不抱怨核心/二進制/符號之間存在不匹配。

然而,我有時會得到沒有符號的核心轉儲!可以理解的是,我正在鏈接libstdC++和libgcc的非調試版本,但如果至少堆棧跟蹤顯示我在代碼中發生錯誤指令調用的位置(雖然它最終可能以?結束) 。

回答

7

其他人有時只有一個堆棧框架「??」是唯一的象徵!

可能有很多原因爲何,其中包括:

  • 堆棧幀被丟棄(覆蓋)
  • EBP/RBP(在x86/64)當前不持有任何有意義的值 - 這可能發生,例如以編譯的單元或者這樣做的asm單元

請注意,第二點可能僅僅通過例如glibc以這種方式編譯而發生。安裝這些系統庫的調試信息可以緩解這種情況(比如openSUSE上的glibc-debug {info,source}包)。

gdb比glibc對程序有更多的控制,所以glibc的backtrace調用自然會無法打印回溯,如果gdb不能這樣做的話。

但出貨來源是:-)

+2

這極有可能是問題要容易得多 - 如果堆棧幀已經被錯誤搗爛,然後就不見了。 – caf 2011-01-06 13:21:58

2
  1. 您是否嘗試過安裝您正在使用的各種庫的調試符號?例如,我的分佈(Ubuntu的)提供libc6-dbglibstdc++6-4.5-dbglibgcc1-dbg
  2. 如果你與優化啓用(如:-O2)大廈,那麼編譯器可以通過內聯模糊堆棧幀之間的邊界,例如。我不確定這是否會導致只有一個堆棧幀的回溯,但總的來說規則是期望很好的調試難度,因爲您在覈心轉儲中查找的代碼已被修改,因此不一定對應於您的源代碼。
3

作爲替代方案,glibc的系統上,你可以使用backtrace函數調用(或backtrace_symbolsbacktrace_symbols_fd)和過濾出來的結果自己,所以只屬於你自己的代碼符號的顯示方式。這是一個更多的工作,但是,然後,你可以真正量身定製它的需求。