gdb 基础命令

概述

GDB是GNU发布的一个调试工具。gdb 是基于UNIX/Linux 命令行的,功能强大,可与windows平台的visual studio 媲美。

基本命令

GDB的命令非常多,但我们只要掌握几个常见的,就可以满足日常基本程序的调试需求。

命令

解释

示例

file <文件名>

加载被调试的可执行文件 如果执行gdb与被调试的程序不在同个目录,则需要带上路径

(gdb) file gdb_sample

l <行号>

List 的缩写,打印源码 在gcc/g++ 编译程序时,需要加上-g 选项

(gdb) l 1

r

Run 的缩写,运行程序

(gdb) r

c

Continue 的缩写,继续执行程序,直到下一个断点或程序结束

(gdb) c

b <行号> b <函数名称>

Breakpoint 的缩写,设置断点

(gdb) b 8 (gdb) b main

d <断点编号>

Delete 的缩写,删除断点

(gdb) d 2

s

Step Into (单步跟踪进入) 执行一行源程序代码,如果此行代码有函数调用,则进入该函数

(gdb) s

n

Step Over (单步跟踪) 执行一行源程序代码,如果此行代码有函数调用,也一并执行

(gdb) n

p <变量名称>

Print 的缩写, 打印变量的值

(gdb) p i

bt

Backtrace 的缩写,查看堆栈信息

(gdb) bt

q

Quit 的缩写,退出gdb 调试环境

(gdb) q

help <命令名称>

可以查看各个命令的用法

(gdb) help r

举例

先看一个简单的程序

#include <stdio.h>

int sum(int n)
{
    int sum=0, i;
    for (i=0; i<n; ++i)
    {
        sum+=i;
    }
    return sum;
}

int main(int argc, char ** argv)
{
    int i=1;
    ++i;

    int result=0;
    result=sum(i);

    printf("sum[%d]\n", result);
    return 0;
}

将上面代码保存到 gdb_sample.c文件,然后用 gcc 编译:

gcc gdb_sample.c -g -o gdb_sample 

上面的命令,用参数 -g将源代码信息编译到可执行文件中,如果不指定,将无法在 gdb 里面查看代码,可以看看使用 -g 和不使用,编译后可执行文件的大小:

[huanghaibin@huanghaibin 17:10:17 ] gcc gdb_sample.c -g -o gdb_sample
[huanghaibin@huanghaibin 17:19:35 ] gcc gdb_sample.c -o gdb_sample_2   
[huanghaibin@huanghaibin 17:19:54 ] ll gdb_sample gdb_sample_2
-rwxrwxr-x 1 huanghaibin 8.4K 3月   9 17:19 gdb_sample_2
-rwxrwxr-x 1 huanghaibin 9.7K 3月   9 17:19 gdb_sample

可以用 gdb gdb_sample 直接进入调试环境,也可以先启动gdb,再打开可执行文件:

GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7
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) file gdb_sample
Reading symbols from /data1/hellerhuang/test_c/gdb_sample...done.
(gdb) 

上面表示可执行文件已经加载成功,(gdb) 是gdb内部命令引导符,等待用户输入命令

下面使用l 命令来查看源码,可以指定行号,回车可以继续往下查看:

(gdb) l 1
1       /*======================================================================
2           @file gdb_sample.c
3           @brief 
4           @author huanghaibin
5           @version 1.0
6           @date 2018-03-09
7           @copyright Copyright (c) 2015 Tencent Inc. All Rights Reserved.
8         ======================================================================*/
9
10      #include <stdio.h>
(gdb) 
11
12      int sum(int n)
13      {
14          int sum=0, i;
15          for (i=0; i<n; ++i)
16          {
17              sum+=i;
18          }
19          return sum;
20      }
(gdb) 
21
22      int main(int argc, char ** argv)
23      {
24          int i=1;
25          ++i;
26
27          int result=0;
28          result=sum(i);
29
30          printf("sum[%d]\n", result);
(gdb) 
31          return 0;
32      }
33
(gdb) 

下面使用r 命令执行程序,因为没有设置断点,所以程序执行到程序结束:

