Windows下安装和使用GDB调试程序

21 篇文章 1 订阅
20 篇文章 0 订阅


或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你在 UNIX 平台下做开发,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。那么如果我想在Windows下使用GDB调试程序,应该怎么做呢?

一、什么是GDB?

「GNU调试器」(英语:GNU Debugger,缩写:「GDB」),GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。

二、它有哪些特点?

GDB具备各种调试功效,能针对计算机程序的执行进行追踪与警告,使用GDB的调试人员可以监督及修改程序的内部变量值,甚至监督与修改独立于主程序运作外,以独立个体类型调用(调用使用)的函数。

下面讲人话,它可以做以下事情:

1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

2、可让被调试的程序在你所指定的调置的断点处停住。

3、当程序被停住时,可以检查此时你的程序中所发生的事。

4、动态的改变你程序的执行环境。

三、前置条件

为了能用gdb调试程序,得先用gcc编译,gcc和gdb在Windows上是没有预装的,所以为了能用上它们,我们得先在 Windows 上安装好【MinGW】这个软件。

mingw(Minimalistic GNU for Windows) 编译器系统,建立在GCC和binutils项目上。MinGW提供了一套简单方便的Windows下的基于GCC程序开发环境,是一套GNU工具集合(一系列免费的Windows使用的头文件和库文件,同时整合了GNU工具集,特别是GNU程序开发工具,如经典gcc,g++,make等)。该集合允许人们在没有第三方动态链接库的情况下使用GCC产生Windows32程序。它在windows平台模拟了Linux下的GCC开发环境,为C++的跨平台提供了良好的基础支持。

1、下载安装

废话不多说,我们先访问MinGW 的主页:https://mingw.osdn.io/

640.png

MinGW 的主页

下载安装MinGW :https://osdn.net/projects/mingw/downloads/68260/mingw-get-setup.exe/

640.png

安装MinGW

安装包就是这个

640.png

安装包

安装很简单的,就不多说了,注意记住安装的目录,如 D:\Tools\MinGw,下面修改环境变量时还会用到

640.png

准备安装

安装好打开就是这个样子,大家感兴趣可以试试

640.png

程序打开后

2、简单配置一下

我们在里面找到【mingw32-gcc.bin】, 【mingw32-gcc-g++.bin】, 【mingw32-gdb.bin】,以及【mingw32-gdb.bin】 第一个是c语言文件的编译器,第二个是c++的,第三个是用来调试编译后文件的,最后一个就是gdb调试用到的。(注意class属性要为bin)

640.png

安装编译器

右键点击Mark for Installation(没截到图)

然后点击左上角的Installation菜单中的Apply changes选项,然后管理器将开始在线安装或更新被选中的组件

640.png

在线安装

不要犹豫和搞其他操作,直接点击Apply申请

640.png

点击Apply申请

640.png

安装中…

下面耐心等待程序的安装就好,安装完成后关闭包管理器。如果由于某种原因安装未能成功,在退出程序前程序将给予提示,选择【review changes】选项重新安装即可。

3、修改环境变量

安装好之后,是不能直接使用的,还需添加到环境变量。

选择计算机—属性—高级系统设置—环境变量,在系统变量中找到 Path 变量,在后面加入 min-gw的安装目录,如 D:\Tools\MinGw

640.png

修改环境变量

我们 win+r 打开运行,输入cmd,再输入 gcc -v 验证一下是否安装成功,g++也可以

640.png

打开gcc验证一下

640.png

打开gdb验证一下

就很简单,对吧。

四、GDB相关命令及程序演示

先上一段演示代码,新建一个名为mmap.c的C文件

#include <stdio.h>
int sum(int n) {
  int sum = 10;
  for (int i = 0; i <= n; i++) {
    sum += i;
    printf("1:the sum of 1-%d is %d\n", i, sum);
  }
  return sum;
}
int main() {
  int n = 0;
  sum(50);
  for (int i = 0; i <= 50; i++) {
    n += i;
  }
  printf("2:the sum of 1-50 is %d\n", sum);
  return0;
}//演示代码略简单,大家轻喷

启动gdb后,进入到交互模式,通过以下命令完成对程序的调试。注意高频使用的命令一般都会有缩写,熟练使用这些缩写命令能提高调试的效率。

进入代码所在目录,在目录内启动命令调试符,输入以下代码:

gcc -gstabs -o mmap mmap.c

640.png

源文件gcc编译一下

注意必须使用 -gstabs 参数,编译会加入调试信息,否则无法调试执行文件

640.png

编译后获得mmap.exe

输入【gdb mmap】 进入gdb调试,mmap为文件名

gdb mmap        //选择我们之前编译的文件,进入gdb调试
(gdb)list 1     //将显示当前文件以“行号”为中心的前后10行代码,list 10

640.png

进入gdb调试

(gdb)breakpoint 6           //简写成b 6,既在第六行设置断点
(gdb)info b                 //显示当前程序的断点设置情况
扩展:
  b fn1 if a>b         //条件断点设置
  break func            //在函数func()的入口处设置断点,如:break cb_button
  delete 断点号n         //删除第n个断点
  disable 断点号n        //暂停第n个断点
  enable 断点号n         //开启第n个断点
  clear 行号n            //清除第n行的断点

640.jpg

设置断点并查看

(gdb)r      //run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令
(gdb)n      //next:简记为n,执行下一行语句(单步调试)
(gdb)bt     //显示当前运行的堆栈列表
(gdb)show args    //查看设置好的参数
(gdb)info frame   //显示当前堆栈页的所有变量

640.png

运行程序并查看堆栈列表

640.png

单步调试

640.png

显示当前堆栈页的所有变量

(gdb)info registers    //查看所有寄存器
(gdb)info function     //查询函数
(gdb)x/4x $esp         //查看4个字节的栈顶寄存器的内容
(gdb)x/4x $ebp         //查看4个字节的栈底寄存器的内容
扩展知识
  (r是64位,e是32位)
  //eax     累加寄存器,它是很多加法乘法指令的缺省寄存器
  //ebx     基地址寄存器, 在内存寻址时存放基地址
  //esi     来源索引暂存器   edi      目的索引暂存器  
  //esp     栈顶寄存器       ebp      栈底寄存器   
  //eflags  状态位寄存器
  //ss      堆栈段寄存器  
  //cs      代码段寄存器  
  //ds      数据段寄存器

d9e07e3f68aa85d711040443f1491ebe.png

查看所有寄存器

d6a8e3e36cdad0523f5b4fdc7f626c85.png

查看4个字节的栈顶(栈底)寄存器的内容

052546362401a1ec3ee5e37a490b0606.png

查看其他寄存器

(gdb)quit       //简记为q,退出gdb
ps:交互模式下直接回车的作用是重复上一指令,对于单步调试非常方便;
ps:在Linux中,栈顶寄存器和栈底寄存器的内容是无法读出来的,会显示权限不够

f66891646589dce57132509c547b8b45.png

退出gdb调试

五、写在最后

最近刚接触到gdb方面的知识,文章写的有些粗糙,师傅们轻喷。


转自:https://developer.aliyun.com/article/1160627

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值