gdb调试多进程和多线程

1. gdb调试多进程

调试多进程有一种笨方法就是在fork之后子进程执行的代码中sleep一下。然后利用这段时间,通过gdb attach 子进程id。
不过在linux系统上(2.5.46之后),gdb是支持调试调试fork和vfork这种类型的多进程程序的。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[]) {
    
    
    pid_t pid = fork();
    if (pid > 0) {
    
    
        printf("parent thread\n");
        exit(0);
    } else if (pid < 0) {
    
    
        perror("fork failed");
        exit(1);
    } else {
    
    
        printf("child thread\n");
    }
    return 0;
}

下面是具体的调试过程

(gdb) show  detach-on-fork
Whether gdb will detach the child of a fork is on.
#这个参数默认是开启状态,意思就是当fork时,子进程默认detach
(gdb) show follow-fork-mode
Debugger response to a program call of fork or vfork is "parent".
(gdb) show   follow-exec-mode
Follow exec mode is "same".
(gdb) info inferiors
  Num  Description       Executable        
* 1    <null>            /root/demo_cpp2/./multi_thread 
(gdb) set detach-on-fork off #关闭
(gdb) info inferiors
  Num  Description       Executable        
* 1    <null>            /root/demo_cpp2/./multi_thread 
(gdb) n
The program is not being run.
(gdb) start
Temporary breakpoint 1 at 0x40064c: file multi_thread.c, line 5.
Starting program: /root/demo_cpp2/./multi_thread 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe378) at multi_thread.c:5
5	    pid_t pid = fork();
Missing separate debuginfos, use: debuginfo-install glibc-2.17-105.el7.x86_64
(gdb) n
[New process 10269]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
6	    if (pid > 0) {
    
    
Missing separate debuginfos, use: debuginfo-install glibc-2.17-105.el7.x86_64
(gdb) info inferiors
  Num  Description       Executable        
  2    process 10269     /root/demo_cpp2/./multi_thread 
* 1    process 10265     /root/demo_cpp2/./multi_thread 
#在这里就看到了所有进程
(gdb) n
7	        printf("parent thread\n");
(gdb) 
parent thread
8	        exit(0);
(gdb) inferior 2
[Switching to inferior 2 [process 10269] (/root/demo_cpp2/./multi_thread)]
[Switching to thread 2 (Thread 0x7ffff7fc8740 (LWP 10269))] 
#0  0x00007ffff78bb50c in fork () from /lib64/libc.so.6
# 通过inferior命令可以实现切换
(gdb) n
Single stepping until exit from function fork,
which has no line number information.
main (argc=1, argv=0x7fffffffe378) at multi_thread.c:6
6	    if (pid > 0) {
    
    
(gdb) n
9	    } else if (pid < 0) {
    
    
(gdb) n
13	        printf("child thread\n");
(gdb) show schedule-multiple
Resuming the execution of threads of all processes is off.
(gdb) set schedule-multiple on # 想让父子进程同时运行就设置成on
(gdb) n
child thread
[Thread 0x7ffff7fc8740 (LWP 10265) exited]
15	    return 0;
(gdb) 

总结一下,两个关键配置项

  • detach-on-fork 设为off,可同时调试父进程和子进程s
  • schedule-multiple 设为on,可同时运行父子进程
2. 调试多线程

gdb默认调试多线程,断点断在某个线程上时,其他线程也暂停。单步走时,其他线程也启动。这种场景,可能并不利于我们排查问题。
如果我们指向锁定一个线程来排查问题,那么可以设置scheduler-locking线程锁来将其他线程"冻住"。
set scheduler-locking on 锁定线程
set scheduler-locking off 不锁定线程,默认模式
set scheduler-locking step 单步执行时,锁定其他线程,不适用于continue, until 这些非单步操作

参考:
[0] https://sourceware.org/gdb/onlinedocs/gdb/Forks.html
[1] https://sourceware.org/gdb/onlinedocs/gdb/All_002dStop-Mode.html

猜你喜欢

转载自blog.csdn.net/niu91/article/details/112407146