您的位置:首页 > 其它

gdb 调试高级命令

2016-12-02 08:07 218 查看
原文链接:http://blog.csdn.net/hejinjing_tom_com/article/details/9472041

1. gdb 运行初始化命令 -x usercmd

在.gdbinit 初始化命令中, 可以用#(同bash 注释符合)来注释
可以用source <cmd file> 在启动gdb 后运行gdb 命令文件
可以用file <loading file> 在启动gdb 后再加载文件

2. gdb 传递命令行 参数

a. run <args>

b. set args <args>

可用 show args 查看

3. gdb 中宏的操作

默认编译的时候,调试过程是看不见宏的值的。编译时候需要给选项。-g3

gcc -g3 -o test.c test

gdb test

察看宏(macro)命令: p macroname(...)

就像察看一个普通变量一样。如果只想看宏的展开形势,就用如下命令:

macro expand macroname(...) 查看展开形式

还可以用info macro macroname 查看宏定义。

4. gdb 临时断点: tbreak

5. gdb 设置显示选项 .

例如 set print pretty

打印结构变量类型. ptype struct 类型名
----------------------------------------

6. 让GDB记录输出信息到文件

----------------------------------------

(gdb) set logging on -> 打开记录功能。

(gdb) set logging off -> 关闭记录功能。

(gdb) show logging -> 显示记录功能中每个选项的设置。

Future logs will be written to gdb.txt. ---> 表示log 没有打开

Currently logging to "gdb.txt". --> 表示log 已经打开

----------------------------------------
7. gdb 调试运行的进程
gdb -p <进程号>
或者:
gdb
attach <进程号>

----------------------------------------

下面不常用的功能,供了解

set logging file <file name> -> 改变记录文件,默认记录文件是gdb.txt。

set logging overwrite [on|off] -> 默认这个项目是关闭,

也就是以添加的形式将记录信息写入文件,这样之前文件中的信息不会被覆盖掉。

注意:如果设置这个选项的时候记录功能已经打开,需要关闭记录功能再重新打开才能起作用。

set logging redirect [on|off] -> 设置输出信息只记录到文件不作显示。

默认这个项目是关闭的,GDB将输出信息到终端和记录文件。如果打开这个项目,GDB将只输出信息到记录文件。

注意:如果设置这个选项的时候记录功能已经打开,需要关闭记录功能再重新打开才能起作用。

注意:记录功能只能记录GDB的输出信息,被调试程序的输出信息仍然会输出到终端。

---------------------------------------

7. 为什么没有core文件生成呢?
---------------------------------------

有时候程序down了, 但是core文件却没有生成.

core文件的生成跟你当前系统的环境设置有关系, 可以用下面的语句设置一下, 然后再运行程序便生成了core文件.

ulimit -c unlimited

gdb a.out core

----------------------------------------

8. gdb加载内核模块符号信息:

add-symbol-file <MODULE_FILE> ADDR
例:
root@ubuntu:/home/hjj/software/uxfs_now/kern# cat debug

set remotebaud 115200

target remote /dev/ttyS1

add-symbol-file uxfs.ko 0xe0886000 -s .exit.text 0xe0888404

-------------------------------------------------

附录:gdb 常用调试命令

-------------------------------------------------

(gdb) l :(字母l)列出源码

(gdb) b n :在第n行处设置断点

(gdb) b func:在函数func()的入口处设置断点
(gdb) 条件断点:条件可以是任何合法的c 表达式。 例如 b n if val1==val2
当已经设置了断点,可以用condition 命令对断点号添加条件, 例: condition 2 val1==val2 , 注意,没有if 单词
当对变量的改变更感兴趣时,可以用watch 命令

(gdb) info break: 查看断点信息

(gdb) r:运行程序

(gdb) n:单步执行

(gdb) s:单步调试如果有函数调用,则进入函数;与命令n不同,n是不进入调用的函数的

(gdb) c:继续运行

(gdb) p 变量 :打印变量的值 也能够修改变量的值(用 = 赋值) // 打印寄存器值。 p $eax
(gdb) x/nfu <addr> 显示内存 // n为个数,f 为格式,u为每单元长度

(gdb) bt:查看函数堆栈

(gdb) finish:退出函数
(gdb) display <var> 每次中断或单步都显示你关心的变量
(gdb)undisplay <编号>

(gdb) shell 命令行:执行shell命令行

(gdb) set args 参数:指定运行时的参数

(gdb) show args:查看设置好的参数

(gdb)info program: 来查看程序的是否在运行,进程号,被暂停的原因。 // 打印寄存器数组, info reg, 简写 i reg

(gdb)clear 行号n:清除第n行的断点

(gdb)delete 断点号n:删除第n个断点

(gdb)disable 断点号n:暂停第n个断点

(gdb)enable 断点号n:开启第n个断点

----------------------------------------

gdb 条件调试

----------------------------------------

“break ... if cond" 命令

例: b fun() if i==20

ignore bnum count

watch var // 此时监测var的变化

----------------------------------------

gdb 多线程调试

----------------------------------------

info threads

thread ID 来切换

set scheduler-locking off|on|step 估计实际使用过多线程调试的人都可以发现,

在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,

怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。

off 不锁定任何线程,也就是所有线程都执行,这是默认值。

on 只有当前被调试程序会执行。

设置 on 之后, step 在单步的时候, 只有当前线程会执行。

next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)。

1.gdb有个很友好的调式界面,就是layout方式调试,可以让你边调试变查看源码,

但是layout方式有时候有点bug,不过基本上还可以使用,

