gdb 基本使用
前言
// Offers opportunities to play with pointers with GDB
/*
gcc -g bar.c -o bar //-g compile with debug info for gdb
*/
# include <stdio.h>
int foo(int n);
void bar(int m);
int main(void)
{
int a;
char *s = "hello, world";
printf("%s\n", &s[7]);
a = 5;
foo(a);
return 0;
}
int foo(int n)
{
int b;
b = n;
b *= 2;
bar(b);
return b;
}
void bar(int m)
{
printf("Hi, I'm bar.\n");
}
首先编译该程序,添加-g
选项可以给编译程序添加debug信息。
# gcc -g bar.c -o bar //-g compile with debug info for gdb
调试开始:
...
Reading symbols from bar...done.
(gdb) break main # 在main函数上打断点,程序在进入main函数后暂停
Breakpoint 1 at 0x40052e: file bar.c, line 9.
(gdb) run # run指令运行程序
Starting program: /home/wangx/test/bar
Breakpoint 1, main () at bar.c:9
9 char *s = "hello, world"; # 程序停止在这里意味着这行下一步将被执行但是还没有执行
(gdb) list # 显示停顿处周围的代码
4 void bar(int m);
5
6 int main(void)
7 {
8 int a;
9 char *s = "hello, world";
10 printf("%s\n", &s[7]);
11 a = 5;
12 foo(a);
13 return 0;
(gdb) print a # 显示a的值,此时a没被赋值,是内存中的一个无效数字
$1 = 32767
(gdb) print &a # 显示a的地址
$2 = (int *) 0x7fffffffe4d4
(gdb) next # 运行程序到当前函数下一行停止
10 printf("%s\n", &s[7]);
(gdb) next # next again
world
11 a = 5;
(gdb) next # next again,看见下一行将进入foo函数
12 foo(a);
(gdb) step # 运行程序到最近位置停下,这里的作用是进入到foo函数中停止
foo (n=5) at bar.c:19
19 b = n;
(gdb) print n # 显示n的值
$3 = 5
(gdb) print b # 显示b的值,b还没被赋值
$4 = 32767
(gdb) print &b # 显示b的地址
$5 = (int *) 0x7fffffffe4bc
(gdb) continue # 程序继续执行直到下一个断点停止
Continuing.
Hi, I'm bar.
[Inferior 1 (process 28376) exited normally] #程序退出
该例子还说明了被调用的函数中变量的地址更小。即新调用的栈的地址更小。具体来说,这里main函数调用了foo函数,main中a变量的地址为0x7fffffffe4d4,foo中b变量的地址为0x7fffffffe4bc,显然b的地址比a小,说明越高的栈在本机中地址是越小的。
+-------------+ 0
| ... | ^
+-------------+ |
memory-> | foo(a), b | ---> smaller address |
+-------------+ |
| main, a | ---> bigger address v
+-------------+ 最大内存位置