gdb调试多进程多线程程序

一、调试的指令

  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 condition 在满足条件的那一行停住

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

  4.单步命令:

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

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

    finish     运行函数,知道当前函数完成返回,并打印出函数返回时的堆栈地址、返回值和参数信息

    until      退出循环体

  5.continue命令:

    当程序被停住后,可以使用continue(c)命令,恢复程序的运行直到程序结束,或到达下一个断点

  6.print(p)命令:

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

    • x 按十六进制格式显示变量
    • d 按十进制格式显示变量
    • u 按十六进制格式显示无符号整型退出
    • o 按八进制格式显示变量
    • t 按二进制格式显示变量t 按二进制格式显示变量
    • a 按十六进制格式显示变量
    • c 按字符格式显示变量
    • f 按浮点数格式显示变量

  7.watch命令:

    watch命令一般用来观察某个表达式(变量也是一种表达式)的值是否有变化,如果有变化,马上停住程序

    设置观察点的方法:

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

    rwatch    expr  当表达式被读是,停住程序

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

  8.exammine命令:

    查看内存地址的值。语法是:x/u addr

  9.jump命令

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

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

jump address      跳到代码行的地址

  10.signal命令

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

  11.set命令

set args       设置命令行参数

set env environmentVarname=value 设置环境变量。如:set env USER=benben

  12.call命令

     call function     强制调用某函数

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

  13.disassemble命令

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

二、多进程调试

1.单独调试子进程

我们可以先运行程序,然后再另一终端使用ps -ef | grep "main"(main此处是可执行文件名)搜索到子进程pid,然后启动gdb,在将其附加(attach)到gdb调试器上

attach child-pid        使用该命令后,直接run即可,和调试普通程序就没区别了

dettach                     脱离进程

2.使用调试器选项follow-fork-mode

我们知道如果不设置任何选项,gdb默认调试父进程。调试器选项用法如下:

set follow-fork-mode mode     其中mode的可选值是parent和child,分别表示调试父进程和子进程。

info inferiors                            查询正在调试的进程

inferior processnum                切换进程

默认设置下,在调试多进程程序时GDB只会调试主进程。但是GDB(>V7.0)支持多进程的分别以及同时调试,换句话说,GDB可以同时调试多个程序。只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可。我们还可以使用catch fork指令,如果fork异常,会停止程序。

        follow-fork-mode  detach-on-fork   说明
        parent                     on               只调试主进程(GDB默认)
        child                        on               只调试子进程
        parent                     off               同时调试两个进程,gdb跟主进程,子进程block在fork位置
        child                        off               同时调试两个进程,gdb跟子进程,主进程block在fork位置

设置方法:set follow-fork-mode [parent|child]   set detach-on-fork [on|off]

三:多线程调试

gdb调试一般有两种模式:all-stop模式和no-stop模式(gdb7.0之前不支持no-stop模式)。

1.all-stop模式

在这种模式下,当你的程序在gdb由于任何原因而停止,所有的线程都会停止,而不仅仅是当前的线程。一般来说,gdb不能单步所有的线程。因为线程调度是gdb无法控制的。无论什么时候当gdb停止你的程序,它都会自动切换到触发断点的那个线程。

2.no-stop模式(网络编程常用)

顾名思义,启动不关模式。当程序在gdb中停止,只有当前的线程会被停止,而其他线程将会继续运行。这时候step,next这些命令就只对当前线程起作用。

gdb支持的命里有两种类型:前台的(同步的)和后台(异步 )的。区别很简单,同步的在输出提示符之前会等待程序report一些线程已经终止的信息,异步则是直接返回。所以我们需要set target-async 1。set pagination off不要出现 Type <return> to continue 的提示信息 。最后一步是打开。

下面是常用命令:

info threads                                       显示所有线程

thread id                                           切换到指定线程

break filename:linenum thread all     在所有线程相应行设置断点,注意如果主线程不会执行到该行,并且启动all-stop模式,主线程执行n或s会切换过去

set scheduler-locking off|on\step       默认off,执行s或c其它线程也同步执行。on,只有当前相称执行。step,只有当前线程执行

show scheduler-locking                    显示当前模式

thread apply all command                每个线程执行同意命令,如bt。或者thread apply 1 3 bt,即线程1,3执行bt。

