做一个自己的免费网站,怎么用ps切片在dw里做网站,百度指数下载,河源城乡规划建设局网站上一篇文章我们学习了使用GDB的最基本方法#xff1a;【软件开发底层知识修炼】十四 快速学习GDB调试一 入门使用 本篇文章将学习GDB的断点调试。断点调试是一种非常重要的调试方法。 文章目录1 断点类型2 GDB软件断点调试相关操作2.1 通过函数名设置断点2.2 通过文件名行号… 上一篇文章我们学习了使用GDB的最基本方法【软件开发底层知识修炼】十四 快速学习GDB调试一 入门使用 本篇文章将学习GDB的断点调试。断点调试是一种非常重要的调试方法。 文章目录1 断点类型2 GDB软件断点调试相关操作2.1 通过函数名设置断点2.2 通过文件名行号设置断点2.3 其他操作3 GDB硬件断点及其应用4 GDB断点调试实际案例4.1 GDB软件断点调试实际案例4.2 GDB硬件断点调试实际案例5 总结 1 断点类型
在具体学习GDB的断点调试之前先简单了解断点的几种类型 软件断点由非法指令异常实现软件实现适用于在内存中的程序的调试硬件断点由硬件特性实现数量有限适用于FLASH中运行的程序调试数据断点由硬件特性实现数量有限用于监视一段内存该内存中的内容被读或者写该程序就会被停下来 2 GDB软件断点调试相关操作
2.1 通过函数名设置断点
break func_name [if var value] 这种方法设置的断点一直有效程序运行一次后下次运行断点还存在。如果加上后面方括号里面的内容就必须在方括号里面的条件成立的时候才能够暂停程序的执行 tbreak func_name [if var value] 设置的断点只有这一次有效下一次重新运行该程序就没有效果了如果加上后面方括号里面的内容就必须在方括号里面的条件成立的时候才能够暂停程序的执行 2.2 通过文件名行号设置断点
break filen_name:line_num [if var value ] 这种方法设置的断点一直有效程序运行一次后下次运行断点还存在。如果加上后面方括号里面的内容就必须在方括号里面的条件成立的时候才能够暂停程序的执行 tbreak filen_name:line_num [if var value ] 设置的断点只有这一次有效下一次重新运行该程序就没有效果了如果加上后面方括号里面的内容就必须在方括号里面的条件成立的时候才能够暂停程序的执行 2.3 其他操作
上面是软件断点调试时的设置断点的操作。下面再给一个表格看看软件断点调试中的一些其他操作 其中enable 是将断点使能使断点可以使用disable是将断点给暂时关闭但是它还存在不能使用了而已下次想使用的时候不需要在重新打断点直接使用enable使能它即可
还有一些调试时常用的操作
3 GDB硬件断点及其应用 当代码位于只读存储器时FLASH一般在在嵌入式软件开发中用的比较多只能通过硬件断点调试硬件断点需要硬件支持数量有限GDB中通过使用hbreak命令支持硬件断点hbreak与break使用方法完全一样 4 GDB断点调试实际案例
本次调试的程序还是和上一篇文章的程序是一样的
test.c
#include stdio.h
#include unistd.h
extern int* g_pointer;
extern void func();void test_1()
{printf(test_1() : %p\n, test_1);
}void test_2()
{printf(test_2() : %p\n, test_2);
}void test_3()
{printf(test_3() : %p\n, test_3);
}
int main(int argc, char *argv[])
{typedef void(TFunc)();TFunc* fa[] {test_1, test_2, test_3};int i 0;printf(main() : begin...\n);for(i0; iargc; i) //argc代表命令行参数的个数{printf(argv[%d] %s\n, i, argv[i]);}for(i0; i100; i){fa[i%3]();sleep(argc 1); // 如果argc大于1则执行睡眠函数}printf(g_pointer %p\n, g_pointer);func();printf(main() : end...\n);return 0;
}func.c
#include stdio.hint* g_pointer;void func()
{*g_pointer (int)D.T.Software; //注意这里是出错的地方g_pointer是指向0地址但是在这里却对0地址赋值return;
}首先对上述程序编译并且运行gcc func.c test.c -o test.out./test.out毫无疑问程序肯定会产生错误如下图 这是在意料之中的毕竟在func.c程序中我们对0地址进行写内容了。那么现在我们开始使用gdb来定位出错误在开启gdb调试之前需要在编译源程序的时候加上-g选项并将程序的崩溃信息转储的core文件这在【软件开发底层知识修炼】六 Binutils辅助工具之- addr2line与strip工具这篇文章中有讲解过。gcc -g test.c func.c -o test.out //重新编译加上调试信息ulimit -c unlimited //让程序在崩溃时产生core文件./test.out //重新运行看看是否产生core文件 很明显核心已转出生成了core文件----注意这是GDB调试需要用的文件 现在就是出现了段错误我们需要使用GDB的断点调试来找出问题所在。那么我们上面介绍了软件断点调试硬件断点调试下面我们就分别使用软件断点调试与硬件断点调试找出我们程序中出现的问题。
4.1 GDB软件断点调试实际案例
注意下面的调试示例可能过于繁复其实可以一两步就能定位到bug所在但是这里我做的比较多是想借此来学习一些GDB的一些调试手段。 首先按照下图中的命令输入顺序在终端中输入 其中start命令与上一篇文章我们使用过的run命令的区别是start后程序已启动就立马停止GDB会自动在程序开始出打上一个断点。而run命令执行后程序会直接跑起来然后我们使用命令break test.c:37 // 这个命令在test.c的37行打断点使用命令info breakpoints //查看我们的断点数量如下图所示 可以看到有一个断点是刚才我们再test.c程序中37行打的断点。输入continue命令继续执行程序程序肯定会在37行停下来如下图 这很正常因为我们在test.c的37行打了断点。又因为37行是for循环的结尾处所以此时才相当于执行了一次for循环但是还没完全循环一次此时i0。 想要单步执行就继续输入next则程序就会一步一步执行。我们输入了很多个next发现这个for循环一直可以正常执行所以这个for循环肯定是没有问题的。那么我们就不必在for循环内部执行了可以直接将i设置为100执行完for循环。输入命令set var i100.然后输入两次next就跳出了for循环现在已经确定for循环没有产生错误那么段错误就是在for循环之后。for循环之后只有两个printf语句和一个func函数调用。现在我们怀疑是func函数内部出现了段错误。我们在func函数调用所对应的行41行打一个断点tbreak test.c:41然后continue执行执行到func函数时停下来了然后使用jump test.c:45 程序直接正常退出 上述图中没有执行continue。实际需要在打完断点后要执行以下然后再jump从上述结果可以知道除了func函数其他地方都是没有问题的。所以问题应该就是出现在func函数中。 上述是没有调用func函数然后程序正常退出所以我们怀疑是func函数的问题。现在还可以这样我们调用func函数但是不执行func函数体内的代码而是直接强制func函数返回看看会怎么样如下动态图模式 上述动态图只是想展示几个命令的用法~~~~注意学会使用。 4.2 GDB硬件断点调试实际案例
注意下面的调试示例可能过于繁复其实可以一两步就能定位到bug所在但是这里我做的比较多是想借此来学习一些GDB的一些调试手段。
硬件断点调试实际上是与软件断点调试的步骤是一样的只不过使用的是hbreak命令而已。 依次输入 gdb test.outstart 进入到调试模式然后我们想要硬件断点调试就得需要知道硬件我们的系统中有没有硬件断点可以使用。输入show can-use-hw-watchpoints 查看本机是否有硬件断点可以使用。显示如下图 很明显我们有一个硬件断点可以使用。输入hbreak func并查看当前断点个数看我们的断点是否打上了 然后输入continue运行到断点处。然后我们可以查询func函数中的g_pointer的值是多少。发现它是0。也就是0地址。我们在func函数中对0地址进行赋值肯定会产生段错误。我们改变g_pointer的值让它指向一块可读写的堆空间然后再执行程序应该就不会有段错误了。如下图正是我们的操作步骤 至此我们已经找到了导致段错误的原因。实际上是在软件断点调试中找到的大概出错范围是func函数而在硬件断点调试中找到了具体的原因是g_pointer指向0地址但是我们对它进行赋值。我们之所以这么大费周章的使用这么多方法来找出出错的原因纯粹是想学习使用GDB 的更多的调试命令你完全可以几个步骤就找到出错的原因。我们只是为了学习。
5 总结
我们还注意到了一个问题就是在整个调试过程中我们没有修改过一句代码也没有重新编译程序。这样很方便的找到源代码中的问题所在。实在是非常的方便。
学会使用软件断点调试学会使用硬件断点调试
本文章参考狄泰软件学院相关课程 想学习的可以加狄泰软件学院群 群聊号码199546072
学习探讨加个人可以免费帮忙下载CSDN资源 qq1126137994 微信liu1126137994