可以用ctrl+x和ctrl+a 来切换。可能layout会造成控制台花屏,使用ctrl+L清屏。

----------------------------------------

GDB堆栈跟踪的方法

----------------------------------------

程序“调用堆栈”是当前函数之前的所有已调用函数的列表(包括当前函数)。每个函数及其变量都被分配了一个“帧”,

最近调用的函数在 0 号帧中(“底部”帧)。要打印堆栈,发出命令 'bt'('backtrace' [回溯] 的缩写):

(gdb) bt

#0 0x80483ea in wib (no1=8, no2=8) at eg1.c:7

#1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

此结果显示了在 main() 的第 21 行中调用了函数 wib()(只要使用 'list 21' 就能证实这一点),而且 wib() 在 0 号帧中,

main() 在 1 号帧中。由于 wib() 在 0 号帧中,那么它就是执行程序时发生算术错误的函数。

实际上,发出 'info locals' 命令时,gdb 会打印出当前帧中的局部变量,缺省情况下,这个帧中的函数就是被中断的函数(0 号帧)。

可以使用命令 'frame' 打印当前帧。要查看 main 函数(在 1 号帧中)中的变量,可以发出 'frame 1' 切换到 1 号帧,

然后发出 'info locals' 命令:

(gdb) frame 1

#1 0x8048435 in main (argc=1, argv=0xbffff9c4) at eg1.c:21

21 result = wib(value, div);

(gdb) info locals

value = 8

div = 8

result = 4

i = 2

total = 6

此信息显示了在第三次执行 "for" 循环时(i 等于 2)发生了错误,此时 "value" 等于 "div"。

可以通过如上所示在 'frame' 命令中明确指定号码,或者使用 'up' 命令在堆栈中上移以及 'down' 命令在堆栈中下移来切换帧。

要获取有关帧的进一步信息,如它的地址和程序语言,可以使用命令 'info frame'。

gdb 堆栈命令可以在程序执行期间使用,也可以在 core 文件中使用,因此对于复杂的程序,可以在程序运行时跟踪它是如何转到函数的。

查看栈信息

当程序被停住了,你需要做的第一件事就是查看程序是在哪里停住的。 当你的程序调用了一个函数,

函数的地址,函数参数,函数内的局部变量都会被压入“栈”(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()

backtrace <n>, bt <n> n是一个正整数,表示只打印栈顶上n层的栈信息。

backtrace <-n> ,bt <-n> -n表一个负整数,表示只打印栈底下n层的栈信息。

如果你要查看某一层的信息,你需要在切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。

frame <n>,f <n> n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。

up <n> 表示向栈的上面移动n层,可以不打n,表示向上移动一层。

down <n> 表示向栈的下面移动n层,可以不打n,表示向下移动一层。

上面的命令,都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三个命令:

select-frame <n> 对应于 frame 命令。

up-silently <n> 对应于 up 命令。

down-silently <n> 对应于 down 命令。

查看当前栈层的信息,你可以用以下GDB命令:

frame 或 f 会打印出这些信息:栈的层编号,当前的函数名,函数参数值,函数所在文件及行号,函数执行到的语句。

info frame,info f 这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内地址。比如:函数地址,调用函数的地址,被调用函数的地址,目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。如:

(gdb) info f

Stack level 0, frame at 0xbffff5d4:

eip = 0x804845d in func (tst.c:6); saved eip 0x8048524

called by frame at 0xbffff60c

source language c.

Arglist at 0xbffff5d4, args: n=250

Locals at 0xbffff5d4, Previous frame's sp is 0x0

Saved registers:

ebp at 0xbffff5d4, eip at 0xbffff5d8

info args 打印出当前函数的参数名及其值。

info locals 打印出当前函数中所有局部变量及其值。

info catch 打印出当前的函数中的异常处理信息。

gdb 跟踪远程调试命令交互过程

"set debug remote 1" 将显示gdb 远程调试的过程。

gdb 内存断点设置。

rwatch, watch, awatch 分别代表读,写,读写内存断点,用的是硬件断点。

------------------------------------------------------------------

gdbtui gdb 图形化接口。方便调试

启动gdb, 按ctrl-x cta-a 也可进入tui 模式

------------------------------------------------------------------

help layout

layout src

layout asm

layout split

help winheight

winheight src +5

winheight src -4

help focus

focus cmd

focus src

focus next

简记为

fs next

fs src

fs cmd

--------------------------------------------------------------------------------

help info

Generic command for showing things about the program being debugged.

关于被调试程序的一些信息

help show

Generic command for showing things about the debugger

关于debugger状态的一些信息

--------------------------------------------------------------------------------

常用命令:
set args
file
source

set logging overwrite on

set logging on

set print pretty

show logging

set pagination off // 不要出现 Type <return> to continue 的提示信息

info functions

info variables
list
list [函数名称]

与调试控制相关的命令

continue 继续运行程序直到下一个断点(类似于VS里的F5)

next 逐过程步进,不会进入子函数(类似VS里的F10)

step 逐语句步进,会进入子函数(类似VS里的F11)

until 运行至当前语句块结束

finish 运行至函数结束并跳出,并打印函数的返回值(类似VS的Shift+F11)

s : step in
fin: step out, 跳出函数
until 行号。 可用于跳出循环,加快了调试速度。

----------------------------------------

gdb 调试跟踪多进程程序

----------------------------------------

gdb只能跟踪一个进程(默认是跟踪父进程),而不能同时跟踪多个进程,

可以设置gdb跟踪父进程还是子进程, 命令如下:

set follow-fork-mode parent 跟踪父进程, 默认

set follow-fork-mode child 跟踪子进程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: