记录学习过程中的点点滴滴
gdb
gdb调试程序之监控内存【七】
二 12th
gdb提供awtach rwatch watch来监控调试中变量或者内存的变化
awatch 命令
awtach [expr]
当debugger read或者write该expr时,debugger 停止
rwatch 命令
rwatch [expr]
当debugger read该expr时,debugger停止
watch命令
watch [expr]
当debugger write该expr时,debugger停止
说明:expr可以是变量或者是内存地址
gdb调试程序之调试宏的方法[六]
二 17th
在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。
另外,你可以使用下述的GDB的宏调试命令 来查看相关的宏。
- info macro_name – 查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。
- macro_name – 查看宏展开的样子。
gdb 调试多进程程序方法
一 12th
今天在用gdb调试sheepdog时,在程序fork出子进程后,整个gdb程序就退出了,无法继续跟踪,网上找了半天找到了解决方法.
解决方法:
设置detach-on-fork参数
set detach-on-fork [on|off]
- on: 断开调试follow-fork-mode指定的进程。
- off: gdb将控制父进程和子进程。follow-fork-mode指定的进程将被调试,另一个进程置于暂停(suspended)状态
将detach-on-fork 设置为off即可
跟踪子进程的方法:
默认情况下,gdb会继续跟踪父亲进程,无法对子进程进行调试
设置follow-fork-mode可以解决这个问题
follow-fork-mode的用法为:
set follow-fork-mode [parent|child]
- parent: fork之后继续调试父进程,子进程不受影响。
- child: fork之后调试子进程,父进程不受影响。
(gdb) set follow-fork-mode child
gdb交叉编译的方法
十二 2nd
最近需要在32位机器上调试64位的内核,需要在32位机器上编译出能够读取64位的内核文件vmlinux的gdb,今天问周老师,原来gdb本身可以支持交叉编译,gdb好强悍!!
正确的编译方法:
./configure --target=x86_64-linux-gnu
错误方法:
./configure --target=x86_64
*** BFD does not support target x86_64-pc-none.
*** Look in bfd/config.bfd for supported targets.
make[1]: *** [configure-bfd] Error 1
make[1]: Leaving directory `/home/yaronli/software-tar/gdb-6.8'
make: *** [all] Error 2
我刚开始用得这个选项,一直报错
gdb调试程序之查看运行时数据【五】
十一 20th
在用gdb调试程序时,当程序运行到之前设置的断点时,很容易想到的操作就是查看当前变量的值,而gdb可以很轻易地满足的你的需求的~~
在gdb中最常用的命令就是print(简写p),具体格式如下:
print <expr> print/f <expr> f代表输出的格式 x 按十六进制格式显示变量 d 按十进制格式显示变量 u 按十六进制格式显示无符号整型 o 按八进制格式显示变量 t 按二进制格式显示变量 a 按十六进制格式显示变量 c 按字符格式显示变量 f 按浮点数格式显示变量
表达式
print命令可以接受表达式,其中表达式的定义遵循C/C++语法,需要注意的是表达式中不能出现程序中定义的宏表达式;同时在gdb表达式中,还支持以下三种特殊的操作符:
@ 是一个和数组有关的操作符,在后面会有更详细的说明 :: 指定一个在文件或是一个函数中的变量,注意与C++语法中的::操作符的区分 {} 表示一个指向内存地址的类型为type的一个对象
更多 >
gdb调试程序之栈和源码信息【四】
十一 15th
显示栈信息
当程序停在你设置的断点处时,你首先需要看的是函数调用的过程即函数调用栈,及每层栈中函数的名称、参数和局部变量等信息,这时可以用gdb提供的backtrace(bt)来查看函数调用栈信息
backtrace <n>, bt <n> n是一个正整数,表示只打印栈顶上n层的栈信息。 backtrace <-n> ,bt <-n> -n表一个负整数,表示只打印栈底下n层的栈信息。
(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()
如果你要查看某一层的信息,你需要在切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈,此时可以用frame命令来进行切换
frame <n> 是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。 up 表示向栈的上面移动n层,可以不打n,表示向上移动一层。 down 表示向栈的下面移动n层,可以不打n,表示向下移动一层。
当切换到某个某层frame时,可以使用info命令来查看当前函数的具体信息
info frame 显示当前frame的详细信息 info args 显示函数的参数的详细信息 info locals 打印出当前函数中所有局部变量及其值 info catch 打印出当前的函数中的异常处理信息
更多 >
gdb调试程序之单步调试【三】
十一 15th
断点维护
在gdb中,如果觉得设置的断点已经没有用处了,可以使用delete clair 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自动删除。
gdb调试程序系统之断点设置【二】
十一 10th
调试程序时,暂停程序运行时首要任务,在gdb中有以下几种暂停方法:断点(BreakPoint)、观察点(WatchPoint)、捕捉点(CatchPoint)、信号(Signals)、线程停止(Thread Stops)
设置断点
break <function> | 在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名 |
break <linenum> | 在指定行号停住 |
break +offset
break -offset |
在当前行号的前面或后面的offset行停住。offset为自然数 |
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 breakpoints [n]
info break [n] |
查看断点时,可使用info命令,如下所示:(注:n表示断点号) |
设置观察点
观察点一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点:
watch <expr> 为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。
rwatch <expr> 当表达式(变量)expr被读时,停住程序。
awatch <expr> 当表达式(变量)的值被读或被写时,停住程序。
info watchpoints 列出当前所设置了的所有观察点。 更多 >
gdb调试程序系列之启动gdb【一】
十一 10th
首先需要在gcc或者g++编译时加入-g选项,这个程序才能将调试信息加入到执行程序中
其次需要把编译优化选项去掉,加入-O0选项,否则的话编译会修改你的源程序,调试时出现诡异的问题;
启动gdb的方法
1、gdb <program>
program也就是你的执行文件,一般在当然目录下。
2、gdb <program> core
用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。
3、gdb <program> <PID>
如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。或者是进入gdb后,通过attach PID命令,将调试进程加入到gdb中
gdb启动时常用开关选项 -symbols <file> -s <file> 从指定文件中读取符号表。 -se file 从指定文件中读取符号表信息,并把他用在可执行文件中。 -core <file> -c <file> 调试时core dump的core文件。 -directory <directory> -d <directory> 加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径
近期评论