Debugging with GDB
1. 调试多线程
1.1 多线程调试示例
-
如下是我们所采用的调试示例源代码
test.c
#include <stdio.h> #include <unistd.h> #include <pthread.h> int a = 0; int b = 0; static void * pthread_run1(void *arg) { int runflag = 1; while(runflag) { a++; sleep(1); } pthread_exit((void *)a); return NULL; } static void * pthread_run2(void *arg) { int runflag = 1; while(runflag) { b++; sleep(1); } pthread_exit((void *)b); return NULL; } int main(int argc,char *argv[]) { pthread_t tid1, tid2; int retval_1, retval_2; pthread_create(&tid1, NULL, pthread_run1, NULL); pthread_create(&tid2, NULL, pthread_run2, NULL); pthread_join(tid1,(void *)&retval_1); pthread_join(tid2,(void *)&retval_2); printf("retval_1: %d\n", retval_1); printf("retval_2: %d\n", retval_2); return 0x0; }
- 编译运行
gcc -c test.c -o test.o
- GDB调试多线程程序
先进入gdb
gdb test.c
打断点
b test.c:14
b test.c:29
run
开始循环跳转
Thread 2 "test" hit Breakpoint 1, pthread_run1 (arg=0x0) at test.c:14
14 a++;
(gdb) n
[Switching to Thread 0x7ffff73fe640 (LWP 961250)]
Thread 3 "test" hit Breakpoint 2, pthread_run2 (arg=0x0) at test.c:29
29 b++;
(gdb) n
30 sleep(1);
(gdb) n
[Switching to Thread 0x7ffff7bff640 (LWP 961249)]
Thread 2 "test" hit Breakpoint 1, pthread_run1 (arg=0x0) at test.c:14
14 a++;
(gdb) n
[Switching to Thread 0x7ffff73fe640 (LWP 961250)]
Thread 3 "test" hit Breakpoint 2, pthread_run2 (arg=0x0) at test.c:29
29 b++;
(gdb) n
30 sleep(1);
(gdb) n
[Switching to Thread 0x7ffff7bff640 (LWP 961249)]
如果在sleep结束的时候查看线程会发现
(gdb) info/i threads
Id Target Id Frame
1 Thread 0x7ffff7fa5740 (LWP 961246) "test" __futex_abstimed_wait_common64 (private=128, cancel=true, abstime=0x0, op=265, expected=961249, futex_word=0x7ffff7bff910)
at ./nptl/futex-internal.c:57
2 Thread 0x7ffff7bff640 (LWP 961249) "test" pthread_run1 (arg=0x0) at test.c:14
* 3 Thread 0x7ffff73fe640 (LWP 961250) "test" pthread_run2 (arg=0x0) at test.c:30
让我们切换现在到thread 2
(gdb) thread 2
[Switching to thread 2 (Thread 0x7ffff7bff640 (LWP 961249))]
#0 pthread_run1 (arg=0x0) at test.c:14
14 a++;
在执行过程中可以使用backtrace查看当前线程调用栈信息
(gdb) backtrace/bt
#0 pthread_run1 (arg=0x0) at test.c:14
#1 0x00007ffff7c94ac3 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#2 0x00007ffff7d26850 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
如果只想运行当前的调试进程,其他线程挂起
set scheduler-locking on
(gdb) n
30 sleep(1);
(gdb) n
27 while(runflag)
(gdb) n
Thread 3 "test" hit Breakpoint 2, pthread_run2 (arg=0x0) at test.c:29
29 b++;
(gdb) n
30 sleep(1);
(gdb) n
n27 while(runflag)
(gdb) n
Thread 3 "test" hit Breakpoint 2, pthread_run2 (arg=0x0) at test.c:29
29 b++;
(gdb) n
30 sleep(1);
指定某线程执行gdb命令
thread apply 'num' n
(gdb) i thread
Id Target Id Frame
1 Thread 0x7ffff7fa5740 (LWP 1379754) "test" __futex_abstimed_wait_common64 (private=128, cancel=true, abstime=0x0, op=265, expected=1379763,
futex_word=0x7ffff7bff910) at ./nptl/futex-internal.c:57
2 Thread 0x7ffff7bff640 (LWP 1379763) "test" pthread_run1 (arg=0x0) at test.c:14
* 3 Thread 0x7ffff73fe640 (LWP 1379764) "test" pthread_run2 (arg=0x0) at test.c:30
(gdb) thread apply 2 n
Thread 2 (Thread 0x7ffff7bff640 (LWP 1379763) "test"):
15 sleep(1);
还有一些指令可以使用
info local #查看当前变量
frame/f 'num' #查看和切换当前堆栈
set var runflag = 0 #修改变量