Linux系统篇,开发工具(六):文件的编译配置、调试的理解、cgdb和gdb的操作使用 系列文章目录第三章 开发工具的认识与使用文章目录系列文章目录[TOC](文章目录)前言一、文件的编译1.1 debug 配置1.2 release 配置二、Linux 文件调试三、程序调试器gdb3.1 认识gdb3.2 cgdb的使用3.2.1 基本操作3.2.2 断点和运行操作3.2.2.1 断点信息3.2.2.2 断点操作3.2.2.3 运行操作3.2.2.4 其他操作四、gdb的调试技巧4.1 watch 监视变量变化4.2 set var 修改运行时变量4.3 条件断点4.3.1 新建条件断点4.3.2 断点新增条件4.4 分屏操作总结前言在Linux当中我们也会遇到代码中的bug那此时我们就渴望像vs当中一样可以对代码进行调试因此本节我们就来学习在Linux当中代码的调试工具的使用——gdb。一、文件的编译文件源码编译成可执行文件的过程中可以分为两种编译模式debug模式和release模式因此形成的不同文件也就具有对应的特点。1.1 debug 配置debug配置是编译器的一套编译规则由该配置产出的文件可以进行调试常用于开发中的测试它决定了该文件在编译过程中细节的处理定义Debug 配置编译的程序包含完整的符号调试信息不启用代码优化作用专门给开发者写代码、找 bug、测试功能用的模式特点不做代码优化在该配置下形成的程序在执行时不会进行优化代码即对代码的增删改操作如省略中间变量保留完整调试信息编译时会把变量名、函数名、代码行号、注释关联信息全部打包进 exe调试符号内存检查宽松一些轻微内存错误比如越界、野指针Debug 能勉强运行Release 直接崩溃1.2 release 配置该配置为开发后发布客户端所使用的它有着以下的细节定义Release 配置编译的程序启用完整代码优化不包含调试符号信息如需事后调试可单独生成 .pdb 调试文件作用代码完全写完、无 bug 后打包给别人运行、作业提交、软件发布用的模式特点度代码优化编译器自动提速编译器会自动删除没用的代码、变量合并重复逻辑精简运算步骤调整代码顺序提升运行速度删除全部调试信息去掉变量名、行号、断点信息无法调试只能直接运行内存检查严格Debug 能运行的轻微 bugRelease 会直接闪退、崩溃因为优化会暴露内存问题二、Linux 文件调试就如同上述所说的文件只有通过debug配置编译才能对代码进行调试。而Linux中编译而成的文件默认是release 版本本质是gcc 和 g 编译时默认选择的是该配置。想要配置为debug版本就需要通过选项改变gcc mycmd.c -o mycmd-g通过该选项实现编译成可调试文件而文件调制的本质无非三点找到问题通过断点将代码分块以块为单位快速排查问题查看代码上下文在找到问题后对代码块的代码详细运行查看分为逐语句和逐过程当然还可以使用监视窗口查看变量的变化解决问题根据所学知识修改和优化问题代码通过以上调试的过程成功实现问题的查找和解决。三、程序调试器gdb3.1 认识gdbGDB是一款用于调试可执行程序的调试器工具直接使用命令gdb 可执行文件来调试文件进入调试界面是这样的情况我们就可以通过在此处进行对文件的调试可以实现初步的调试功能打断点、单行运行、过程运行等但是这样我们都无法看到现在执行的代码和运行的情况因此我们推荐使用cgdb这个工具是gdb的加强升级版使用方式为cgdb 可执行文件不是系统自带需要安装centossudo yum install -y cgdbubuntusudo apt-get install -y cgdb通过cgdb我们就能在调试时看到代码和运行到的进程了。3.2 cgdb的使用Linux作为命令行操作它的应用程序也离不开命令行所以让我们来学习下cgdb的命令使用。3.2.1 基本操作基本操作涉及cgdb的进入、退出等不涉及具体使用的操作编号命令作用1cgdb 可执行文件(debug)进入cgdb界面2quit退出cgdb3list / l 源代码显示文件的源代码后加:数字从代码第几行开始显示3.2.2 断点和运行操作调式的实现离不开断点的使用以及运行方法。通过合适的断点分块和判断运行过程还是语句实现问题的查找3.2.2.1 断点信息断点就是你让程序停下来的标记是调试cgdb/gdb最核心的功能。当然系统为了区分不同的断点给断点设置了不同的信息我们使用命令info b进行查看让我们先来认识以下断点信息都有哪些Num断点编号每个断点都有自己的编号并且编号是逐渐递增的即使删除1号新增也是4号不退出情况Type断点类型断点分为五个类型常用为breakpoint普通断点、watchpoint观察断点Disp断点存活方式keep 永久有效不会自动删除还有tbreak临时断点Enb是否启用y 启用n 禁用Address内存地址代码在内存里的位置不用管What断点位置哪个文件、第几行、哪个函数下面会对某些信息做详细解释。3.2.2.2 断点操作编号命令作用1b / break 数字在该程序的第几行打断点b 文件行号在对应的文件行打断点b 文件函数在对应的文件该函数处打断点2info b查看断点信息3d 断点编号删除相应编号的断点4disable / enable 断点编号禁用 / 启用 对应的断点编号3.2.2.3 运行操作编号命令作用1run / r运行程序直到遇到断点或程序结束2next / n逐过程运行将函数调用视为一个整体步骤执行例如直接执行完整个函数不进入其内部3step / s逐语句运行gdb记录最新的一条输入语句4finsh直接执行完当前函数5c直接由上一断点运行到下一断点6until 行号快速执行到第几行3.2.2.4 其他操作我们来讲解以下除了以上调试功能外的常用其他操作bt查看代码的调用栈我们会遇到这样一个情况在函数调用返回值的时候需要使用两次n才能运行到下一行。这是因为返回值是函数的一个临时变量需要mov操作将该变量赋值给变量所以使用函数赋值做了两件事callq 和 mov。p查看变量的值在调试过程中查看当前的变量存储的数据值。还可以充当临时计算的工具display / undisplay加入 / 删除 监视变量通过常显示来显示每一步变量的变化情况便于查看代码上下文info locals查看现在执行代码块中的临时变量及变量的值四、gdb的调试技巧4.1 watch 监视变量变化在display的监视功能的基础上新增了变量的变化信息当变量存储数据改变时列出新老数据用法watch 变量新增监视变量d 变量删除监视变量功能如果你有⼀些变量不应该修改但是你怀疑它修改导致了问题你可以watch它如果变化了就会通知你4.2 set var 修改运行时变量我们常常会遇到发现变量异常此时我们需要退出调试并重新设值再次运行才能继续。而set var这个命令就可以在运行时直接修改变量用法set var flag 1修改运行程序中的变量功能不用改代码、不用重新编译直接在命令行改变量的值。4.3 条件断点4.3.1 新建条件断点创建一个带有条件实现的断点实现如达到目标循环次数时停止运行用法b 行号 条件满足条件时触发断点。如b 6 if i 84.3.2 断点新增条件为已有的断点新增运行条件用法condition 断点编号 条件为已存断点新增满足条件。如condition 6 if i 84.4 分屏操作cgdb还可以通过Esc分屏进入到代码文件当中操作i从代码屏回到调试窗口。总结本章的开发工具到本节就结束了下一章我们将学习到Linux底层的东西感谢您的阅读期待下一次的学习。