利用GDB进行多线程调试

一、多线程调试

多线程调试重要就是下面几个命令:

info thread 查看当前进程的线程。 thread <ID> 切换调试的线程为指定ID的线程。 break file.c:100 thread all  在file.c文件第100行处为所有经过这里的线程设置断点。 set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。 off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。 二、调试宏

这个问题超多。在GDB下,我们无法print宏定义,因为宏是预编译的。但是我们还是有办法来调试宏,这个需要GCC的配合。

在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。

另外,你可以使用下述的GDB的宏调试命令 来查看相关的宏。

info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。 macro – 你可以查看宏展开的样子。

 

三、源文件

这个问题问的也是很多的,太多的朋友都说找不到源文件。在这里我想提醒大家做下面的检查:

编译程序员是否加上了-g参数以包含debug信息。 路径是否设置正确了。使用GDB的directory命令来设置源文件的目录。

下面给一个调试/bin/ls的示例(ubuntu下)


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20


$ apt-get sourcecoreutils

$ sudoapt-get installcoreutils-dbgsym

$ gdb /bin/ls

GNU gdb (GDB) 7.1-ubuntu

(gdb) list main

1192    ls.c: No such fileor directory.

inls.c

(gdb) directory ~/src/coreutils-7.4/src/

Source directories searched: /home/hchen/src/coreutils-7.4:$cdir:$cwd

(gdb) list main

1192        }

1193    }

1194

1195    int

1196    main (int argc, char **argv)

