|
Debugging Threads
This section assumes that you have a thread-capable
gdbserver, available in the download
section.
Note: if you get the message
Ignoring
packet error, continuing...
Ignoring packet error, continuing...
Reply contains invalid hex digit 79
Stopped due to shared library event
you have to increase the remotetimeout in gdb (default is 2
seconds):
set remotetimeout 60
libthread_db
The gdbserver uses libthread_db, a helper library, when
debugging threads. If you are on a glibc-based system,
libthread_db is already available. If you are on an uclibc-based
system, make sure PTHREADS_DEBUG_SUPPORT is set in your .config
file (or else gdbserver won't compile).
Pthread Debugging Example
The following is an example of what a pthread debugging
session might look like, along with some basic commands. The
example program below just creates 5 threads and waits for
them to terminate. The call to sleep is just there so we'll
have a chance at looking at the threads before they terminate.
#include
<pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *thread_function(void *arg)
{
printf("Hello
World from %d!\n", arg);
sleep(10);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t
threads[NUM_THREADS];
int i;
for (i =
0; i < NUM_THREADS; i++)
pthread_create(&threads[i],
NULL, thread_function, (void *)i);
for (i =
0; i < NUM_THREADS; i++)
pthread_join(threads[i], NULL);
return
0;
}
First we set everything up and connect:
(gdb)
set solib-search-path /usr/local/cris/r59/cris-axis-linux-gnu/lib/
(gdb) set solib-absolute-prefix /dev/null/
(gdb) set remotetimeout 60
(gdb) target remote 10.84.130.10:2222
Remote debugging using 10.84.130.10:2222
0x35557608 in ?? ()
Next we set a breakpoint in main after all threads have
been created:
(gdb)
break 20
Breakpoint 1 at 0x80568: file hello.c, line 20.
Now send the program on its way:
(gdb)
c
Continuing.
[New Thread 1024]
[Switching to Thread 1024]
Breakpoint 1, main (argc=1, argv=0x9ffffe84) at hello.c:20
20
for (i = 0; i < NUM_THREADS; i++)
The 'info
threads' command displays information about the active
threads:
(gdb)
info threads
7 Thread 5126 0x355f04fe in nanosleep ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
6 Thread 4101 0x355f04fe in nanosleep ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
5 Thread 3076 0x355f04fe in nanosleep ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
4 Thread 2051 0x355f04fe in nanosleep ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
3 Thread 1026 0x355f04fe in nanosleep ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
2 Thread 2049 0x35608072 in __poll (fds=0xfffffffc, nfds=1, timeout=2000)
at
../sysdeps/unix/sysv/linux/poll.c:63
* 1 Thread 1024 main
(argc=1, argv=0x9ffffe84) at hello.c:22
Notice
that there are 7 threads, and not just the 5 that we created
in the program. Besides the main thread there is also a
management thread. Now switch thread using the 'thread'
command:
(gdb)
thread 4
[Switching to thread 4 (Thread 2051)]#0
0x355f04fe in nanosleep ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
As usual, use 'backtrace' to find out how the thread ended
up in nanosleep:
(gdb)
backtrace
#0 0x355f04fe
in nanosleep ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
#1 0x355f0496
in __sleep (seconds=4294967292)
at
../sysdeps/unix/sysv/linux/sleep.c:81
#2 0x0008050c
in thread_function (arg=0x1) at hello.c:8
#3 0x3556e06a
in pthread_start_thread (arg=0xfffffffc) at manager.c:262
#4 0x3556e0b2
in pthread_start_thread_event (arg=0x9f5ffc00) at
manager.c:285
#5 0x3560d244
in clone ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
#6 0x3560d244
in clone ()
from /usr/local/cris/r59/cris-axis-linux-gnu/lib/libc.so.6
Previous frame identical to this frame (corrupt stack?)
Don't be
alarmed by the "corrupt stack?" message. It is
explained in the Known problems
section.
|