Tomasz Kasperczyk
Tomasz Kasperczyk

Reputation: 2093

How to properly use gdb?

I want gdb to display only my code (skip the included headers). I'm struggling with the segmentation fault thrown randomly by my multithreaded program. In gdb I can see this:

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

At what point in MY code (not in the thread library) the error occurred? Or at least which call to the thread::joinable() function caused the error? Is it possible to get such information? I'm sorry for asking such questions, but I'm totally new to debugging with gdb.

Upvotes: 0

Views: 232

Answers (2)

Michael Karcher
Michael Karcher

Reputation: 4011

The innermost (active) stack frame is frame #0, the caller ist frame #1 and so on. Looking from top to bottom, I notice that frame #0 is in a function inside namespace std and refers to a system header file as source code, but already frame #1 mentions a method in a class called Finder, which is not provided by the standard library, and also the source code path does not refer to a system header. Also a quick google does not yield results indicating that the Finder class is part of a well-known framework, so it is most likely your code.

Finder::join_threads calls joinable on a std::thread pointer that is nullptr (aka NULL) in line 25 of global_search.cpp.

Upvotes: 1

Tom Tromey
Tom Tromey

Reputation: 22519

There are two cases here.

One case -- the one in your question -- concerns stack traces. In this case there is just no way to eliminate the frames coming from outside your program. I suppose gdb could be taught to do this somehow, say with a frame filter, but it would be confusing in practice, as the debugger would then be presenting a falsified view of the current state of the program you're debugging.

For this case I usually just use the "up" command to walk up the stack until I see something I'm interested in.

The other case is stepping. For this case gdb provides the "skip" command, which instructs it not to single-step into certain bits of code. This can be handy to elide accessors and foreign code. Note that this doesn't present the same problem as dropping information from a stack trace, as gdb isn't falsifying any information, it is just treating "step" and "next" as shorthand for longer operations.

Upvotes: 1

Related Questions