《fortran调试技巧.pdf》由会员分享,可在线阅读,更多相关《fortran调试技巧.pdf(4页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、功能强大的 vc6 调试调试器(适用于 Compaq FortranFortran Debug)作者:yy2better要成为一位优秀的软件工程师,调试调试能力必不可缺。本文将较详细介绍VC6 调试调试器的主要用法。windows 平台的调试调试器主要分为两大类:1 用户模式(user-mode)调试调试器:它们都基于 win32 Debugging API,有使用方便的界面,主要用于调试调试用户模式下的应用程序。这类调试调试器包括 VisualC+调试调试器、WinDBG、BoundChecker、Borland C+Builder 调试调试器、NTSD 等。2 内核模式(kernel-mo
2、de)调试调试器:内核调试调试器位于 CPU 和操作系统之间,一旦启动,操作系统也会中止运行,主要用于调试调试驱动程序或用户模式调试调试器不易调试调试的程序。这类调试调试器包括 WDEB386、WinDBG 和 softice 等。其中 WinDBG和 softice 也可以调试调试用户模式代码。国外一位调试调试高手曾说,他 70调试调试时间是在用 VC+,其余时间是使用WinDBG 和 softice。毕竟,调试调试用户模式代码,VC6 调试调试器的效率是非常高的。因此,我将首先在本篇介绍 VC6 调试调试器的主要用法,其他调试调试器的用法及一些调调试试技能在后续文章中阐述。一 位置断点(L
3、ocation Breakpoint)大家最常用的断点是普通的位置断点,在源程序的某一行按 F9 就设置了一个位置断点。但对于很多问题,这种朴素的断点作用有限。譬如下面这段代码:void CForDebugDlg:OnOK()for(int i=0;i 1000;i+)/A intk=i*10-2;/B SendTo(k);/C int tmp=DoSome(i);/D int j=i/tmp;/E 执行此函数,程序崩溃于 E 行,发现此时 tmp 为 0,假设 tmp 本不应该为 0,怎么这个时候为 0 呢?所以最好能够跟踪此次循环时 DoSome 函数是如何运行的,但由于是在循环体内,如果
4、在 E 行设置断点,可能需要按 F5(GO)许多次。这样手要不停的按,很痛苦。使用 VC6 断点修饰条件就可以轻易解决此问题。步骤如下。1 Ctrl+B 打开断点设置框,如下图:Figure 1 设置高级位置断点2 然后选择 D 行所在的断点,然后点击 condition 按钮,在弹出对话框的最下面一个编辑框中输入一个很大数目,具体视应用而定,这里 1000 就够了。3 按 F5 重新运行程序,程序中断。Ctrl+B 打开断点框,发现此断点后跟随一串说明:.487 times remaining。意思是还剩下 487 次没有执行,那就是说执行到 513(1000487)次时候出错的。因此,我们
5、按步骤 2 所讲,更改此断点的 skip 次数,将 1000 改为 513。4 再次重新运行程序,程序执行了 513 次循环,然后自动停在断点处。这时,我们就可以仔细查看 DoSome 是如何返回 0 的。这样,你就避免了手指的痛苦,节省了时间。再看位置断点其他修饰条件。如Figure 1所示,在“Enter the expressionto be evaluated:”下面,可以输入一些条件,当这些条件满足时,断点才启动。譬如,刚才的程序,我们需要 i 为 100 时程序停下来,我们就可以输入在编辑框中输入“i=100”。另外,如果在此编辑框中如果只输入变量名称,则变量发生改变时,断点才会启
6、动。这对检测一个变量何时被修改很方便,特别对一些大程序。用好位置断点的修饰条件,可以大大方便解决某些问题。二 数据断点(Data Breakpoint)软件调试调试过程中,有时会发现一些数据会莫名其妙的被修改掉(如一些数组的越界写导致覆盖了另外的变量),找出何处代码导致这块内存被更改是一件棘手的事情(如果没有调试调试器的帮助)。恰当运用数据断点可以快速帮你定位何时何处这个数据被修改。譬如下面一段程序:#include stdafx.h#include int main(int argc,char*argv)charszName110;char szName24;strcpy(szName1,s
7、henzhen);printf(%sn,szName1);/A strcpy(szName2,vckbase);/B printf(%sn,szName1);printf(%sn,szName2);return 0;这段程序的输出是szName1:shenzhen szName1:ase szName2:vckbase szName1 何时被修改呢?因为没有明显的修改 szName1 代码。我们可以首先在 A 行设置普通断点,F5运行程序,程序停在 A 行。然后我们再设置一个数据断点。如下图:Figure 2 数据断点F5 继续运行,程序停在 B 行,说明 B 处代码修改了 szName1。B
8、 处明明没有修改 szName1 呀?但调试调试器指明是这一行,一般不会错,所以还是静下心来看看程序,哦,你发现了:szName2 只有 4 个字节,而 strcpy 了 7 个字节,所以覆写了 szName1。数据断点不只是对变量改变有效,还可以设置变量是否等于某个值。譬如,你可以将 Figure 2 中红圈处改为条件”szName20=y“,那么当szName2 第一个字符为 y 时断点就会启动。可以看出,数据断点相对位置断点一个很大的区别是不用明确指明在哪一行代码设置断点。三 其他1 在 call stack 窗口中设置断点,选择某个函数,按 F9 设置一个断点。这样可以从深层次的函数调
9、用中迅速返回到需要的函数。2 Set Next StateMent 命令(debug 过程中,右键菜单中的命令)此命令的作用是将程序的指令指针(EIP)指向不同的代码行。譬如,你正在调试调试上面那段代码,运行在 A 行,但你不愿意运行 B 行和 C 行代码,这时,你就可以在 D 行,右键,然后“Set Next StateMent”。调试调试器就不会执行 B、C 行。只要在同一函数内,此指令就可以随意跳前或跳后执行。灵活使用此功能可以大量节省调试调试时间。3 watch 窗口watch 窗口支持丰富的数据格式化功能。如输入 0 x65,u,则在右栏显示101。实时显示 windows API 调用的错误:在左栏输入err,hr。在 watch 窗口中调用函数。提醒一下,调用完函数后马上在 watch 窗口中清除它,否则,单步调试调试时每一步调试调试器都会调用此函数。4 messages 断点不怎么实用。基本上可以用前面讲述的断点代替。总结调试调试最重要的还是你要思考,要猜测你的程序可能出错的地方,然后运用你的调试调试器来证实你的猜测。而熟练使用上面这些技巧技巧无疑会加快这个过程。最后,大家如果有关于调试调试方面的问题,我乐意参与探讨。
限制150内