2015-02-11 34 views
0

我希望gdb只顯示我的代碼(跳過包含的頭文件)。我正在努力解決由多線程程序隨機拋出的分段錯誤。在gdb中我可以看到這一點:如何正確使用gdb?

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0x7fffeffff700 (LWP 27533)] 
0x0000000000409939 in std::thread::joinable (this=0x0) at /usr/include/c++/4.9.2/thread:162 
162  { return !(_M_id == id()); } 
(gdb) bt 
#0 0x0000000000409939 in std::thread::joinable (this=0x0) at /usr/include/c++/4.9.2/thread:162 
#1 0x0000000000404562 in Finder::join_threads (this=0x7ffff0000cd0) at global_search.cpp:25 
#2 0x0000000000416ea9 in std::_Mem_fn<void (Finder::*)()>::operator()<, void>(Finder&) const (this=0x7ffff00013c0, __object=...) at /usr/include/c++/4.9.2/functional:556 
#3 0x0000000000416d1e in std::_Mem_fn<void (Finder::*)()>::operator()<Finder<>, void>(std::reference_wrapper<Finder<> >, (void&&)...) const (this=0x7ffff00013c0, __ref=...) 
    at /usr/include/c++/4.9.2/functional:585 
#4 0x00000000004166fe in std::_Bind_simple<std::_Mem_fn<void (Finder::*)()> (std::reference_wrapper<Finder>)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0x7ffff00013b8) 
    at /usr/include/c++/4.9.2/functional:1700 
#5 0x00000000004160eb in std::_Bind_simple<std::_Mem_fn<void (Finder::*)()> (std::reference_wrapper<Finder>)>::operator()() (this=0x7ffff00013b8) 
    at /usr/include/c++/4.9.2/functional:1688 
#6 0x0000000000415b12 in std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (Finder::*)()> (std::reference_wrapper<Finder>)> >::_M_run() (this=0x7ffff00013a0) 
    at /usr/include/c++/4.9.2/thread:115 
#7 0x00007ffff76b4d90 in execute_native_thread_routine() from /usr/lib/libstdc++.so.6 
#8 0x00007ffff7910374 in start_thread() from /usr/lib/libpthread.so.0 
#9 0x00007ffff6e2427d in clone() from /usr/lib/libc.so.6 

發生在什麼時候在我的代碼(不是在線程庫)的錯誤?或者至少對thread :: joinable()函數的哪個調用導致了錯誤?是否有可能獲得這樣的信息?我很抱歉問這樣的問題,但我完全不熟悉用gdb進行調試。

回答

1

最內層(活動)堆棧幀是幀#0,調用者是幀#1,依此類推。從上到下,我注意到frame#0在名字空間std內部的一個函數中,並且將系統頭文件稱爲源代碼,但是第1幀已經在類Finder中提到了一種方法,該方法不是由標準庫,並且源代碼路徑也不涉及系統頭。另外一個快速谷歌不會產生結果表明Finder類是一個着名框架的一部分,所以它很可能是你的代碼。

Finder::join_threads調用global_search.cpp的第25行中的std :: thread指針nullptr(又名NULL)可加入。

1

這裏有兩種情況。

一個案例 - 您的問題之一 - 涉及堆棧跟蹤。在這種情況下,沒有辦法消除來自程序外部的幀。我想gdb可能會被教會以某種方式這樣做,用框架過濾器來說,但實際上會讓人感到困惑,因爲調試器會呈現出您正在調試的程序當前狀態的僞造視圖。

對於這種情況,我通常只是用「UP」命令向上走棧,直到我看到一些我感興趣的。

另一種情況是步進。在這種情況下,gdb提供了「skip」命令,它指示它不要單步進入特定的代碼位。這可以方便地刪除訪問者和外部代碼。請注意,這不會像從堆棧跟蹤中刪除信息那樣出現問題,因爲gdb不會僞造任何信息,只是將「step」和「next」視爲較長操作的簡寫。