GDB调试多线程

来源:互联网 发布:爱思苹果助手 mac 编辑:程序博客网 时间:2024/06/08 11:12
GDB是*nix下常用的调试工具,可以提供及其复杂的调试功能,功能十分强大。这里展示一下GDB调试多线程的常规方法。
常用命令:
info threads :显示当前可以调试的所有线程。
thread IDx : IDx请用上述命令中的线程ID替换,该命令用于切换被调试的线程,请注意GDB只能调试一个执行序列,也就一个传统意义上的进程
break file.c:20 thread all:在file.c中的第20行,为所有经过这里的线程设置断点
set scheduler-locking off|on|step:线程之间是并行执行的,step之类的命令会对所有线程生效。该命令就是提供了一种只对单一线程生效的解决方式。选项off表示不锁定任何进程,也就是默认情况。on表示命令只对当前线程生效。step表示在单步的时候,除了next过一个函数的情况以外,只对当前线程执行。

使用举例:

应用1,下面代码会产生coredump,我们调试之。

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <pthread.h>  
  3.   
  4. int a(void){  
  5.     sleep(2);  
  6.     return 0;  
  7. }  
  8.   
  9. int b(){  
  10.     a();  
  11.     return 0;  
  12. }  
  13.   
  14. int c(){  
  15.     b();  
  16.     return 0;  
  17. }  
  18. void *myThread1(void)  
  19. {  
  20.     int i=9;  
  21.     while(i>0)  
  22.     {  
  23.         printf("Our 1st pthread,created by chn89.\n");  
  24.         sleep(2);  
  25.         i--;  
  26.         c();  
  27.     }  
  28.     pthread_exit(0);  
  29. }  
  30.   
  31. void *myThread2(void)  
  32. {  
  33.     int i=5;  
  34.     while(i>0)  
  35.     {  
  36.         printf("Our 2st pthread,created by chn89.\n");  
  37.         sleep(2);  
  38.         i--;  
  39.     }  
  40.     pthread_exit(0);  
  41. }  
  42.   
  43. int main()  
  44. {  
  45.     int  ret=0;  
  46.     pthread_t thread_id1,thread_id2;  
  47.     
  48.     ret = pthread_create(&thread_id1, NULL, (void*)myThread1, NULL); //这里笔误,应为thread_id1 就是调试这里的错误  
  49.     if (ret)  
  50.     {  
  51.         printf("Create pthread error!\n");  
  52.         return 1;  
  53.     }  
  54.     
  55.     ret = pthread_create(&thread_id2, NULL, (void*)myThread2, NULL);  
  56.     if (ret)  
  57.     {  
  58.         printf("Create pthread error!\n");  
  59.         return 1;  
  60.     }  
  61.     
  62.     pthread_join(thread_id1, NULL);  
  63.     pthread_join(thread_id2, NULL);  
  64.     
  65.     return 0;  
  66. }  
编译之 gcc pthread_gdb.c -g  -lpthread
执行会提示segment错误,并提示产生coredump。但是却没有产生。需要执行ulimit -c unlimited。再执行一次,才真正的产生了coredump文件。
执行gdb a.out corefile 并执行bt查看执行backtrace,显示第49行执行错误。也就是初步怀疑线程1运行有问题。
执行
   gdb a.out
  (gdb) b 49
  (gdb) thread 2 //主线程是1
  (gdb) c
之后发现线程2工作正常,同理对线程2,也正常。按理pthread_join()是库函数不应该有问题,仔细检查发现,XX的笔误。这里提供了单独调试线程的方法,各位可以一试。

应用2,代码是修正笔误的上述代码,这里假设上述代码已经处于运行状态,但是跑飞了,需要确定各线程执行位置。

[cpp] view plaincopy
  1. gdb a.out   pid -- pid是运行的进程号  
  2. (gdb) thread 2  
  3. (gdb) bt  
  4. #0  0x00855416 in __kernel_vsyscall ()  
  5. #1  0x00bf1086 in nanosleep () from /lib/libc.so.6  
  6. #2  0x00bf0ea4 in sleep () from /lib/libc.so.6  
  7. #3  0x08048516 in a () at pthread_gdb.c:5  
  8. #4  0x08048528 in b () at pthread_gdb.c:10  
  9. #5  0x0804853a in c () at pthread_gdb.c:15  
  10. #6  0x08048571 in myThread1 () at pthread_gdb.c:26  
  11. #7  0x00cede99 in start_thread () from /lib/libpthread.so.0  
  12. #8  0x00c2cd2e in clone () from /lib/libc.so.6  
  13. 可以看出线程1的backtrace,正在执行函数a中的sleep呢。  


0 0
原创粉丝点击