一、gdb调试

1、gdb调试的三种方式

  • 目标板直接使用GDB进行调试。
  • 目标板使用gdbserver,主机使用xxx-linux-gdb作为客户端。
  • 目标板使用ulimit -c unlimited,生成core文件;然后主机使用xxx-linux-gdb ./test ./core。

例子:

(1)main.cpp

#include "sum.h"using namespace std;int main(int argc, char *argv[])
{if(argc != 2){cout << "please start with 2 values!" << endl;return -1;}else{Sum s;int ret = s.add(atoi(argv[1]));cout << "add result = " << s.getResult() << endl;}return 0;
}

(2)sum.h

#include <iostream>using namespace std;class Sum{public:Sum(){}~Sum(){}int add(int value);int getResult();private:int _result = 0;
};

(3)sum.cpp

#include "sum.h"int Sum::getResult()
{return _result;
}int Sum::add(int value)
{int result = 0;cout << "input value = " << value << endl;for(int i = 0; i < value; i++){result += i;}_result = result;return result;
}

2、编译及运行

编译:

g++ main.cpp sum.h sum.cpp -o add -g

运行:

(法一):gdb + 编译后的文件名,然后输入run(简写r)即可运行。

(法二):命令行中先输入gdb,按回车,再输入file + 编译后的文件.

退出:q

注:cmake项目,在CMakeLists.txt文件中添加如下语句:

SET(CMAKE_BUILD_TYPE "Debug")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

3、断点

(1)设置断点

设置断点可以通过b或者break设置断点,断点的设置可以通过函数名、行号、文件名+函数名、文件名+行号以及偏移量、地址等进行设置。

格式:

  • break 函数名
  • break 行号
  • break 文件名:函数名
  • break 文件名:行号
  • break +偏移量
  • break -偏移量
  • break *地址

(2)删除断点

格式:

  • delete <断点id>:删除指定断点
  • delete:删除所有断点
  • clear
  • clear 函数名
  • clear 行号
  • clear 文件名:行号
  • clear 文件名:函数名

(3)设置条件断点

  • break 断点 if 条件;比如break add if value==9,当输入的value为9的时候才会断住。
  • condition 断点编号:给指定断点删除触发条件。
  • condition 断点编号 条件:给指定断点添加触发条件。

(4)停用或启用断点

  • disable
  • disable 断点编号
  • disable display 显示编号
  • disable mem 内存区域
  • enable
  • enable 断点编号
  • enable once 断点编号:该断点只启用一次,程序运行到该断点并暂停后,该断点即被禁用。
  • enable delete 断点编号
  • enable display 显示编号
  • enable mem 内存区域

(5)断点commands高级功能

大多数时候需要在断点处执行一系列动作,gdb提供了在断点处执行命令的高级功能commands。

例:

#include <stdio.h>int total = 0;int square(int i)
{int result=0;result = i*i;return result;
}int main(int argc, char **argv)
{int i;for(i=0; i<10; i++)  {total += square(i);}return 0;
}

比如需要对如上程序square参数i为5的时候断点,并在此时打印栈、局部变量以及total的值,同时生成gdb的调试log,编写gdb.init如下:

set logging on gdb.logb square if i == 5
commandsbt fulli localsp totalprint "Hit break when i == 5"
end

4、显示堆栈

如果遇到断点而暂停执行,或者coredump可以显示栈帧。通过bt可以显示栈帧,bt full可以显示局部变量。

格式:

  • bt
  • bu full:不仅显示backtrace,还显示局部变量
  • bt N:显示开头N个堆栈
  • bt full N

5、显示变量

“print 变量”(简写“p”)可以显示变量内容。

如果需要一行监控多个变量,可以通过p {var1, var2, var3}。

如果要跟踪自动显示,可以使用display {var1, var2, var3}。

6、显示寄存器

info reg可以显示寄存器内容。

在寄存器名之前加$可以显示寄存器内容:

  • p $寄存器:显示寄存器内容
  • p/x $寄存器:十六进制显示寄存器内容。

用x命令可以显示内容内容,“x/格式 地址”。

  • x $pc:显示程序指针内容
  • x/i $pc:显示程序指针汇编。
  • x/10i $pc:显示程序指针之后10条指令。
  • x/128wx 0xfc207000:从0xfc20700开始以16进制打印128个word。

          还可以通过disassemble指令来反汇编。

  • disassemble
  • disassemble 程序计数器 :反汇编pc所在函数的整个函数。
  • disassemble addr-0x40,addr+0x40:反汇编addr前后0x40大小。

7、单步执行

单步执行有两个命令next和step,两者的区别是next遇到函数不会进入函数内部(逐过程),step(逐语句)会执行到函数内部。

如果需要逐条汇编指令执行,可以分别使用nexti和stepi。

注:直接回车默认为上一次的命令。

  • continue、step、stepi、next、nexti都可以指定重复执行的次数。
  • ignore 断点编号 次数:可以忽略指定次数断点。

