In this article we will discuss how to debug multi-threading C++ application using gdb debugger.

Compiling Multi-threaded Code using g++ with Debug Info

To compile code in debug mode in gcc/g++ we need to use option “-g” .
Also in Linux to compile multi threading we need to include pthread library option i.e. “-pthread”.

Let see how to compile a c++11 thread code (sample.cpp) with debug symbol i.e.

g++ -g --std=c++11 -pthread sample.cpp -o sample

Now start the debugging.

How to List all active threads

To list all the active threads use command,

“info threads”

For example,

(gdb) info threads
Id Target Id Frame
4 Thread 0x7ffff6fc3700 (LWP 2281) "sample" 0x00007ffff73c34fd in write () at ../sysdeps/unix/syscall-template.S:81
3 Thread 0x7ffff67c2700 (LWP 2282) "sample" __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
2 Thread 0x7ffff5fc1700 (LWP 2283) "sample" __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
* 1 Thread 0x7ffff7fd0740 (LWP 2277) "sample" __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
(gdb)

 

Each row represents a thread and contains info like thread id and current frame.
So, like in above example we have 4 active threads. Each thread has an assigned ID, which is visible in first column.

How to Check Stack trace of threads

In non multi threading applications there is only one thread i.e. main function. Therefore, to check the stacktrace we use command “bt”.
But in multi threading applications, as there are many threads and each threads has its own stack.
But “bt” command will display the stack trace of current active thread only. Now what if want to inspect stacktrace of all the threads at same point ?

To display the stack trace of all the threads use following command

(gdb) thread apply all bt

It will display the stack trace of all the active threads.

 

The command “thread apply applies the specified command to specified thread ID. Also, you can specify “all” instead of thread ID to apply the command to all threads.

To display the stack trace of current thread only use command “bt” i.e.

(gdb) bt

It will show the stacktrace as follows,
(gdb) bt
#0 __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
#1 0x00007ffff733bb1a in __GI__IO_fwrite (buf=0x7ffff7692970 , size=1, count=11, fp=0xffffffffffffffff) at iofwrite.c:41
#2 0x00007ffff7b63a66 in std::basic_ostream<char, std::char_traits >& std::__ostream_insert<char, std::char_traits >(std::basic_ostream<char, std::char_traits >&, char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7b63e77 in std::basic_ostream<char, std::char_traits >& std::operator<< <std::char_traits >(std::basic_ostream<char, std::char_traits >&, char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x000000000040104f in main () at sample.cpp:23
(gdb)

Now how to inspect stacktrace of different threads?

How to Switch between threads while debugging

To switch between different threads to inspect their stack trace while debugging use following command,

(gdb) thread <Thread Number>

For example,
(gdb) thread 2

It will switch the debugger to thread 2. Now if use will type “bt” command then it will show the stack trace of thread 2.

Join a list of 2000+ Programmers for latest Tips & Tutorials