进程地址空间
高地址 | 命令行参数和环境变量 |
|
| 栈 | 向下增长; |
| 未使用空间 |
|
| 堆 | 向上增长; |
| 未初始化数据段(BSS) | 未初始化全局变量,程序执行前初始化为0或NULL; |
| 已初始化数据段 | 由exec从程序文件读取; |
低地址 | 文本段 | 由exec从程序文件读取; |
l 栈中保存了函数调用关系。每调用一个函数,分配一个栈帧,记录函数返回地址、传递的参数以及局部变量。
l 可以使用GDB的backtrace(缩写为bt)命令查看栈信息。最前面的数字代表帧号。
可以使用frame(缩写为f)命令查看当前栈帧,即当前所在的函数。
l GDB只能查看当前函数内的变量。如果要查看其它函数内的变量,需要切换栈帧,方法是为frame命令传递帧号。
(gdb) p i No symbol "i" in current context. (gdb) frame 2 #2 0x08048453 in main (argc=Cannot access memory at address 0xc) at gdb_test.c:14 (gdb) p i $1 = 3 |
运行程序
l 要在GDB中运行程序,可以在shell中输入gdb ./filename。
l 或者在运行GDB后,通过file命令打开程序。
l 调用run(缩写为r)命令开始执行。可以为run命令传递命令行参数。set args命令撤销之前传递的参数。
(gdb) run 1 2 3 Starting program: /home/pydeng/gdb_test/gdb_test 1 2 3 There are 4 args. |
l 调用kill(缩写为k)命令停止程序的执行,然后使用run重新运行。
l 或者在程序运行的时候再次调用run命令,GDB将询问是否重新运行程序。
查看代码
l 可以使用list(缩写为l)命令显示当前位置后面的十行代码。加上负号则显示前面十行,如list -。
l 可以以多种方式指定显示的位置,如:
从第5行开始 | (gdb) list 5, |
到28行结束 | (gdb) list ,28 |
显示21到25行之间的代码 | (gdb) list 21,25 |
显示func1函数 | (gdb) list func1 |
显示其它文件的12行 | (gdb) list otherfile.c:12 |
显示其它文件的函数 | (gdb) list otherfile.c:func |
l 可以通过set命令改变显示的代码行数,如set listsize 5。
设置断点
l 使用break命令设置断点,断点的位置可以通过四种方式指定。
通过函数名指定 | (gdb) break func1 |
通过行号指定 | (gdb) break 9 |
通过文件名和行号指定 | (gdb) break main.c:10 |
通过内存地址指定 | (gdb) break *0x80483f4 |
l 也可以在到达断点的时候,根据当前的位置设置断点。如break +2在当前位置后面第2行的位置设置断点,break -3在当前位置的前面第3行的位置设置断点。
l 可以通过where命令查看当前所在的位置。
l 可以为断点添加条件,只有当条件满足时才会在断点处暂停程序。
(gdb) b 17 if i==1 Breakpoint 8 at 0x8048455: file gdb_test.c, line 17. |
l 程序到达断点暂停后,可以使用continue命令恢复执行。
l 或者使用step或next命令单步执行。两者的区别在于,step命令将进入被调用的函数,而next命令将函数调用看作一条语句。
l info breakpoints(缩写为i b)命令能够查看设置的所有端点。Num为断点号,Enb标识端点是否启用。
(gdb) i b Num Type Disp Enb Address What 6 breakpoint keep n 0x08048436 in main at gdb_test.c:12 8 breakpoint keep y 0x08048455 in main at gdb_test.c:17 stop only if i==1 |
l 可以使用clear或delete命令删除断点,前者使用上述四种指定断点位置的方式标识断点,后者使用断点号标识断点。
l 通过传递断点号,disable或enable命令能够暂时停用或重新启用断点。
查看变量
l 使用ptype(缩写为pt)命令查看变量的类型。要记住,只能查看当前栈帧内的变量。
l 使用print(缩写为p)命令加变量名,可以查看变量的值,也可以使用取地址符查看变量的地址,并且能够指点显示的格式。
| o octal x hex d decimal u unsigned decimal t binary f float a address c char |
|
(gdb) p /x i $3 = 0x1 | ||
l 查看数组时,可以指定显示的元素起始位置和元素个数,但是不会检查是否越界。
(gdb) p array[2]@5 $4 = {3, 4, 5, 6, 134514064} |
l 也可以查看结构体。使用set print pretty命令优化显示格式。
(gdb) p p $6 = {age = 25, name = 0x80485a7 "cying"} (gdb) set print pretty (gdb) p p $7 = { age = 25, name = 0x80485a7 "cying" } |
l 可以使用set或print命令,在程序执行过程中,改变变量的值,如set i = 5或print i = 5。两者区别在于,后者打印改变后的值。
(gdb) set array[0]=11 (gdb) p array[1]=22 $8 = 22 (gdb) p array $9 = {11, 22, 3, 4, 5, 6} |