gdb学习笔记

设置断点

b main; 在main()入口处

b 148; 在第148行

查看断点

info b

运行程序

r

单条语句执行

n

继续运行程序

c

打印变量i的值

p i

查看函数堆栈

bt

退出函数

finish

help命令只是例出gdb的命令种类,如果要看种类中的命令,可以使用help <class> 命令,如:help breakpoints,查看设置断点的所有命令。也可以直接help <command>来查看命令的帮助。

TAB可补全函数名,命令名

在gdb中,我们可以有以下几种暂停方式:断点(BreakPoint)、观察点(WatchPoint)、捕捉点(CatchPoint)、信号(Signals)、线程停止(Thread Stops)。如果要恢复程序运行,可以使用c或是continue命令。

一、设置断点(BreakPoint)
    
    我们用break命令来设置断点。正面有几点设置断点的方法:
    
    break <function> 
        在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。

break <linenum>
        在指定行号停住。

break +offset 
    break -offset 
        在当前行号的前面或后面的offset行停住。offiset为自然数。

break filename:linenum 
        在源文件filename的linenum行处停住。

break filename:function 
        在源文件filename的function函数的入口处停住。

break *address
        在程序运行的内存地址处停住。

break 
        break命令没有参数时,表示在下一条指令处停住。

break ... if <condition>
        ...可以是上述的参数,condition表示条件,在条件成立时停住。比如在循环境体中,可以设置break if i=100,表示当i为100时停住程序。

查看断点时,可使用info命令,如下所示:(注:n表示断点号)
    info breakpoints [n] 
    info break [n]

二、设置观察点(WatchPoint)
    
    观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:
    
    watch <expr>
        为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。
        
    rwatch <expr>
        当表达式(变量)expr被读时,停住程序。
        
    awatch <expr>
        当表达式(变量)的值被读或被写时,停住程序。
    
    info watchpoints
        列出当前所设置了的所有观察点。

三、设置捕捉点(CatchPoint)

你可设置捕捉点来补捉程序运行时的一些事件。如:载入共享库(动态链接库)或是C++的异常。设置捕捉点的格式为:
    
    catch <event>
        当event发生时,停住程序。event可以是下面的内容:
        1、throw 一个C++抛出的异常。(throw为关键字)
        2、catch 一个C++捕捉到的异常。(catch为关键字)
        3、exec 调用系统调用exec时。(exec为关键字,目前此功能只在HP-UX下有用)
        4、fork 调用系统调用fork时。(fork为关键字,目前此功能只在HP-UX下有用)
        5、vfork 调用系统调用vfork时。(vfork为关键字,目前此功能只在HP-UX下有用)
        6、load 或 load <libname> 载入共享库(动态链接库)时。(load为关键字,目前此功能只在HP-UX下有用)
        7、unload 或 unload <libname> 卸载共享库(动态链接库)时。(unload为关键字,目前此功能只在HP-UX下有用)

tcatch <event> 
        只设置一次捕捉点,当程序停住以后,应点被自动删除。

四、维护停止点

上面说了如何设置程序的停止点,GDB中的停止点也就是上述的三类。在GDB中,如果你觉得已定义好的停止点没有用了,你可以使用delete、clear、disable、enable这几个命令来进行维护。

clear
        清除所有的已定义的停止点。

clear <function>
    clear <filename:function>
        清除所有设置在函数上的停止点。

clear <linenum>
    clear <filename:linenum>
        清除所有设置在指定行上的停止点。

delete [breakpoints] [range...]
        删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。

比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。

disable [breakpoints] [range...]
        disable所指定的停止点,breakpoints为停止点号。如果什么都不指定,表示disable所有的停止点。简写命令是dis.

enable [breakpoints] [range...]
        enable所指定的停止点,breakpoints为停止点号。

enable [breakpoints] once range...
        enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动disable。

enable [breakpoints] delete range...
        enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动删除。

查看栈信息
—————

当程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入“栈”(Stack)中。你可以用GDB命令来查看当前的栈中的信息。

下面是一些查看函数调用栈信息的GDB命令:

backtrace 
    bt 
        打印当前的函数调用栈的所有信息。如:
        
        (gdb) bt
        #0  func (n=250) at tst.c:6
        #1  0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30
        #2  0x400409ed in __libc_start_main () from /lib/libc.so.6
        
        从上可以看出函数的调用栈信息:__libc_start_main --> main() --> func()

一、显示源代码

GDB 可以打印出所调试程序的源代码,当然,在程序编译时一定要加上-g的参数,把源程序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后,GDB会报告程序停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。还是来看一看查看源代码的GDB命令吧。
    
    list <linenum>
        显示程序第linenum行的周围的源程序。
    
    list <function> 
        显示函数名为function的函数的源程序。
        
    list 
        显示当前行后面的源程序。
    
    list - 
        显示当前行前面的源程序。

五、强制调用函数

call <expr>
    表达式中可以一是函数,以此达到强制调用函数的目的。并显示函数的返回值,如果函数返回值是void,那么就不显示。
    
    另一个相似的命令也可以完成这一功能——print,print后面可以跟表达式,所以也可以用他来调用函数,print和call的不同是,如果函数返回void,call则不显示,print则显示函数返回值,并把该值存入历史数据中。

一、修改变量值

