gdb入门使用

一.gdb是什么?

二.gdb怎么用?

三.命令详解

  • 1.调试命令​​s​​​或​​step​
(gdb) s
4 for (i=1;i<=n;i++)
(gdb) p i
$11 = 0

可以看到执行命令​​s​​​之后,出现了一行​​4 for (i=1;i<=n;i++)​​,这代表着即将执行的一行,我们打印i的值可以看到,此时的i的值仍然是0。再执行s命令,再打印i的值,会发现i从0变成了1。过程如下所示:

(gdb) s
5 sum+=i;
(gdb) p i
$12 = 1

下面再给出一个​​step​​执行的详细过程。在我的电脑中执行过程如下:

首先看一下源程序​​hello.cpp​

[root@localhost home]# cat hello.cpp 
#include<stdio.h>
int main(){
printf("hello world\n");
return 0;
}

使用命令​​gcc hello.cpp -g -o hello​​编译得到​​hello​​这个文件【这是一个具有编译标志的文件,可以使用gdb进行调试】。

下面就开始进行调试。

[root@localhost home]# gdb 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7_4.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.

在终端输入​​gdb​​​可以直接进入gdb环境【但是在后面需要再次使用​​file hello​​​对文件​​hello​​​进行操作】,也可以直接使用命令​​gdb hello​​。

(gdb) file hello

Reading symbols from /home/hello...done.
(gdb) list

1 #include<stdio.h>
2 int main(){
3 printf("hello world\n");
4 return 0;
5 }
6
(gdb) run
Starting program: /home/hello
hello world
[Inferior 1 (process 14136) exited normally]

直接使用命令​​run​​得到的结果如上所示。下面尝试添加断点,再次调试程序。

(gdb) b 3
Breakpoint 1 at 0x4005f1: file hello.cpp, line 3.
(gdb) run
Starting program: /home/hello

Breakpoint 1, main () at hello.cpp:3
3 printf("hello world\n");
(gdb) s
_IO_puts (str=0x4006a0 "hello world") at ioputs.c:33
33 {
(gdb) n
35 _IO_size_t len = strlen (str);
(gdb) n
36 _IO_acquire_lock (_IO_stdout);
(gdb) n
35 _IO_size_t len = strlen (str);
(gdb) n
36 _IO_acquire_lock (_IO_stdout);
(gdb) finish
Run till exit from #0 _IO_puts (str=0x4006a0 "hello world") at ioputs.c:36
hello world
main () at hello.cpp:4
4 return 0;
Value returned is $1 = 12
(gdb) finish
"finish" not meaningful in the outermost frame.
(gdb) quit
A debugging session is active.

Inferior 1 [process 14164] will be killed.

Quit anyway? (y or n) n
Not confirmed.
(gdb) n
5 }
(gdb) n
__libc_start_main (main=0x4005ed <main()>, argc=1, argv=0x7fffffffe108,
init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffe0f8) at ../csu/libc-start.c:300
300 exit (result);
(gdb) next
[Inferior 1 (process 14164) exited normally]
(gdb) next
The program is not being run.
(gdb) quit
[root@localhost home]#

在程序调试过程中,得到了如下的信息:

_IO_puts (str=0x4006a0 "hello world") at ioputs.c:33

这是怎么回事儿?仔细想想原来是因为​​step​​命令的原因,因为这个命令会进入到函数内部,所以在执行​​printf()​​函数时,便进到了c语言中的​​printf()​​的函数中。导致看到了一串很古怪的代码。

我们可以使用​​finish​​命令很快的跳出来,然后再使用​​next​​命令退回来。执行过程如上所示。不再赘述。

  • 2.观察变量值命令​​watch​​​ 先简述​​watch​​命令的使用效果和方法.
    watch可设置观察点(watchpoint)。使用观察点可以使得当某表达式的值发生变化时,程序暂停执行。执行该命令前,必须保证程序已经运行

在测试​​watch​​之前,先看一下源程序:

[root@localhost home]# cat test.cpp 
#include<cstdio>
#include<iostream>

using namespace std;

int main(){
int sum = 0;
for(int i = 0;i< 5;i++){
sum += i;
}
cout << sum;
return 0;
}

使用命令​​g++ test.cpp -g -o test​​编译得到​​test​​文件;

执行命令​​# gdb test​​进入​​gdb​​的环境;

执行命令​​(gdb) b 7​​打断点;

下面执行的命令较多,这里不再叙述,具体过程如下:

(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/test

Breakpoint 1, main () at test.cpp:7
7 int sum = 0;
(gdb) watch sum
Hardware watchpoint 3: sum
(gdb) s
8 for(int i = 0;i< 5;i++){
(gdb)
9 sum += i;
(gdb)
8 for(int i = 0;i< 5;i++){
(gdb)
9 sum += i;
(gdb)
Hardware watchpoint 3: sum

Old value = 0
New value = 1
main () at test.cpp:8
8 for(int i = 0;i< 5;i++){
(gdb)
9 sum += i;
(gdb)
Hardware watchpoint 3: sum

Old value = 1
New value = 3
main () at test.cpp:8
8 for(int i = 0;i< 5;i++){
(gdb)
9 sum += i;
(gdb)
Hardware watchpoint 3: sum

Old value = 3
New value = 6
main () at test.cpp:8
8 for(int i = 0;i< 5;i++){
(gdb)
9 sum += i;
(gdb)
Hardware watchpoint 3: sum

Old value = 6
New value = 10
main () at test.cpp:8
8 for(int i = 0;i< 5;i++){
(gdb)
11 cout << sum;
(gdb)
12 return 0;
(gdb) n
13 }
(gdb)

Watchpoint 3 deleted because the program has left the block in
which its expression is valid.
__libc_start_main (main=0x40076d <main()>, argc=1, argv=0x7fffffffe108,
init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffe0f8) at ../csu/libc-start.c:300
300 exit (result);
(gdb)
10[Inferior 1 (process 15275) exited normally]

在上述的执行过程中,我对​​sum​​​进行了观测,可以看到每次​​sum​​的值有变化时,就可以看到都会打印出

Hardware watchpoint 3: sum

Old value = 3
New value = 6

这样的字眼。这里表示的含义就是:sum之前的值是3,现在的值是6。