8、继续执行

调试时,使用continue命令继续执行程序。程序遇到断电后再次暂停执行;如果没有断点,就会一直执行到结束。

  • continue:继续执行
  • continue 次数:继续执行一定次数。

9、监视点

要想找到变量在何处被改变,可以使用watch命令设置监视点watchpoint。

格式:

  • watch <表达式>:表达式发生变化时暂停运行
  • awatch <表达式>:表达式被访问、改变时暂停执行
  • rwatch <表达式>:表达式被访问时暂停执行

注:

其他变种还包括watch expr [thread thread-id] [mask maskvalue],其中mask需要架构支持。

GDB不能监控一个常量,比如watch 0x600850报错。但是可以watch *(int *)0x600850。

10、改变变量的值

“通过set variable <变量>=<表达式>”来修改变量的值。

  • set $r0=xxx:设置r0寄存器的值为xxx。

11、生成内核转储文件

运行后,如果有段错误,会在当前目录下生成通过生成core.pid(pid为进程号)转储文件。或者通过“generate-core-file”也会生成core.pid(pid为进程号)转储文件。

通过gdb ./main ./core.pid查看恢复的现场。

(1)配置是否允许生成core文件

在生成内核储文件之前需要先查看配置是否允许生成core文件。

ulimit -a,如果core file size为0,则表示core文件大小为0,即不允许生成。

注:ulimit使用

(a)语法:

ulimit [-aHS][-c <core文件上限>][-d <数据节区大小>][-f <文件大小>][-m <内存大小>][-n <文件数目>][-p <缓冲区大小>][-s <堆叠大小>][-t <CPU时间>][-u <程序数目>][-v <虚拟内存大小>]

(b)参数:

  • -a  显示目前资源限制的设定。
  • -c <core文件上限>  设定core文件的最大值,单位为区块。
  • -d <数据节区大小>  程序数据节区的最大值,单位为KB。
  • -f <文件大小>  shell所能建立的最大文件,单位为区块。
  • -H  设定资源的硬性限制,也就是管理员所设下的限制。
  • -m <内存大小>  指定可使用内存的上限,单位为KB。
  • -n <文件数目>  指定同一时间最多可开启的文件数。
  • -p <缓冲区大小>  指定管道缓冲区的大小,单位512字节。
  • -s <堆叠大小>  指定堆叠的上限,单位为KB。
  • -S  设定资源的弹性限制。
  • -t <CPU时间>  指定CPU使用时间的上限,单位为秒。
  • -u <程序数目>  用户最多可开启的程序数目。
  • -v <虚拟内存大小>  指定可使用的虚拟内存上限,单位为KB。

(2)修改core文件大小

ulimit -c 0      # 禁止生成core文件
ulimit -c 100       # 限制core文件大小100块
ulimit -c unlimited # 不限制core文件大小

注:要永久生效则修改配置文件/etc/security/limits.conf,使用类似如下形式进行配置:

*               soft    core            unlimited

(3)生成core文件

(a)通过kill触发生成

# 查看当前core文件大小限制
ulimit -c
# 设置成不限制大小
ulimit -c unlimited
# 再次查看core文件大小限制
ulimit -c# 新启动一个bash进程
bash
# 查看当前bash的pid
echo $$
# 将该进程kill掉,触发core文件生成
kill -s SIGSEGV $$
# 确认core文件确实已经生成
ls

(b)使用gdb直接生成

# 查看当前bash的pid
echo $$
# 通过pid进行gdb调试。为了通用性这里直接使用$$
gdb -p $$
# 生成core文件。在gdb内部输入
generate-core-file
# 退出gdb。在gdb内部输入
quit
# 确认退出gdb。在gdb内部输入
y
# 确认当前目录下有core文件生成
ls -l | grep $$

使用gdb查看core文件即可定位到出错行,如下图。

(c)使用gcore生成

# 直接生成当前bash进程的core文件
gcore $$
# 确认core文件已在当前目录下生成
ls -l | grep $$

12、attach到进程

如果程序已经运行,或者是调试陷入死循环而无法返回控制台进程,可以使用attach命令。

attach pid

通过ps aux可以查看进程的pid,然后使用bt查看栈帧。

以top为例操作步骤为:

ps -aux查看进程pid,为16974.
sudo gdb attach 16974,使用gdb 附着到top命令。

使用bt full查看,当前栈帧。此时使用print等查看信息。

还可以通过info proc查看进程信息。

参考:https://www.cnblogs.com/arnoldlu/p/9633254.html

