关闭

GDB调试信号、多进程、多线程

标签: 多线程threadsignalcommandfile工作
483人阅读 评论(0) 收藏 举报
 

GDB的功能很强大,本文主要介绍用GDB来调试信号、多进程、多线程,具体如下:

(一)信号

GDB有能力在你调试程序的时候处理任何一种信号,你可以告诉GDB需要处理哪一种信号。你可以要求GDB收到你所指定的信号时,马上停住正在运行的程序,以供你进行调试。你可以用GDB的handle命令来完成这一功能。

    handle <signal> <keywords...>
        在GDB中定义一个信号处理。信号<signal>可以以SIG开头或不以SIG开头,可以用定义一个要处理信号的范围(如:SIGIO- SIGKILL,表示处理从SIGIO信号到SIGKILL的信号,其中包括SIGIO, SIGIOT,SIGKILL三个信号),也可以使用关键字 all来标明要处理所有的信号。一旦被调试的程序接收到信号,运行程序马上会被GDB停住,以供调试。其<keywords>可以是以下几种关键字的一个或多个。

        nostop
            当被调试的程序收到信号时,GDB不会停住程序的运行,但会打出消息告诉你收到这种信号。
        stop
            当被调试的程序收到信号时,GDB会停住你的程序。
        print
            当被调试的程序收到信号时,GDB会显示出一条信息。
        noprint
            当被调试的程序收到信号时,GDB不会告诉你收到信号的信息。
        pass
        noignore
            当被调试的程序收到信号时,GDB不处理信号。这表示,GDB会把这个信号交给被调试程序会处理。
        nopass
        ignore
            当被调试的程序收到信号时,GDB不会让被调试程序来处理这个信号。

    info signals
    info handle
    查看有哪些信号在被GDB检测中。

(二)线程

如果你程序是多线程的话,你可以定义你的断点是否在所有的线程上,或是在某个特定的线程。GDB很容易帮你完成这一工作。

    break <linespec> thread <threadno>
    break <linespec> thread <threadno> if ...
        linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID,注意,这个ID是GDB分配的,你可以通过“info threads”命令来查看正在运行程序中的线程信息。如果你不指定
thread <threadno>则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如:

        (gdb) break frik.c:13 thread 28 if bartab > lim

    当你的程序被GDB停住时,所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行时,所有的线程也会被恢复运行。那怕是主进程在被单步调试时。

线程有自己的寄存器,运行时堆栈或许还会有私有内存。  
gdb提供了以下供调试多线程的进程的功能:  
*   自动通告新线程。  
*   \ "thread   THREADNO\ ",一个用来在线程之间切换的命令。  
*   \ "info   threads\ ",一个用来查询现存线程的命令。  
*   \ "thread   apply   [THREADNO]   [ALL]   ARGS\ ",一个用来向线程提供命令的命令。  
*   线程有关的断点设置。  
注意:这些特性不是在所有gdb版本都能使用,归根结底要看操作系统是否支持。  
如果你的gdb不支持这些命令,会显示出错信息:  
(gdb)   info   threads  
(gdb)   thread   1  
Thread   ID   1   not   known.   Use   the   \ "info   threads\ "   command   to  
see   the   IDs   of   currently   known   threads.  
gdb的线程级调试功能允许你观察你程序运行中所有的线程,但无论什么时候  
gdb控制,总有一个“当前”线程。调试命令对“当前”进程起作用。  
一旦gdb发现了你程序中的一个新的线程,它会自动显示有关此线程的系统信  
息。比如:  
[New   process   35   thread   27]  
不过格式和操作系统有关。  
为了调试的目的,gdb自己设置线程号。  
`info   threads\ "  
显示进程中所有的线程的概要信息。gdb按顺序显示:  
1.线程号(gdb设置)  
2.目标系统的线程标识。  
3.此线程的当前堆栈。  
一前面打\ "*\ "的线程表示是当前线程。  
例如:  
(gdb)   info   threads  
3   process   35   thread   27   0x34e5   in   sigpause   ()  
2   process   35   thread   23   0x34e5   in   sigpause   ()  
*   1   process   35   thread   13   main   (argc=1,   argv=0x7ffffff8)  
at   threadtest.c:68  
`thread   THREADNO\ "  
把线程号为THREADNO的线程设为当前线程。命令行参数THREADNO是gdb内定的  
线程号。你可以用\ "info   threads\ "命令来查看gdb内设置的线程号。gdb显示该线程  
的系统定义的标识号和线程对应的堆栈。比如:  

(gdb)   thread   2  
[Switching   to   process   35   thread   23]  
0x34e5   in   sigpause   ()  
\ "Switching后的内容取决于你的操作系统对线程标识的定义。  

`thread   apply   [THREADNO]   [ALL]   ARGS\ "  
此命令让你对一个以上的线程发出相同的命令\ "ARGS\ ",[THREADNO]的含义同上。  
如果你要向你进程中的所有的线程发出命令使用[ALL]选项。  
无论gdb何时中断了你的程序(因为一个断点或是一个信号),它自动选择信号或  
断点发生的线程为当前线程。gdb将用一个格式为\ "[Switching   to   SYSTAG]\ "的消息  
来向你报告。  

 

(三)进程

1. 用的是attach子进程的方法
attach到正在运行的进程的功能,即attach <pid>命令。因此我们可以利用该命令attach到子进程然后进行调试。

一般的步骤是  1.首先要在要调试的子进程初始代码中,加入一段特殊代码,使子进程睡眠等待,然后运行待调试的程序
2.用ps -ef |grep 查看产生的子进程pid
3. 然后gdb启动,attach <pid>到进程后在该代码段后设上断点,就可以调试了

eg.

        pid = fork();
if (pid <0) {
printf("fork err\n");
exit(-1);
} else if (pid == 0) {
/* in child */
sleep(60); ------------------ (!)

int     value   = 10;

**********
} /**in parent****/

执行程序(比如说是 examp)
examp &   --- 让examp后台运行吧。(不后台运行也可以);

查找进程id:
ps -ef

运行gdb:
gdb
(gdb) attach xxxxx  --- xxxxx为利用ps命令获得的子进程 id
(gdb) stop --- 这点很重要,你需要先暂停那个子进程,然后设置一些断点和一些Watch
(gdb) break xx
Breakpoint 1 at 0x10808: file eg1.c, line 37.
(gdb) c
Continuing.

2. 使用follow-fork-mode 的方法调试多进程
最好使用GDB 6.6或以上版本

使用follow-fork-mode 的方法调试多进程时的一般步骤是:
1.启动gdb
2设置set follow-fork-mode [child/parent] 想调试child就使用child参数,如调试parent则使用parent
3启动程序文件 file ./hello ----------当然路径名自己要搞对哦
4.break num -----------如调试子进程则num是子进程代码的行数,
还有个小技巧就是break fork也就是在fork函数处设置断点,

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:500272次
    • 积分:5338
    • 等级:
    • 排名:第5039名
    • 原创:42篇
    • 转载:201篇
    • 译文:1篇
    • 评论:37条
    文章分类
    最新评论