- 创建可调试的可执行文件
gdb -g main.c -o main -g Produce debugging information in the operating system's native format (stabs, COFF, XCOFF, or DWARF 2). GDB can work with this debugging information.
- 开始调试
1. gdb main 2. gdb (gdb) file main
- gdb里显示源代码
源代码一定要存在,否则不能显示。
(gdb) list 每次显示10行。 (gdb) list 10 将会显示 从5行到14行 (gdb) list main 显示main所在行的前5行和后4行
跨文件(test.c)显示
(gdb) list test.c:1 从test.c的第一行开始显示 (gdb) list test.c:test 显示test.c的test函数
注:list 可以简写为 ‘l’
- 参数传递
有时写的程序需要从外面传参。
(gdb) set args "hello" "world" 传入两个参数 (gdb) show args 显示传入的参数
- 断点操作
调试的目的在于看执行的中间过程,因此需要为程序设置断点。- 断点设置
(gdb)break main 在main处设为断点 (gdb)break 10 在第10行入设置断点 (gdb)break test.c:test 在test.c的test函数处设置断点
- 查看断点
(gdb)info breakpoints
- 删除断点
(gdb) delete breakpoints 1 删除断点1 (gdb) disable breakpoints 1 使断点1无效 (gdb) clean 10 清除第10行所有的断点
- 断点设置
- 调试执行
当断点设置好后,就可以开始执行了,
(gdb) run 程序将会运行到第一个断点处 (gdb) continue 将运行到下一个断点处 (gdb) step 单步执行,当遇到函数调用时,会步进到该函数中 (gdb) finish 当步进到一个函数后, 该指令完成该函数的全部执行. (gdb) next 也是单步执行,当遇到函数调用时,不会进入该函数 (gdb) stepi 单步执行一条指令 (gdb) nexti 与step/next效果一样 (gdb) until 结果当前循环
- 值的查询
在调试过程中,必然会对中间值进行查看.否则就失去调试的意义了
(gdb) display a 监视变量a (gdb) print a 打印变量a的值 (gdb) print h@length 打印h及h后面连续length个h类型, 如int h[10] print h@10将会打印10*4*10个字节的内容. (gdb) call func(5) or print func(5) 调用func函数,传入参数5,返回该函数执行后的结果 (gdb) bt 打印当前的函数调用关系 (gdb) frame 查看当前运行到的函数,以及下一条要执行的语句 (gdb) x/19x sum 查看sum开始的19个字节并以16进制的形式显示出来 x,a: 十六进制 u:无符号的十六进制 d:十进制 o:八进制 t:二进制 c:字符形式 f:浮点形式 (gdb) 当为int *pc指针分配了一段内存空间后,并为其赋值后要查看该段内存里的值时用 print *pc@10 or x/10 pc or display *pc@10 (gdb) info locals 查看函数的局部变量的值 (gdb) show args 显示传入程序的参数 (gdb) whatis x 显示x的类型(int, char, struct) (gdb) ptype x 显示x的类型,如果x是结构体或union,将会显示该结构体的定义 (gdb) set var a = 10 有时在调试时,看下当某个变量为想要的值时,程序是否正常运行.这时就设置该变量为该值
- 反汇编
(gdb) disassemble 反汇编当前函数 (gdb) disassemble sum 反汇编sum函数 (gdb) jump line or address of instruction 即汇编中的jump,被跳过的指令不执行 (gdb) stepi/nexti or si/ni 单步执行指令 (gdb) infor r 显示所有的寄存器的值 (gdb) display /i $pc 显示下一条将要执行的指令 (gdb) print $eax 打印寄存器eax的值
- gdb代码查看
(gdb) layout asm 查看汇编代码 (gdb) layout split 分隔 (gdb) layout src 查看源代码 (gdb) layout reg 查看寄存器
- gdb命令文件
当要重复调试一个程序时,如果修改一点,再调试,这时要重新设置断点,监视变量,将会非常麻烦.gdb可以把要事先设置好的断点或变量打印加入到一个文件当中去,当gdb启动时,会自动查询该文件并将里面的内容作为gdb命令事先设置好.
gdb –command=file gdb导入file文件中的命令
gdb默认会在当前目录下搜寻.gdbinit文件,如果搜寻到则将先执行里面的命令
gdb -sysbols file or -s file 从指定的file读取符号表
gdb –directory directory or -d directory 从directory中加入一个源文件做为搜索目录 - gdb调试线程
info threads #显示程序中所有的线程ID. thread ID #切换当前调试线程为指定的ID线程. thread apply ID1 ID2 command #让一个或者多个线程执行GDB命令command。 thread apply all command #让所有的线程执行command set scheduler-locking off|on|step #在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。 off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。
参考:
http://361324767.blog.163.com/blog/static/1149025252012620105742710/
http://www.mystone7.com/2012/09/19/gdb_comman/
http://wiki.ubuntu.org.cn/%E7%94%A8GDB%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F
gdb -command=file gdb导入file文件中的命令,当gdb启动时,会自动查询该文件并将里面的内容作为gdb命令事先设置好
gdb -d directory 从directory中加入一个源文件做为搜索目录
gdb /some/process -q
-q是“quite”的意思,手册中的说明是“Do not print the introductory and copyright messages. These messages are also suppressed in batch mode.”,就是不打印gdb一开始时的一堆版本信息
(gdb) info line some_function 打印函数some_function()的地址信息,
比如“Line 79 of "main.cpp" starts at address 0x4a58a3 <main(int, char**)> and ends at0x4a58a2 <main(int, char**)+15>”
(gdb) p $pc $pc是GDB的环境变量,表示着指令的地址
结果如,$1 = (void (*)(void)) 0x400558 <main()+4>
(gdb)set args "hello" "world" 传入两个参数
(gdb) show args 显示传入的参数
(gdb)until 结束当前循环
(gdb)call func(5) orprint func(5) 调用func函数,传入参数5,返回该函数执行后的结果
(gdb)frame 查看当前运行到的函数,以及下一条要执行的语句
(gdb)x/19x sum 查看sum开始的19个字节并以16进制的形式显示出来
x,a: 十六进制 u:无符号的十六进制 d:十进制 o:八进制 t:二进制 c:字符形式 f:浮点形式
(gdb)info locals 查看函数的局部变量的值
(gdb)whatis x 显示x的类型(int, char, struct, ……)
(gdb)ptype x 显示x的类型,如果x是结构体或union,将会显示该结构体的定义
或者ptx
(gdb)layout asm 查看汇编代码
(gdb) layout split 分隔
(gdb) layout src 查看源代码
(gdb) layout reg 查看寄存器
(gdb) list 简记为 l ,其作用就是列出程序的源代码,默认每次显示10行
(gdb) list 行号 显示当前文件以“行号”为中心的前后10行代码,如:list 12
(gdb) list 函数名 显示“函数名”所在函数的源代码,如:list main
(gdb) list 不带参数,将接着上一次 list 命令的,输出接下来的内容
注意, 如果运行list 命令得到类似如下的打印,那是因为在编译程序时没有加入 -g 选项
(gdb) list
1 ../sysdeps/i386/elf/start.S: No such file or directory.
in ../sysdeps/i386/elf/start.S
(gdb) focus cmd/src/asm/regs/next/prev 切换当前窗口
(gdb) update 更新源代码窗口和当前执行点
有时候,需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用GDB的“@”操作符,“@”的左边是第一个内存的地址的值,“@”的右边则你你想查看内存的长度。例如,你的程序中有这样的语句:
int *array = (int *) malloc (len * sizeof (int));
于是,在GDB调试过程中,你可以以如下命令显示出这个动态数组的取值:
(gdb) p *array@len
(gdb) info threads 显示程序中所有的线程ID.
(gdb) thread ID 切换当前调试线程为指定的ID线程.
(gdb) thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command。
(gdb) thread apply all command 让所有的线程执行command
《gdb命令小结》
转自:http://www.mystone7.com/2012/09/19/gdb_comman/