gdb调试之快速入门相关推荐

  1. [转载].gdb调试器快速入门

    调试在我们编写程序时占有重要的地位.在linux下如何使用gdb调试器?下面采用FQA的方式让你快速了解gdb调试器. 1.如何启动gdb调试器呢? 在终端输入 gdb 程序文件名 即可.注意gdb调 ...

  2. Petalinux快速入门向导 (1) 目录

    目录 Petalinux快速入门向导 (2) 第一章.测试环境和软件下载 第一章. 测试环境和软件下载     1. Ubuntu16.04     2. PetaLinux2020.1 Petali ...

  3. 【软件开发底层知识修炼】十四 快速学习GDB调试一 入门使用

    前面几篇文章学习了链接器相关的内容.现在开始来学习GDB调试.我们的目的是通过这几篇文章将GDB调试完全学会. 文章目录 1 为什么需要GDB 2 GDB 的常规应用 3 GDB调试程序实例 4 总结 ...

  4. 【软件开发底层知识修炼】十九 GDB调试从入门到熟练掌握超级详细实战教程学习目录

    本文记录之前写过的5篇关于GDB快速学习的文章,从第一篇开始学习到最后一篇,保证可以从入门GDB调试到熟练掌握GDB调试的技巧. 学习交流加 个人qq: 1126137994 个人微信: liu112 ...

  5. 【软件开发底层知识修炼】十五 快速学习GDB调试二 使用GDB进行断点调试

    上一篇文章我们学习了使用GDB的最基本方法:[软件开发底层知识修炼]十四 快速学习GDB调试一 入门使用 本篇文章将学习GDB的断点调试.断点调试是一种非常重要的调试方法. 文章目录 1 断点类型 2 ...

  6. gdb调试lua_gdb 调试入门,大牛写的高质量指南

    原标题:gdb 调试入门,大牛写的高质量指南 (点击上方公众号,可快速关注) 来源: 伯乐在线 - 道法子 如需转载,发送「转载」二字查看说明 没想到Brendan Gregg这样的大牛,会写出这样一 ...

  7. JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署...

    接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...

  8. java8生成jsp页面内容组装到jsp中_JAVA WEB快速入门之从编写一个JSP WEB网站了解JSP WEB网站的基本结构、调试、部署...

    接上篇<JAVA WEB快速入门之环境搭建>,在完成了环境搭建后(JDK.Tomcat.IDE),现在是万事具备,就差写代码了,今天就来从编写一个JSP WEB网站了解JSP WEB网站的 ...

  9. .NET Core快速入门教程 5、使用VS Code进行C#代码调试的技巧

    .NET Core 快速入门教程 .NET Core 快速学习.入门系列教程.这个入门系列教程主要跟大家聊聊.NET Core的前世今生,以及Windows.Linux(CentOS.Ubuntu)基 ...

最新文章

  1. 自动化测试测试工具 AirTest 的使用方法与简介
  2. java gpio_Java控制树莓派GPIO口-Pi4J
  3. HTC One 802w(联通双卡版本)刷机过程(只是记录大概的过程,网上已经有各步骤的详细过程)...
  4. 个人作业-Week2:案例分析
  5. java保存图片进度条_Java上传文件进度条的实现方法(附demo源码下载)
  6. 计算机安全可靠替代工程,基于安全可靠软硬件的党政军OA系统的整系统优化方法与研究-计算机技术专业论文.docx...
  7. TP5解析html 回显到页面上
  8. 自学python考哪些证书-学python需要考证吗?考证有什么好处?
  9. 【大数据部落】用R Shiny生态快速搭建交互Web网页APP应用
  10. 永宏plc和台达vfd-m变頻器modbs rtu通讯程序史上最好用的plc和变頻器rtu通讯程序
  11. FLV格式视频转换成MP4格式教程
  12. 闲置路由器做无线打印服务器
  13. 2.4gwifi最高下载速度_2.4g网速(2.4gwifi最高下载速度)
  14. AutoJsPro,猜歌红包群(看广告游戏脚本源码)
  15. 福建农林大学计算机与信息学院副书记,福建农林大学计算机与信息学院导师介绍:钟一文...
  16. 剔除错误匹配算法:RANSAC与MSAC分析
  17. 解决PS内存不足的错误
  18. 【正点原子Linux连载】第十八章 Camera 摘自【正点原子】I.MX6U嵌入式Qt开发指南V1.0.2
  19. 谷歌翻译软件-大家都在下载的谷歌翻译软件
  20. fastdfs 沧海一粟

热门文章

  1. SpringBoot整合Thymeleaf模板引擎以及静态资源的访问
  2. 使用umiJs搭建前端项目添加背景图片
  3. python将panadas写入excel_python pandas写入excel文件的方法示例
  4. 学习ofbiz 订单支付设计
  5. c语言求解三角形的重心,计算几个三角形的重心
  6. PWM开发SG90舵机
  7. 打卡系列-剑指 Offer 62. 圆圈中最后剩下的数字
  8. 现代金融业务--计算题合集(自用,quiz的解答瞎写的)
  9. 网络攻防研究第001篇:尝试暴力破解某高校研究生管理系统学生密码
  10. Remove Assignments to Parameters 移除对参数的赋值