使用gdb调试多进程多线程程序

来源:互联网 发布:苏联国歌 知乎 编辑:程序博客网 时间:2024/05/18 20:11

一、gdb基础知识

1、gdb是Linux环境下的一种调试工具,使用时在源程序生成是加上-g选项。

2、开始使用:gdb binFile;退出使用:ctrl+d或quit。

3、调试过程中常用的命令有:

(1)list命令

         list linenum                       显示程序第linenum行周围的程序

         list function                        显示函数名为function的函数的源程序

         list                                       显示当前行后面的源程序

         list -                                     显示当前行前面的源程序

(2)run(r)运行命令

         run args                             run命令可以直接接命令行参数值,也可以在执行run之前通过set  args +参数值实现。

(3)break(b)打断点

         b linenum                          在某行打断点

         b +offset/-offset                在当前行号的前面或后面offset停住

         b filename:linenum        在某文件的某行打断点

         b filename:function         在某文件某个函数入口停住

         b *address                       在程序的运行地址处停住

         b                                         没有参数再下一句停住

         b where if cindition          在某个条件满足时,在某行停止

    关闭断点:delete(d)bresakpoint-id

(4)单步命令

         step count                          一次性执行count步,如果有函数hiu进入函数

         next count                           一次性执行count,不进入函数

         finish                                   运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值以及参数信息

         until                                      退出循环体

(5)continue命令

          当程序被停住之后,可以使用continue(c)命令,恢复程序的运行知道程序结束或到达下一个断点。这里要注意如果没有断点程序是会直接结束的

(6)print(p)命令

           这个命令比较常用,用来查看我们想看的内容。比如有关数组可以看全部,也可以从左到右某一部分:

   print命令针对变量查看的输出格式有:

            x                                         按十六进制格式显示变量

           d                                          按十进制格式显示变量

           u                                          按十六进制格式显示无符号整型

           o                                          按八进制格式显示变量

            t                                          按二进制格式显示变量

           a                                          按字符格式显示变量

            ......

(7)watch命令

            watch expr                          为表达式expr设置一个观察点,一旦表达式值有变化,马上停住程序

           rwatch expr                          当表达式expr被读时。停住程序

           awatch expr                         当表达式的值被读或被写时,程序停住

           info watchpoints                 列出所有观察点(info指令通常可以去套)

(8)examine命令

            x/u addr                              查看内存中的值,“x/”后的n、f、u都是可选项

(9)jump命令 

       jump命令不会改变程序栈的内容,一般只在同一函数内跳转

            jump linespec                  指定下一跳语句的运行点,linespec可以是linenum,filename+linenum,+offset这几种形式

            jump address                   跳到代码行的地址

(10)ignal命令

       使用signal信号名(如SIGINT)这种方式把信号发送给程序,如果程序注册了signal_handler函数,还可以进行相应的处理,帮助调试程序

(11)set命令

             set args                               设置命令行参数

             set env environmentVarname=value设置环境变量。

(12)call命令

              call function                         强调调用某函数

         强调调用某函数,它会显示函数返回值(如果函数返回值不是void)。print命令也可以完成该功能。

(13)disassemble命令

          反汇编命令,查看执行时源代码的机器码

二、使用gdb调试多进程

1、代码调试:


2、gdb可以同时调试多个程序。

     只需设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可。

parent on                        只调试主进程(gdb默认)

child on                          只调试子进程

parent off                        同时调试两个进程,gdb和主程序,子进程block在fork位置

child off                          同时调试两个进程,gdb和子进程,主进程block在fork位置

3、进入gdb调试模式


4、查看系统默认的follow-fork-mode和detach-on-fork


5、设置follow-fork-mode和detach-on-fork


6、用list命令查看源代码(按enter翻页),分别在子进程和父进程相应位置下断点


7、打断点


8、查看正在调试的进程:

        显示gdb调试的所有inferior,gdb会为它们分配id。其中带有*得进程是正在调试的inferior。(gdb将每一个被调试程序的执行记录在一个名为inferior的结构中。一般情况下一个inferior对应一个进程,每个不同inferior有不同的地址空间。inferior有时候会在进程没有启动的时候就存在。)


9、切换调试的进程:inferior<infer number>


10、其他

(1)remove-inferior infno

删除一个infno号的inferior。如果inferior正在运行则不能删除,所以删除前需要先kill或者detach这个inferior。

(2)clone-inferior[-copies n] [infno]

复制n个编号是infno号的inferior。如果指不定n的话,就只复制一个inferior。如果不指定infno,则就复制正在调试的inferior。

(3)detach inferior

detach掉编号是infno的inferior。注意这个inferior还存在,可以再次用run命令执行它。

(4)kill inferior infno:

kill掉infno号inferior。注意这个inferior任然存在,可以再次用run等命令执行它。

(5)set schedule-multiple on|off

设为off:只有当前inferior会执行。

设为on:全部是执行状态inferior都会执行。

这个选项类似于多线程里的set。

(6)main info program-space

显示当前gdb一共管理多少地址空间

(7)set print inferior-events on|off

打开和关闭inferior状态的提示信息

         show print inferior-events

查看print inferior-events设置的状态

(8)set follow-exec-mode new|same

设置same:当发生exec的时候,在执行exec的inferior上控制子进程。

设置为new:新建一个inferior给执行的子进程。而父进程的inferior任然保留,当前保留的inferior的程序状态是没有执行。

三、gdb调试多线程

1、调试代码



上面代码中主进程创建了3个子进程,他们是thread1,thread2和thread3,所以也就有3的线程。

2、使用gdb对多线程进行调试

            gdb调试多线程的的常用命令:

(1)info threads 显示可以调试的所有线程

            gdb会为每个线程分配一个id(和tid不同),编号一般从1开始。后面的id是指它的id。

(2)thread id 切换当前调试的线程·为指定id的线程

(3)break FileName.cpp:LineNum thread all:

                所有线程都在文件FineName.cpp的第Linenum行有断点

(4)step:在step(单步)调试时,只有被调试的线程运行

(5)set non-stop on/off

                当调试一个线程时,其它线程是否运行。

           set pagination on/off

                 在使用backtrack时,在分页时是否停止

           set target-async on/off:

                  同步和异步。同步,gdb在输出提示符之前等待程序报告一些线程已经终止的信息。而异步的则直接返回

            show scheduler-locking

              查看当前锁定线程的模式

原创粉丝点击