1197    {

1198      int i;

1199      struct pending *thispend;

1200      int n_files;

1201

四、条件断点

条件断点是语法是:break  [where] if [condition],这种断点真是非常管用。尤其是在一个循环或递归中,或是要监视某个变量。注意,这个设置是在GDB中的,只不过每经过那个断点时GDB会帮你检查一下条件是否满足。

五、命令行参数

有时候,我们需要调试的程序需要有命令行参数,很多朋友都不知道怎么设置调试的程序的命令行参数。其实,有两种方法:

gdb命令行的 –args 参数 gdb环境中 set args命令。 六、gdb的变量

有时候,在调试程序时,我们不单单只是查看运行时的变量,我们还可以直接设置程序中的变量,以模拟一些很难在测试中出现的情况,比较一些出错,或是switch的分支语句。使用set命令可以修改程序中的变量。

另外,你知道gdb中也可以有变量吗?就像shell一样,gdb中的变量以$开头,比如你想打印一个数组中的个个元素,你可以这样:


1

2

3

4

5


(gdb) set$i = 0

  

(gdb) p a[$i++]

  

...  #然后就一路回车下去了

当然,这里只是给一个示例,表示程序的变量和gdb的变量是可以交互的。

七、x命令

也许,你很喜欢用p命令。所以,当你不知道变量名的时候,你可能会手足无措,因为p命令总是需要一个变量名的。x命令是用来查看内存的,在gdb中 “help x” 你可以查看其帮助。

x/x 以十六进制输出 x/d 以十进制输出 x/c 以单字符输出 x/i  反汇编 – 通常,我们会使用 x/10i $ip-20 来查看当前的汇编($ip是指令寄存器)x/s 以字符串输出 八、command命令

有一些朋友问我如何自动化调试。这里向大家介绍command命令,简单的理解一下,其就是把一组gdb的命令打包,有点像字处理软件的“宏”。下面是一个示例:


1

2

3

4

5

6

7

8

9

10


(gdb) breakfunc

Breakpoint 1 at 0x3475678: filetest.c, line 12.

(gdb) command1

Type commands forwhen breakpoint 1 is hit, one per line.

End with a line saying just "end".

>print arg1

>print arg2

>print arg3

>end

(gdb)

当我们的断点到达时,自动执行command中的三个命令,把func的三个参数值打出来。

 

设置core环境
uname -a 查看机器参数
ulimit -a 查看默认参数
ulimit -c 1024  设置core文件大小为1024
ulimit -c unlimit 设置core文件大小为无限

  多线程如果dump,多为段错误,一般都涉及内存非法读写。可以这样处理,使用下面的命令打开系统开关,让其可以在死掉的时候生成
core文件。   
ulimit -c unlimited

线程调试命令
(gdb)info threads 
显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 
前面有*的是当前调试的线程。

(gdb)thread ID 
切换当前调试的线程为指定ID的线程。

(gdb)thread apply ID1 ID2 command 
让一个或者多个线程执行GDB命令command。
(gdb)thread apply all command 
让所有被调试线程执行GDB命令command。

(gdb)set scheduler-locking off|on|step 
估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。 
on 只有当前被调试程序会执行。 
step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

//显示线程堆栈信息
(gdb) bt 
察看所有的调用栈

(gdb) f 3
调用框层次

(gdb) i locals  
显示所有当前调用栈的所有变量

时间: 2024-11-01 20:00:54

利用GDB进行多线程调试的相关文章

pwntools如何用利用Pwnlib.gdb进行远程调试?

问题描述 pwntools如何用利用Pwnlib.gdb进行远程调试? 1C 这几天在学习pwn,在调试一些交互程序的时候,需要输入信息,可是无法在调试过程中输入内存地址无法观察输入字符串是否覆盖到了栈地址(比如在测试栈溢出的到时候利用python可以python -c ""print 'A'*123 +'x12x12x12.......'"")因此想进行远程调试,从网上找到pwntools,其中pwnlib.gdb的gdb.debug可以用来远程调试,就是用gdb

《深入剖析Nginx》——第2章  跟踪与调试2.1 利用gdb调试

第2章 跟踪与调试 跟踪与调试,不仅是我们解决程序Bug的有力途径,也是帮助我们理解现有代码的有效方法.通过跟踪程序执行的过程,我们可以清楚地了解程序的内部逻辑,对于不明就里的实现细节,调试查看程序内部变量也能更好地帮助我们做出正确的理解.本章将介绍一些跟踪与调试程序的方法,除了最基本的 gdb 调试,我还将结合个人经验,介绍一些相对高级的应用技巧. 2.1 利用gdb调试 gdb是Linux下调试程序的常用工具,任何Linux开发工程师初学程序调试时第一个接触到的工具应该就是gdb.关于gdb

《深入剖析Nginx》一2.1 利用gdb调试

2.1 利用gdb调试 深入剖析Nginx gdb是Linux下调试程序的常用工具,任何Linux开发工程师初学程序调试时第一个接触到的工具应该就是gdb.关于gdb本身的详细用法,我们不多详述,读者可以参考gdb官网手册1,而在这里,我们将重点介绍一些与Nginx相关的注意点与调试技巧. 2.1.1 绑定Nginx到gdb 利用gdb调式Nginx,首先得在生成Nginx程序时把-g编译选项打开.当然,这并不是说不打开-g选项就无法用gdb调试它,只是会因为缺少相应的符号信息导致调试不便,而此

Java多线程调试

摘要 最有价值的调试工具是以线程为中心的.大部分 Java 错误都与线程交互有关.多线程调试让开发人员可以查看应用程序中运行的每个线程中的执行情况. SUN Laura Bennett 多线程调试基础 最有价值的调试工具是以线程为中心的.大部分 Java 错误都与线程交互有关.多线程调试让开发人员可以查看应用程序中运行的每个线程中的执行情况. 由于执行顺序的易变性,查找多线程应用程序中的错误比非线程化情况要困难得多.如果可以按相同的可预料顺序执行指令,那么调试这些应用程序就可以变得非常简单.当然

解析VS2010利用VS.PHP插件调试PHP的方法

以下是对VS2010利用VS.PHP插件调试PHP的方法进行了详细的分析介绍,需要的朋友可以过来参考下   1.安装VS.PHP插件 2.新建PHP工程:如下图,选择PHP 4 webproject创建PHP工程. 3.新建PHP页 4.添加PHP代码 5.设置起始页 6.设置断点 7.启动调试 启动新实例后,将会在任务栏右边(图标通知栏)显示如下图标 8.进入断点 9.继续调试:之后的调试与VS2010的调试方法相同.

MySQL · 特性分析 · 利用gdb跟踪MDL加锁过程

MDL(Meta Data LocK)的作用 在MySQL5.1及之前的版本中,如果有未提交的事务trx,当执行DROP/RENAME/ALTER TABLE RENAME操作时,不会被其他事务阻塞住.这会导致如下问题(MySQL bug#989) master: 未提交的事务,但SQL已经完成(binlog也准备好了),表schema发生更改,在commit的时候不会被察觉到. slave: 在binlog里是以事务提交顺序记录的,DDL隐式提交,因此在备库先执行DDL,后执行事务trx,由于

工程属性页,关于多线程调试MDd,MTD等等问题

问题描述 一个VC转成VC.net库文件,给C#工程调用现在问题有点奇怪,本来在工程属性--C/C++---代码生成页面下.运行库原先是设置的多线程调试(/MTd),编译工程,运行没有错误.现在设置,多线程调试(/MDd),编译工程,运行有错误.还原设置,多宣传调试(/MTd),编译工程,运行有错误.不明白原因.错误:托管调试助手"PInvokeStackImbalance"在......exe中检测到故障.其他信息:对PInvoke函数"Func"的调用导致堆栈不

多线程的那点儿事(之多线程调试)

 软件调试是我们软件开发过程中的重要一课.在前面,我们也讨论过程序调试,比如说这里.今天,我们还可以就软件调试多讲一些内容.比如说条件断点,数据断点,多线程断点等等. [cpp] view plaincopy #include <stdio.h>   int value = 0;      void test()   {       int total;       int index;          total = 0;       for(index = 0; index < 1

利用C#线程窗口调试多线程程序

  从网上的资料判断,调试多线程程序似乎就一下3种方法. 1.在日志的某个地方写日志文件. 优点:不会干扰程序的执行,特别是对网络的多线程通信. 缺点:每次都需要打开日志文件以查看进程运行的信息. 2.利用断点进行调试. 优点:直观,可以直接看到运行过程的值 缺点:在多个线程设置断点,可能让程序跳来跳去,还需要额外地分出一部分精力用来理清程序的逻辑 3.利用弹出窗口来查看进程调试的信息. 优点;直观 缺点;在调试网路通信的时候,使得通信的过程产生延时,导致通信失败. 4.利用vs2010自带的线