新建工程
codeblocks的调试功能必须在建立工程的情况下才能使用,接下来一新建一个c++工程为例讲述新建工程的步骤:
- 打开codeblocks
- 点击左上角的File,并选择New->project
- 选择Console application->Go
- 选择语言->Next
- 填写名称和路径->Next
- Finish
添加断点并进行简单调试
这里以一个简单的程序为例:
我们可以用鼠标左键点击行号,或者将光标放到某一行按F5来添加断点:
然后点击这个红色箭头开始调试(快捷键F8)
我们发现黄色的箭头指向第7行,表示程序当前中断在此(黄色箭头指向的语句还未执行)
我们点击Debug->Debugging windows->Watches调成变量查看窗口
现在我们就可以查看各个变量的值了,如果有表格里没有的全局变量,手动添加一下即可,codeblocks的调试功能本质上是GDB的可视化,现在GDB已经支持可以查看STL容器了。
由于黄色箭头指向的语句未被运行,所以此刻的c还是一个“随机数”。
接下来我们介绍控制程序运行的几种方法:
我们现在按下F7(执行一条语句),发现c的值变成了3(执行第7条语句的结果),黄色的箭头指向了第8行。
我们便可以这样一步一步地调试程序。
调试技巧1:条件式断点
接下来我们假装不知道:
∑
i
=
1
n
i
2
=
n
∗
(
n
+
1
)
∗
(
2
∗
n
+
1
)
6
\sum_{i=1}^n i^2=\frac{n*(n+1)*(2*n+1)}{6}
i=1∑ni2=6n∗(n+1)∗(2∗n+1)
我们写了个程序来求1-100的平方和:
然后我们希望循环跑到第98次,也就是i=98时开始调试,那我们应该怎么办呢?
如果我们在第9行设置断点,那么每一层循环我们都会暂停,我们需要用手戳98次才能到i=98的时候,那如果数更大呢?
这显然不是一个解决办法,所以需要引入条件式断点,当某个条件成立是断点才生效。
我们和之前一样在第9行打上断点:
然后选择Debug->Debugging windows ->Breakpoints
找到第9行的断点,右键点击,选择Edit
勾选Break when expression is true:
在下面的框中填入想让断点生效的条件,这里就是i==98(记得是双等号)
然后点击OK
(顺带一提,第二个选项Ignore count :before break的意思是在断点生效前忽略它多少次,当然也可以实现我们这里的功能,但是没有第三个选项灵活多变)
开始调试(F8):
我们惊喜地发现程序在第9行暂停了,并且这个时候i的值等于98
调试技巧2:查看调用栈
接下来我们写了一个递归求阶乘的函数,但是不小心忘记写递归边界了。
那么一旦执行程序就会崩溃。
为了找到错误,我们直接使用F8运行,并且调出Call stack 窗口
Call stack窗口可以显示我们每一层递归调用的情况并且可以在不同的调用层之间切换,我们发现程序中断时n等于一个负的很多的值,于是便找到了错误。
调试技巧3:汇编层面调试
汇编层面调试是指以汇编指令为单元对代码进行调试。
是一种非常底层的调试手段,可以看到内存单元及CPU寄存器中的值。
接下来介绍一下窗口:
CPU Registers:查看CPU寄存器的值
Disassembly:查看对应的汇编代码
Memory dump:查看内存单元
汇编层面的调试和普通的调试几乎一样,只是所观察的不是变量而是具体的内存单元,以汇编指令为单位执行而不是c++语句。
如有其它关于Codeblocks调试的问题,可以在评论区留言,我会进一步补充。