2015-02-11 56 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”视为较长操作的简写。