Starting program: /data1/hellerhuang/test_c/gdb_sample 
sum[1]
[Inferior 1 (process 6401) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-157.tl2.2.x86_64
(gdb) 

下面使用b 设置断点,在24行int i=1;设置断点,后执行r,再进入单步调试n s

(gdb) b 24
Breakpoint 1 at 0x40056d: file gdb_sample.c, line 24.     // 设置断点
(gdb) 
Starting program: /data1/hellerhuang/test_c/gdb_sample 

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:24   // 程序中断在24行
24          int i=1;
(gdb) n
25          ++i;
(gdb) s
27          int result=0;
(gdb) 

上面程序先执行到断点处(24行),然后单步调试,对于非函数,ns 执行结果一样

下面在28行设置第二个断点,用明令c直接运行到第二处断点,对比ns 执行函数的结果:

(gdb) b 28                                                       // 设置第二处断点
Breakpoint 2 at 0x40057f: file gdb_sample.c, line 28.
(gdb) c                                                          // 直接运行到第二个断点
Continuing.

Breakpoint 2, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28          result=sum(i);
(gdb) n                                                         // 执行整个函数
30          printf("sum[%d]\n", result);
(gdb) p result                                                  // 打印变量
$1 = 1
(gdb) r                                                         // 重新运行程序
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /data1/hellerhuang/test_c/gdb_sample 

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:24
24          int i=1;
(gdb) c
Continuing.

Breakpoint 2, main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28          result=sum(i);
(gdb) s                                                       // 单步调试进入函数
sum (n=2) at gdb_sample.c:14
14          int sum=0, i;
(gdb) bt                                                      // 查看堆栈信息
#0  sum (n=2) at gdb_sample.c:14
#1  0x0000000000400589 in main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
(gdb) finish
Run till exit from #0  sum (n=2) at gdb_sample.c:14
0x0000000000400589 in main (argc=1, argv=0x7fffffffe548) at gdb_sample.c:28
28          result=sum(i);
Value returned is $2 = 1
(gdb) n
30          printf("sum[%d]\n", result);
(gdb) p result
$3 = 1
(gdb) q
A debugging session is active.

        Inferior 1 [process 10635] will be killed.

Quit anyway? (y or n) y

上面bt 可查看程序的堆栈信息,然后通过finish命令执行完该函数,最后用命令q退出调试。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏互联网高可用架构

简单易用的消息队列框架的设计与实现

26820
来自专栏jeremy的技术点滴

netty3与netty4的区别

1.5K40
来自专栏张善友的专栏

如何合并Git 代码库中牛人的代码到自己的库

github for Windows使用介绍 这篇文章可以很好带我们入门github,同时还带了一个gitshell,这个工具可以运行github的所有命令,命...

21180
来自专栏NetCore

尝试使用Memcached遇到的狗血问题

乘着有时间,尝试下利用Memcached进行分布式缓存,其中遇到了不少问题及狗血的事情,开篇记录下,希望对您有帮助。 我之前的项目为:Asp.Net MVC4 ...

25650
来自专栏python开发者

linux用户权限相关内容查看

linux用户权限相关内容查看 1   用户信息 创建用户一个名为 webuser 的账号,并填写相应的信息: root@iZ94fabhqhuZ:~# add...

26590
来自专栏陈仁松博客

【译】使用 dotnet watch 开发 ASP.NET Core 应用

介绍 dotnet watch 是一个开发阶段在源文件发生变动的情况下使用 dotnet 命令的工具。 当代码发生变动的时候可以用来执行编译,运行测试,或者发布...

49860
来自专栏FreeBuf

从NTDS.dit获取密码hash的三种方法

本文我将为大家介绍一些取证工具,这些工具在渗透测试中将会对我们起到很大的帮助。例如当你提取到了大量的主机内部文件时,你可会发现其中包含如NTDS.dit和系统h...

19930
来自专栏烂笔头

Pycharm创建virtualenv方法

目录[-] Python的版本众多,在加上适用不同版本的Python Package。这导致在同时进行几个项目时,对库的依赖存在很大的问题。这个时候就牵涉...

49950
来自专栏蓝天

使用cmake编译和安装jsoncpp-0.10.2

网上主要介绍了python方式编译安装jsoncpp,但它的官网有介绍cmake安装命令行安装方式,以下笔记在SUSE Linux g++ 4.1.0上经过验证...

18320
来自专栏xingoo, 一个梦想做发明家的程序员

Tomcat 6 --- 你很少使用的安全管理SecurityManager

试想一下,如果你的JSP页面中包含一句代码“System.exit(1);”,你的web应用访问到该JSP时,会发生什么? 一般使用tomcat可能都没有注...

27370

扫码关注云+社区

领取腾讯云代金券