修改被调试程序运行时的变量值,在GDB中很容易实现,使用GDB的print命令即可完成。如:
    
        (gdb) print x=4
    
    x=4这个表达式是C/C++的语法,意为把变量x的值修改为4,如果你当前调试的语言是Pascal,那么你可以使用Pascal的语法:x:=4。

时间: 2024-10-25 12:20:56

gdb学习笔记的相关文章

[Debug]GDB学习笔记(一)

GDB学习 点击打开链接 比较详细的gdb命令 gcc编译的程序要带 -g 参数,要想运行准备调试的程序,可使用run(r)命令,在它后面可以跟随发给该程序的任何参数 其它相关备忘如何在gdb下调用shell命令:答:比如要查看当前目录,只要输入 shell pwd就好了 单步调试的一些相关命令答:step <count>单步跟踪,如果有函数调用,他会进入该函数(进入函数的前提是,此函数被编译有debug信息).next <count>同样单步跟踪,如果有函数调用,他不会进入该函数

Gdb学习笔记1

其实,从很早就开始接触gdb程序,gdb调试程序伴我成长,现在对其用法记录以下: 当程序的运行结果和预期结果不一致,或者程序出现运行错误时,gdb就可以派上大用处了.调试的基本过程是: -> 根据情况,分析现象 -> 根据直觉,假设原因 -> 根据经验,修改验证 -> | | <-   根据经验,修改验证 <-  根据直觉,假设原因 <- 根据情况,分析现象 <- 直到程序的结果和预期完全一致为止,就可以结束苦逼的程序调试了.调试器(如GDB)的目的是允许你

gcc gdb makefile学习笔记

一.gcc (GNU C compiler )1.预处理  gcc -E aaa.c  -o aaa.i   →  .i(c代码)    ↓ 2. 编译   gcc -S aaa.i  -o aaa.s   →   .s(汇编代码)    ↓3. 汇编   gcc -c  aaa.s  -o aaa.o  →   .o(目标代码-二进制)    ↓4. 链接   gcc aaa.o    -o aaa    →   aaa(可执行文件) 优化编译链接   gcc -O(O2/O3) aaa.o

《软件调试的艺术》学习笔记——GDB使用技巧摘要

<软件调试的艺术>学习笔记——GDB使用技巧摘要 <软件调试的艺术>,因为名是The Art of Debugging with GDB, DDD, and Eclipse. 作者是美国的Norman Matloff和Peter Jay Salzman,中文版由张云翻译.是人邮出版社图灵程序设计丛书初版.这里称为"艺术",个人觉得有点过了,但是其中关于gdb以及在gdb基础之上集成的DDD和Eclipse调试技巧的整理确实是做的很好,对于Linux/开源社区下的

Android NDK学习笔记(一) 为什么要用NDK?

NDK是什么 NDK是Native Development Kit的简称,即本地开发工具包.通过NDK,Android允许开发人员使用本地代码语言(例如C/C++)来完成应用的部分(甚至全部)功能.注意:由于翻译原因,有些地方也把Native翻译为"原生". NDK是SDK的一个补充,可以帮助你做这些事情: 生成可以在ARM CPU,Android 1.5(及以上)平台运行的JNI兼容的共享库. 将生成的共享库放置在应用程序项目路径的合适位置,使其能自动地添加进你最终的(和经过签名的)

《Linux内核分析》第六周学习笔记

<Linux内核分析>第六周学习笔记 进程的描述和创建 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 [学习视频时间:1小时 撰写博客时间:2小时] [学习内容:进程创建的过程.使用gdb跟踪分析内核处理函数sys_clone] 一.进程的描述 1.1 进程描述符task_struct数据结构(一) 1. 进程控制块PCB——task_struct 为了管理进程,内核

【Linux学习笔记第0天:学前计划与其他】

             前言     因为学习ARM的原因,最近开始接触到Linux操作系统,原本并没 有写博客或是学习笔记的习惯,但听了马哥的建议之后,觉得如果 将学习中的知识点和感悟记录下来,一方面,是一份可以长久保存的 笔记,任何时候都可以重新翻阅:另一方面可以培养自己的文档撰写 能力,有利于自己今后的工作.同时,如果记录的东西,对某些迷茫的 同学可以有帮助的话,那也算做了件好事. 之所以要开始学习Linux,主要是因为学习ARM的过程中,需要在ARM上 跑系统,而就市面上的学习资料而言

LVS的持久连接和awk/sed/grep的学习笔记

一.LVS持久连接的模式 1.PPC(persistent port connection) ipvsadm -A|E 192.168.10.1:80 -p 600 定义VIP为192.168.10.1director的80端口为持久连接,也就是只把web服务加入集群服务,可以通过改变端口实现不同服务的持久连接且把不同服务加入集群服务 2.PCC(persistent client connection) ipvsadm -A|E 192.168.10.1:0 -p 600 定义VIP为192.

MIT 6.828 JOS学习笔记2. Lab 1 Part 1.2: The kernel

Lab 1 Part 1: PC bootstrap 我们继续~ PC机的物理地址空间 这一节我们将深入的探究到底PC是如何启动的.首先我们看一下通常一个PC的物理地址空间是如何布局的:                           这张图仅仅展示了内存空间的一部分. 第一代PC处理器是16位字长的Intel 8088处理器,这类处理器只能访问1MB的地址空间,即0x00000000~0x000FFFFF.但是这1MB也不是用户都能利用到的,只有低640KB(0x00000000~0x00