`
simohayha
  • 浏览: 1386440 次
  • 性别: Icon_minigender_1
  • 来自: 火星
社区版块
存档分类
最新评论

gdb学习笔记(一)

阅读更多
这里只是一个摘要。具体的细节还需要去看manual。



1 info 用来描述你的程序的状态,比如info b就是显示出当前的程序的所有断点.

2 set 用来设置一些环境变量的值,比如set prompt $.

3 show用来描述gdb自己的状态.


编译要用-g选项.


然后用gdb +程序名,或者直接gdb后,用file + 文件名加载程序.

1 run/r 运行程序.

2 set args 设置程序的参数.

3 path directory 加一个目录到环境变量path

4 set directory 设置gdb的工作目录

5 pwd 当前的工作目录

6 attch process-id 调试 运行的进程

  dettach  当调试进程完毕,release 掉gdb的控制.


调试多线程.

1 thread threadno 选择当前的线程.

2 info thread 查看当前程序的线程.

debug多进程:

默认情况下,当fork一个子进程之后,gdb会继续debug父进程,而子进程会运行下去.不过我们能够改变这个.

set follow-fork-mode mode 这里mode可以为parent或者child. parent是默认值,而child的话就是gdb继续debug子进程,而父进程会运行下去.

如果你想要同时debug父子进程,也可以设置:

set detach-on-fork mode 默认是on,也就是只能debug一个进程,如果改为off则可以同时debug父子进程.

保存一个书签稍后返回.

checkpoint 保存当前的程序的状态.

restart checkpoint-id 返回到checkpoint-id那个点.这个值可以用info checkpoint来查看

breakpoint,watchpoint以及catchpoint

breakpoint 就是断点.

watchpoint 就是用来检测变量的改变,他可以看做是特殊的断点,也就是当变量改变时停止程序.

catchpoint 是另外一种特殊的断点,用来监测某一事件的发生,有点类似其它语言中的异常.

1 设置Breakpoint

break location 设置断点.location可以为行号,函数名或者指令地址.

break 设置断点,不过这个断点为当前栈帧的下一条指令.

break location if condition 当condition为真时,程序到达这个断点才起作用.

tbreaks args, 一次性的断点.

rbreaks regex 设置断点在所有与regex匹配的函数.这个正则表达式的语义与grep的相同.

2 设置watchpoint

watch expr[thread threadno] 设置检测变量expr,后面可以跟着改变这个变量的线程.如果跟着线程号,则说明只有当这个线程改变变量时,程序才会stop.

rwatch expr[thread threadno] 上面是监测变量改变,而这个命令是监测程序读取变量.

awatch expr[thread threadno] 当expr要么被读,要么被写时,程序直接break.

3 设置catchpoint

catch event 当event发生的时候程序停止.

event可以是下面的几种类型: throw ,catch,exception,exception unhandled,assert,exec,fork,vfork.

tcatch event 一次性的监测事件.


删除断点

clear 删除在当前的栈帧的将要被执行的下一条指令断点.

clear location 删除location位置的断点.其实更有用的是下面几个命令:

clear function,clear filename:function ,clear linenum,clear filename:linenum.

delete [breakpoints][range...]  其实也就是删除多个断点,如果没有range,咋就是删除全部断点.

关闭断点

一个断点(包括 watchpoint和catchpoint)可以有下面四种状态.

打开,关闭,enabled once,enabled for deletion

disable [breakpoints][range..]  关闭指定的断点或者全部断点(如果没有range)

enable [breakpoints][range..] 打开指定的断点或者全部断点(如果没有range)

enable [breakpoints] once range  临时打开指定的断点(也就是说是一次性的,.

enable [breakpoints] delete range 临时打开指定的断点并只工作一次,也就是一次之后这个断点将会被删除.


break condition

contidition bnum expression  当expression为真的时候,程序到达这个断点才会停止.

contidition bnum 从断点bnum删除掉一个condition.

ignore bnum count 设置一个断点bnum的忽略次数为count.也就是只有count次数后,这个断点才会起作用.

断点命令列表

这个主要是用来当到达这个断点,程序停止后,你想要执行一连串的命令.格式为:

command [bnum]
... command-list ..
end


指定一堆命令给断点bnum.如果想删除命令的话就把command-list置为空就行了.
如果没有bnum,则这个command指的是最后设置的一个断点.

这里有个例子:

break 403
commands
///不输出任何东西
silent
///改变x的值
set x = y + 4
///然后continue
cont
end


接下来来看continue和step

continue表示让程序继续执行,直到下一个断点或者执行完毕。

step表示让程序执行一行代码或者说一条机器指令(依赖于你选择的命令)。

下面来看命令:

continue [ignore-count]
c [ignore-count]
fg [ignore-count]


这几个命令都是resume一个程序,然后参数ignore-count表示忽略当前这个断点的次数。

step [count]

继续运行程序直到抵达一个新的代码行(它会跟入函数).这里要记住step只会停止在source line的第一条指令。

如果加上count参数则表示它会step count次。如果遇到断点则会停止。

next [count]
和step很类似,区别就是不会跟进函数。

set step-mode
set step-mode on
set step-mode off

on就可以使step停止在没有debug信息的函数的第一条指令上。off则是直接执行完这个函数。


这里要注意上面的命令都只是跳一行代码。而不是一条指令。

util  继续运行直到source line通过了当前的行。这个命令主要是针对循环语句中的step。比如你在循环结尾设置util,则只有当循环退出时才会在这个断点停止。而不是每次都停止。

util location 继续运行直到指定的location,或者当前的栈帧返回。

advance location 继续运行直到给定的location,这个相比与上面的命令,它就象全局的。

stepi [arg]

执行一条机器指令。 arg表示次数。

nexti [arg]

和next类似只不过执行的是一条机器指令。


下来来看信号。

gdb可以监测在你的程序中的任何信号。

来看命令。

handle signal [keywords...]

这个命令用来改变信号signal(名字或者数字)在gdb中的行为。

其中关键就是keywords.在这里keywords可以为下面几种类型:

1 nostop gdb接收到信号不会停止程序,而只是打印出一段message

2 stop 和上面类似只不过会停止程序。

3 print 当信号发生必须打印一条消息通知。

4 noprint 信号发生,gdb将不会打印任何东西。

5 pass和noignore 这两个是同义的。表示信号对你的程序是可见的。

6 nopass和ignore 这两个也是同义的。和上面相反。。

在gdb中,当你的程序由于一个信号而停止后,直到你继续执行,否则信号对你的程序是不可见得。也就是说当gdb捕捉到信号,我们可以用nopass或者ignore来使信号对我们的程序为不可见。

最后来看下多线程程序的调试。

首先来看多线程调试的几种模式。

1 all-stop模式。

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

在一些os中我们可以通过lock线程调度器,从而达到只有一个线程在运行。

set scheduler-locking mode

设置模式,如果mode是off,则表示没有lock,则任何线程在任何时候都有可能在运行。当mode为on的时候,锁定其他的线程,也就是只有当前线程在执行。也就是你单步的时候其他线程是不会运行的。这个对我们只关注本线程比较重要。

默认情况下,当你键入step或者next命令时,gdb只允许当前进程的线程运行。我们可以通过命令来修改这个默认值。

set schedule-multiple mode

当mode为on则所有进程的所有线程都匀许运行。否则只有当前的进程的线程能够resume。

2 none-stop模式。

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

我们要打开这个模式需要这样操作:

# Enable the async interface.
set target-async 1
# If using the CLI, pagination breaks non-stop.
set pagination off
# Finally, turn it on!
set non-stop on


这里要注意打开这个模式必须得在你attach或运行这个程序或者进程之前才能进行。

Background Execution

gdb执行命令有两种类型:前台的(同步)和后台(异步)的。

区别很简单,前台的话,gdb在输出提示符之前会等待程序report一些线程已经终止的信息。而异步的则是直接返回。

我们需要显式打开异步模式。

set target-async on

下面就是支持异步的命令:

run 
attach 
step 
stepi 
next 
nexti 
continue 
finish 
until


通过上面我们可以看到异步模式主要用在none-stop模式中。


如果你想停止后台运行的程序,那么使用interrupt

在all-stop模式中interrupt将会停止所有的线程。而在none-stop中只会停止当前线程。interrupt -a此时就能停止所有线程。’

当你有多个线程,你此时只想给某个线程设置断点,这个时候可以用这个命令:

break linespec thread threadno
break linespec thread threadno if ...

linespec为源码行号,threadno为线程id。

最后来看下多线程调试中可能会遇到的一个问题:

如果一个线程在一个断点,或者由于其他什么原因停止,此时另外的线程阻塞在一个系统调用。这个时候这个系统调用就有可能会过早的返回。因此我们在调用系统调用,最好都要检测它的返回值。

举个例子:

sleep (10);

这个我们应该改成这样:

int unslept = 10;
while (unslept > 0)
unslept = sleep (unslept);






1
0
分享到:
评论

相关推荐

    gdb调试器命令学习总结笔记

    gdb调试器命令学习总结笔记 gdb调试器命令学习总结笔记 gdb调试器命令学习总结笔记

    非常宝贵的LINUX学习笔记

    【linux学习笔记-1】使用GDB调试简单的用户程序 【linux学习笔记-2】父子进程共享文件描述符 【linux学习笔记-3】文件操作(stat,chmod,umask) 【linux学习笔记-4】进程扇和进程链 【linux学习笔记-5】编写自己的ls...

    Linux学习笔记Linux学习资料Linux教程

    【linux学习笔记-1】使用GDB调试简单的用户程序.doc 【linux学习笔记-2】父子进程共享文件描述符.doc 【linux学习笔记-3】文件操作(stat,chmod,umask).doc 【linux学习笔记-4】进程扇和进程链.doc 【linux学习笔记-...

    Go学习笔记(第四版).zip

    Go 学习笔记, 第 4 版 4.4 Struct 47 第 5 章 ⽅法 53 5.1 ⽅法定义 53 5.2 匿名字段 54 5.3 ⽅法集 56 5.4 表达式 56 第 6 章 接⼝ 60 6.1 接⼝定义 60 6.2 执⾏机制 62 6.3 接⼝转换 63 6.4 接⼝技巧 65 第 7 章 ...

    Go 语言编程 + Go 学习笔记

    Go 语言编程 + Go 学习笔记, 第 部分 语 第 1 章 类型 1.1 变量 1.2 常量 1.3 基本类型 1.4 引 类型 1.5 类型转换 1.6 字符串 1.7 指针 1.8 定义类型 第 2 章 表达式 2.1 保留字 2.2 运算符 2.3 初始化 2.4 控制流 ...

    Oracle11G数据库学习笔记

    最近朋友传给的Oracle11G学习笔记,将近200页,都是很实用的知识。

    go学习笔记

    Go 学习笔记, 第 4 版 4 4.4 Struct 47 第 5 章 ⽅方法 53 5.1 ⽅方法定义 53 5.2 匿名字段 54 5.3 ⽅方法集 56 5.4 表达式 56 第 6 章 接⼝口 60 6.1 接⼝口定义 60 6.2 执⾏行机制 62 6.3 接⼝口转换 63 6.4 接⼝...

    Qt基础学习笔记

    Qt [1] 是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象...

    ARM-LINUX学习笔记(四)

    详细的分析了,arm-linux-gdb+insight调试环境,可以实现可视化仿真调试

    C语言学习笔记快速入门

    C语言自学笔记,快速入门,C语言组成,数据类型,运算符与表达式,分支结构,循环结构,数组,函数,指针等知识,且包含例题和答案解析。

    linux学习笔记

    这位自由软件的“顶级神甫”为自己的梦想付出了大半生的努力,他不但自己创作了许多自由软件,如:GCC、和GDB,在他的倡导下,目前人们熟悉的一些软件如BIND、Perl、Apache、TCP/IP等都成了自由软件的经典之作。...

    linux c语言 笔记

    linux c的笔记资料,和大家一起分享 gcc介绍 gdb工具 基本类型、转义符、printf、scanf、操作符 字符处理函数 运算符优先表 文件结构体struct file 宏定义 Linux常用C函数open和read以及write的使用说明 还有一些...

    国嵌笔记。全集全集

    本人学习的国嵌笔记。操作详细! 第一季 精通嵌入式 4 一. 安装tftp服务器 4 二. Samba服务器安装 4 三. NFS服务器 5 四. 安装vsftpd FTP服务器 5 第2季-裸奔吧-ARM 6 一. 安装交叉编译器 6 二. 安装驱动 6 三...

    linux网络编程学习 .doc

    本文档为本人在学习linux编程的学习笔记,记载了socket基础知识,makefile和GDB调试,收获不少。

    LDD-LinuxDeviceDrivers:Linux内核与设备驱动程序学习笔记

    LDD-LinuxDeviceDrivers#1书籍-一些书中的原始码和范例目录书籍#2 study--本人的linux学习以及驱动代码目录书籍学习Linux内核的设计与实现,包括文档和示例代码,文档与同步更新自己实现的一些linux内核的驱动代码...

    emacs编辑工具学习资料

    【Linux】Emacs_教程中文版、elisp入门、emacs_vim快速入门、emacs_学习笔记_-_初级教程、Emacs教程初步、Emacs生活、Emacs学习笔记

    Linux与嵌入式(个人总结笔记,可自行删改)

    为课堂笔记和其他途径搜集的内容总结出来的。主要内容如下: 第一章:嵌入式概述(嵌入式的系统概念,开发流程,系统结构,开发模式等) 第二章:嵌入式开发环境 第三章:Linux环境下的C编程(GCC编译过程和GCC编译...

    Cyber-Security-Knowledge:我尝试每2天学习一次新事物的项目,每天学习1天,第二天应用知识,这是一个跟踪知识的地方

    这个挑战主要是关于学习的,所以这里的笔记并不是全部都是由知识引起的,我会使用很多资源并尝试将它们链接起来,如果没有提及任何资源,请随时给我发消息,我会添加它们 第1天:Linux堆栈粉碎/缓冲区溢出的基本知识...

Global site tag (gtag.js) - Google Analytics