主要是我们要用能用的上的,比如no-stop模式,一般多线程调试就很有用的。

时间: 2024-10-12 10:59:26

gdb调试多进程多线程程序的相关文章

gdb 调试openmp多线程程序 示例介绍

 首先一个简单程序源代码: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <omp.h> 4 int main(int argc, char * argv[]){ 5 int i, k,m,n; 6 printf("i=%d,threads_num=%d\n",i, omp_get_num_threads()); 7 printf("i=%d,thread_id=%d\n&quo

gdb调试多进程和多线程命令

gdb调试多进程和多线程命令 来源:http://blog.csdn.net/pbymw8iwm/article/details/7876797 1. 默认设置下,在调试多进程程序时GDB只会调试主进程.但是GDB(>V7.0)支持多进程的分别以及同时调试,换句话说,GDB可以同时调试多个程序.只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可. follow-fork-mode  detach-on-fork   说明 pare

使用 GDB 调试多进程程序

GDB 是 linux 系统上常用的调试工具,本文介绍了使用 GDB 调试多进程程序的几种方法,并对各种方法进行比较. 3 评论 田 强 ([email protected]), 软件工程师, IBM中国软件开发中心 2007 年 7 月 30 日 内容 在 IBM Bluemix 云平台上开发并部署您的下一个应用. 开始您的试用 GDB 是 linux 系统上常用的 c/c++ 调试工具,功能十分强大.对于较为复杂的系统,比如多进程系统,如何使用 GDB 调试呢?考虑下面这个三进程系统: 进程

Eclipse+CDT+GDB调试android NDK程序(转)

Eclipse+CDT+gdb调试android ndk程序 先介绍一下开发环境,在这个环境下,up主保证是没有问题的. ubuntu 11.10 eclipse 3.7(indego) for java jdk 6 android sdk 2.2 andrid ndk r7 当然,在windows环境下通过cygwin等工具也是可以实现gdb调试的,我也确实实现过.但是性能实在太低,卡的根本没法用.Linux下直接用gdb调试本地方法是很流畅的. 再确定安装并配置好开发环境之后,就可以开始了.

用GDB调试多进程程序

在子进程中sleep,然后attach上去. gdb --pid=123456 ps出子进程的id,gdb attach 进程号. http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html 实际上,GDB 没有对多进程程序调试提供直接支持.例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去.如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号并终止.那么

GDB调试多进程程序

[gdb manaul]https://sourceware.org/gdb/current/onlinedocs/gdb/Forks.html#Forks [参考]http://www.cnblogs.com/zhenjing/archive/2011/06/01/gdb_fork.html [参考]http://blog.chinaunix.net/uid-23062171-id-4107159.html gdb没有对fork创建的进程调试做特别的支持.如果用gdb调试父进程,父进程创建子进

使用GDB调试多进程

如果一个进程fork了多个进程,这时使用GBD工具对程序进行调试会如何呢? 实际上,GDB 没有对多进程程序调试提供直接支持.例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去. 如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号,如果没有对此信号进行捕捉处理,就会按默认的处理方式处理--终止进程. 那么该如何调试子进程呢?有3种方法: 1.follow-fork-mode 在2.5.60版Linux内核及以后,GDB对使

gdb调试带参数程序

一般来说GDB主要调试的是C/C++的程序.要调试C/C++的程序,首先在编译时,我们必须要 把调试信息加到可执行文件中.使用编译 器(cc/gcc/g++)的 -g 参数可以做到这一点.如: > cc -g hello.c -o hello > g++ -g hello.cpp -o hello 如果没有-g,你将看不见程序的函数名.变量名,所代替的全是 运行时的内存地址.当你用 -g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他. 启动 GDB的方法有以下几种

gdb调试带参数程序(转:笑笑小白,cnblog http://www.cnblogs.com/rosesmall/archive/2012/04/10/2440514.html)

一般来说GDB主要调试的是C/C++的程序.要调试C/C++的程序,首先在编译时,我们必须要 把调试信息加到可执行文件中.使用编译 器(cc/gcc/g++)的 -g 参数可以做到这一点.如: > cc -g hello.c -o hello > g++ -g hello.cpp -o hello 如果没有-g,你将看不见程序的函数名.变量名,所代替的全是 运行时的内存地址.当你用 -g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他. 启动 GDB的方法有以下几种