1. gdb多线程篇

    • 能力介绍

      • gdb能调试多线程程序,可以同时调试多个进程.

      • 支持远程调试,即执行在另一个系统上的程序.另一个系统可以是不同平台.

    • inferior

      • 用这么一个对象表示一个调试程序.不管有没有执行,都会记录.
      • 调试某个程序,调试多个程序就有多个inferior.

      • 默认创建一个,被调试程序不管有没有执行,即程序执行前存在,程序终止后也存在。

      • 可以理解为一个调试会话。一个程序一个会话。或者说一个进程一个会话,不过进程执行前和执行后都存在,所以用进程也不是很准确。
  2. 查看调试的程序

    • 查看调试的程序info inferiors

      chen@chen:~/cppfile/test$ g++ test.cpp -g
      chen@chen:~/cppfile/test$ gdb -q ./a.out
      Reading symbols from ./a.out...done.
      (gdb) info inferiors
       Num  Description       Executable
      * 1    <null>            /home/chen/cppfile/test/a.out
      (gdb) break main
      Breakpoint 1 at 0x4004d6: file test.cpp, line 2.
      (gdb) r
      Starting program: /home/chen/cppfile/test/a.out
      
      Breakpoint 1, main () at test.cpp:2
      2       }
      (gdb) info inferiors
       Num  Description       Executable
      * 1    process 9371      /home/chen/cppfile/test/a.out
      
      • 可以看到到调试的程序,在启动之前也有,只是没有执行信息.
      • 分析: *表示当前进程和线程。 1表示当前调试程序会话编号为1description的值表示这个进程的进程号是9371,可以通过/proc/pid/查看信息。executable表示路径。
      • 有的可能有五列: 当前执行,进程描述,远程还是本地,可执行文件.

    • 查看当前的会话

      • inferror
  3. 多线程

    • 多线程的本质

      • 就是多个进程共享了一些数据(地址空间,堆,text,bss等)的进程组合。
    • 查看线程info threads

      chen@chen:~/cppfile/test$ gdb -q ./a.out
      Reading symbols from ./a.out...done.
      (gdb) b main
      Breakpoint 1 at 0x400625: file test.cpp, line 9.
      (gdb) r
      Starting program: /home/chen/cppfile/test/a.out
      [Thread debugging using libthread_db enabled]
      Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
      
      Breakpoint 1, main () at test.cpp:9
      9           pthread_create(&tid,nullptr,run,nullptr);
      (gdb) n
      [New Thread 0x7ffff77f2700 (LWP 9412)]
      10          pthread_join(tid,nullptr);
      (gdb) printf "%p\n",tid
      0x7ffff77f2700
      (gdb) info threads
       Id   Target Id                                Frame
      * 1    Thread 0x7ffff7fed740 (LWP 9408) "a.out" main () at test.cpp:10
       2    Thread 0x7ffff77f2700 (LWP 9412) "a.out" 0x0000000000400612 in run () at test.cpp:4
      
      • *表示当前调试的线程.
      • ID表示线程在调试器中的内部编号,这里是1
      • Target ID表示当前的线程信息.lwp:light weight process轻量级线程就是进程嘛.9412就是线程号./proc/9408/task/9412就是全局进程号,这里是线程就是线程号好了。中间那个地址就是tid的值,即pthread结构体的首地址。
    • 线程切换

      (gdb) list
      5           return nullptr;
      6       }
      7       int main() {
      8           pthread_t tid;
      9           pthread_create(&tid,nullptr,run,nullptr);
      10          pthread_join(tid,nullptr);
      11      }
      (gdb) thread 2
      [Switching to thread 2 (Thread 0x7ffff77f2700 (LWP 9412))]
      #0  0x0000000000400612 in run () at test.cpp:4
      4           while(!stop);
      (gdb) list
      1       #include<pthread.h>
      2       int stop = false;
      3       void* run(void*) {
      4           while(!stop);
      5           return nullptr;
      6       }
      7       int main() {
      8           pthread_t tid;
      9           pthread_create(&tid,nullptr,run,nullptr);
      10          pthread_join(tid,nullptr);
      
      • thread id表示切换到目标线程。
      • 分别用list查看代码,可以看到显示的不一样。
  4. 多进程调试

    • 编号差异

      chen@chen:~/cppfile/test$ gdb -q ./a.out
      Reading symbols from ./a.out...done.
      (gdb) clone-inferior
      [New inferior 2 (process 0)]
      Added inferior 2.
      (gdb) info inferiors
       Num  Description       Executable
      * 1    <null>            /home/chen/cppfile/test/a.out
       2    <null>            /home/chen/cppfile/test/a.out
      (gdb) break main
      Breakpoint 1 at 0x400625: main. (2 locations)
      (gdb) r
      Starting program: /home/chen/cppfile/test/a.out
      [Thread debugging using libthread_db enabled]
      Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
      
      Breakpoint 1, main () at test.cpp:9
      9           pthread_create(&tid,nullptr,run,nullptr);
      (gdb) n
      [New Thread 0x7ffff77f2700 (LWP 9422)]
      10          pthread_join(tid,nullptr);
      (gdb) info inferiors
       Num  Description       Executable
      * 1    process 9418      /home/chen/cppfile/test/a.out
       2    <null>            /home/chen/cppfile/test/a.out
      (gdb) inferior 2
      [Switching to inferior 2 [<null>] (/home/chen/cppfile/test/a.out)]
      (gdb) info inferiors
       Num  Description       Executable
       1    process 9418      /home/chen/cppfile/test/a.out
      * 2    <null>            /home/chen/cppfile/test/a.out
      (gdb) break main
      Note: breakpoint 1 also set at pc 0x400625.
      Note: breakpoint 1 also set at pc 0x400625.
      Breakpoint 2 at 0x400625: main. (2 locations)
      (gdb) r
      Starting program: /home/chen/cppfile/test/a.out
      [Thread debugging using libthread_db enabled]
      Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
      
      Thread 2.1 "a.out" hit Breakpoint 1, main () at test.cpp:9
      9           pthread_create(&tid,nullptr,run,nullptr);
      (gdb) n
      [New Thread 0x7ffff77f2700 (LWP 9424)]
      10          pthread_join(tid,nullptr);
      (gdb) info threads
       Id   Target Id                                Frame
       1.1  Thread 0x7ffff7fed740 (LWP 9418) "a.out" main () at test.cpp:10
       1.2  Thread 0x7ffff77f2700 (LWP 9422) "a.out" 0x0000000000400612 in run () at test.cpp:4
      * 2.1  Thread 0x7ffff7fed740 (LWP 9423) "a.out" main () at test.cpp:10
       2.2  Thread 0x7ffff77f2700 (LWP 9424) "a.out" 0x0000000000400612 in run () at test.cpp:4
      
      • 首先是使用指令clone-inferior 创建了一个一模一样的环境。
      • 然后分别设置断点。
      • 再查看线程编号。
      • 可以看到ID出现了轻微的变化。1.1了,前面的就是inferior的编号,后面就是线程的编号。
      • 同样的*表示当前正在调试的线程。
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