gdb
多线程篇
能力介绍
gdb
能调试多线程程序,可以同时调试多个进程.支持远程调试,即执行在另一个系统上的程序.另一个系统可以是不同平台.
inferior
- 用这么一个对象表示一个调试程序.不管有没有执行,都会记录.
调试某个程序,调试多个程序就有多个
inferior
.默认创建一个,被调试程序不管有没有执行,即程序执行前存在,程序终止后也存在。
- 可以理解为一个调试会话。一个程序一个会话。或者说一个进程一个会话,不过进程执行前和执行后都存在,所以用进程也不是很准确。
查看调试的程序
查看调试的程序
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
表示当前调试程序会话编号为1
。description
的值表示这个进程的进程号是9371
,可以通过/proc/pid/
查看信息。executable
表示路径。有的可能有五列: 当前执行,进程描述,远程还是本地,可执行文件.
查看当前的会话
inferror
多线程
多线程的本质
- 就是多个进程共享了一些数据
(地址空间,堆,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
查看代码,可以看到显示的不一样。
多进程调试
编号差异
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
的编号,后面就是线程的编号。- 同样的
*
表示当前正在调试的线程。