调试程序的简单说明
如何调试程序

• 数据类型错误
• 输出格式错误
• 忘记删除用于输出调试信息的语句
如何让你的代码更漂亮
• 养成一个好的编程习惯 • 学会去优化自己的模板 • 合理使用宏定义
• 将执行不同功能的程序写在不同的函数中, 最后在主函数中调用 • 合理使用函数库和类模板
4、构造测试数据和测试程序
• 在题目中所给出的测试样例只是一小组测试数据,这虽然通常 是我测试数据,尤其是一些边界状态 的测试数据(数据极大、数据极小、数据量极多、数据量极少、 预期出现极端结果等情况)。 • 边界测试数据可以用于检查程序中是否存在边界错误,设计有 缺陷的程序,在处理边界测试数据时往往容易暴露出错误。但 如果没有发生明显的运行错误,就需要对结果的正确性进行验 证。 • 有些测试数据可以通过手工计算求出结果,再与程序的计算结 果相对比,而也有些问题,可以通过构造测试程序来进行验证。 • 测试程序通常是用确定可靠的算法编写的解题程序,但不须考 虑时间和空间的消耗,用测试程序对测试数据进行求解,用计 算结果与待测试程序的计算结果进行对比。 • 随机生成数据+文件对拍
• • • • •
方法二:利用文件输入输出 对于输入文件 freopen(“文件名”,”r”,stdin); 对于输出文件 freopen(“文件名”,”w”,stdout);
2、输出调试信息
• 在调试时,很多同学往往首先想到的是使用开发环境所提供的 调试功能:设置断点、单步执行、查看和修改变量,甚至改变 程序的流程。不可否认,使用开发环境所提供的调试功能的确 很方便,但当你过分依赖于这些集成工具时,你可能忽略了很 多更有效的手段:仔细地分析、充分的信息。 • 当我们发现程序没有按照自己预期得那样工作时,不要急于跟 踪甚至修改程序,而是应该首先仔细对程序的逻辑、语句、表 达式进行检查和分析,尽可能使程序在表达上更简洁、更干净。 如果实在难以发现问题所在,也不必急于借助于集成工具去跟 踪程序的运行。早期的程序员在调试程序时经常会在程序中加 入输出调试信息的语句或过程,用以观察程序的运行过程,分 析程序的运行逻辑,这种调试手段即使在今天也仍然是非常有 效的。 • 输出的调试信息要尽量容易阅读,格式清楚,在必要的时候, 可以借助工具程序或自己编写的程序对输出信息进行处理,以 帮助分析问题。
关于C语言程序的调试

Courseware template
使用此按钮, 运行到断点处.
On the evening of July 24, 2021
Courseware template
在变量窗口发现 sum的值有问题
这时应想到是变 量没赋初值。
注:如果程序代码多,可设多个断点,。
On the evening of July 24, 2021
On the evening of July 24, 2021
调试示例:
Courseware template
求二数的最小公倍数和最大公约数.
#include<stdio.h>
void main()
{ int m,n,j,k;
printf("input m,n:\n");
scanf("%d%d",&m,&n);
Courseware template
单击终止调试(Stop Debuging),仔细分析. 循环条件改为(j%n=0)
重新运行程序: Input m n: 3 7(回车)
输出结果: 最小公倍数是:21 最大公约数:1
On the evening of July 24, 2021
Courseware template
Courseware template
On the evening of July 24, 2021
Courseware template
1.使用此按钮(run to cursor), 运行到光标处. 2.输入数据后, 运行到光标处.
On the evening of July 24, 2021
Courseware template
CSS-100BE稳控新平台通用调试程序使用说明(0SF.457.042)_V1.0

CSS-100BE数字式安全稳定控制装置通用调试程序使用说明CSS-100BE数字式安全稳定控制装置通用调试程序使用说明编制:雷瑞丰校核:牛胜南标准化审查:李连昌审定:李哲出版号:V1.00文件代号:0SF.457.042出版日期:2012年2月目录第 1 篇概述 (2)1.1程序功能概述 (2)1.2硬件配置情况 (2)第 2 篇使用说明 (3)2.1程序下载说明 (3)2.2装置参数固化 (3)2.3测试项目 (6)2.3.1模拟量测试 (6)2.3.2开入测试 (6)2.3.3开出测试 (7)2.3.4187C通道测试 (8)第 3 篇常见问题汇总 (8)第 1 篇概述1.1程序功能概述本调试程序是CSS-100BE装置的专用调试程序,主要功能是对CSS-100BE 装置的硬件进行测试。
由于稳控工程的特殊性,绝大多数的稳控工程的功能都是定制的,每个稳控工程的CSS-100BE机箱个数,交流插件个数,开入插件个数,开出插件个数都不尽相同,因此就需要有一套程序能够对任意个数的机箱、交流插件、开入插件、开出插件都适用,但是又不必要有具体的功能,只需要对硬件进行测试即可。
故此本调试程序应运而生。
1.2硬件配置情况调试程序对交流插件、CPU插件、开入插件、开出插件都做了最大化配置,最多可以实现个机箱(即6个CPU),18块交流插件(每个机箱最多3块)、6块开入插件、7块开出插件(含一块信号插件)。
为了清楚起见,下面列表说明。
由于每个机箱里只放一块CPU插件,即机箱与CPU插件是一对一的,因此下面的内容中的机箱和CPU的个数相同,只列出CPU个数。
针对不同的工程的不同插件个数,可以通过装置参数来整定,使用方法详见下面章节说明。
CPU插件交流插件开入插件开出插件最少 1 0 1 1最多 6 18 6 7第 2 篇使用说明2.1程序下载说明本套调试程序有2个固化程序,主机专用一个固化程序。
所有的从机使用一个固化程序。
控制器程序调试说明书

控制器程序调试说明书一、引言控制器程序是现代工厂中自动化设备的核心,控制器程序质量的好坏将直接影响设备的性能和生产效率。
因此,为了确保自动化设备的正常运行,必须对控制器程序进行调试。
二、调试前的准备工作在进行控制器程序调试前,需要做好以下准备工作:1.确认控制器型号及接口特性,了解设备的具体工作流程。
2.确认所使用软件版本和硬件版本,确保软、硬件的相容性。
3.根据设备的工作流程,编写出详细的测试用例,包括正常情况下的工作流程和异常情况下的处理方案。
4.准备好必要的测试工具和设备,如逻辑分析仪、示波器等。
三、调试步骤按照以下步骤进行控制器程序调试:1.连接设备并配置环境根据控制器型号和接口特性,将设备与计算机连接,并配置好开发环境。
在这个步骤中需要注意软硬件版本的相容性,避免由于版本不兼容造成的问题。
2.对控制器程序进行编译和下载在编译之前,需要检查程序代码是否符合编译要求,包括语法、变量命名等方面。
编译完成后,将程序下载至控制器中。
3.测试程序功能根据准备好的测试用例,进行程序功能测试。
测试过程中需要注意数据的正确性和程序对异常的处理能力。
4.性能测试针对程序的性能指标,进行性能测试。
例如,测试程序的响应时间、稳定性等。
测试过程中需要模拟真实环境,提高测试的可靠性。
5.问题分析与解决根据测试结果,对程序中存在的问题进行分析,并制定相应的解决方案。
在解决问题时需要考虑工厂生产的实际情况,并及时向生产部门汇报。
避免在生产中出现问题。
四、注意事项在控制器程序调试过程中,需要注意以下事项:1.严格按照测试用例进行测试,确保测试的全面性和可靠性。
2.避免调试过程中对程序进行随意修改。
如需进行修改,应当经过论证和审核,并记录修改的内容与原因。
五、总结本文简述了控制器程序调试的基本步骤和注意事项,希望读者能够在进行调试前做好充分的准备工作,确保调试的顺利进行,并在生产过程中避免控制器程序带来的影响。
c语言程序调试的方法

c语言程序调试的方法C语言是一种广泛应用的编程语言,但是在写程序的过程中难免会遇到各种错误和bug。
为了解决这些问题,程序调试是必不可少的环节。
本文将一步一步介绍C语言程序调试的方法,帮助读者更好地定位和修复错误。
一、理解程序调试概念及重要性(100-200字)程序调试是指通过识别、定位和修复软件中的错误(也称为缺陷或bug)来确保程序的正确运行。
调试是开发过程中的重要环节,它不仅可以解决已知的错误,还可以帮助我们理解代码和程序的执行过程。
在大型项目中,调试能够提高开发效率,降低错误的出现频率。
二、确定调试目标(200-300字)在开始调试之前,我们首先需要明确调试的目标是什么。
这有助于我们有条不紊地进行调试,并有效地利用时间。
调试目标可以是识别特定的错误、改进程序的性能或验证代码行为的正确性。
确定了调试目标后,我们就可以有针对性地采取相应的调试方法来达到目标。
三、检查代码和数据(200-300字)一旦我们明确了调试目标,下一步是检查代码和数据。
这个过程主要包括以下几个方面:1. 语法检查:通过编译器进行语法检查可以找到一些常见的语法错误,如括号不匹配、缺失分号等。
2. 变量和常量检查:检查变量和常量的命名是否规范、是否被正确初始化和赋值。
同时也要注意无效的内存引用、数组溢出等问题。
3. 函数调用:检查函数调用是否正确、参数是否传递正确,以及返回值是否被正确处理。
4. 数据流分析:通过追踪代码的执行过程,观察数据在程序中的流动,找出可能的错误。
通过仔细检查代码和数据,我们可以尽早发现问题,提高调试的效率。
四、使用调试工具(300-400字)在调试过程中,我们可以使用一些专门的调试工具来帮助我们定位和解决问题。
常用的调试工具有:1. 编译器提供的调试信息:在编译时,可以通过开启调试信息选项来生成包含调试信息的可执行文件。
在调试过程中,我们可以使用调试器来查看代码的执行过程、变量的值以及函数的调用关系,帮助我们定位问题所在。
程序调试的常用方法

程序调试的常用方法程序调试是软件开发中非常重要的一环,它可以帮助开发人员找出程序中的错误并进行修复,从而保证程序的正常运行。
在实际的开发过程中,程序调试的方法有很多种,下面将介绍一些常用的调试方法。
1. 打印调试信息打印调试信息是最常用的调试方法之一。
开发人员可以在程序中添加一些打印语句,输出程序中的变量值、函数调用信息等,以便于观察程序的执行过程。
在调试完成后,可以将这些打印语句删除或注释掉,以避免影响程序的性能。
2. 使用调试工具调试工具是一种专门用于调试程序的软件,它可以帮助开发人员快速定位程序中的错误。
常见的调试工具有Visual Studio、Eclipse、Xcode等。
这些工具可以提供调试器、断点调试、内存泄漏检测等功能,大大提高了调试效率。
3. 单元测试单元测试是一种测试方法,它可以对程序中的每个模块进行测试,以确保程序的每个部分都能正常运行。
在单元测试中,开发人员可以编写一些测试用例,对程序进行测试,并查找错误。
单元测试可以帮助开发人员快速定位错误,并提高程序的可靠性。
4. 代码审查代码审查是一种通过检查代码来发现错误的方法。
在代码审查中,开发人员可以通过查看代码、注释、变量名等来发现潜在的错误。
代码审查可以帮助开发人员发现一些常见的错误,如语法错误、逻辑错误等。
5. 日志记录日志记录是一种记录程序运行过程的方法。
在程序中添加日志记录语句,可以记录程序中的变量值、函数调用信息等,以便于观察程序的执行过程。
在调试完成后,可以将这些日志记录语句删除或注释掉,以避免影响程序的性能。
总之,程序调试是软件开发中非常重要的一环,它可以帮助开发人员找出程序中的错误并进行修复,从而保证程序的正常运行。
在实际的开发过程中,开发人员可以根据实际情况选择不同的调试方法,以提高调试效率。
K1000TII标准程序调试参数说明

K1000T标准程序调试相关参数表;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PLC记忆型控制继电器信号定义;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SKEY_K = K0.7 ;选择X3.0功能; 1-程序开关;0-主轴暂停开关MST_K = K0.6 ;禁止X3.1为循环启动开关; 1-禁止;0-有效MSP_K = K0.5 ;禁止X3.2为暂停开关; 1-禁止;0-有效MOT_K = K0.4 ;选择是否检查硬限位1:不检查MESP_K = K0.3 ;禁止急停功能; 1-禁止;0-有效MESP3_K = K0.2 ;禁止X4.7为急停开关3; 1-禁止;0-有效MESP2_K = K0.1 ;禁止X3.3为急停开关2; 1-禁止;0-有效MESP1_K = K0.0 ;禁止X2.4为急停开关1; 1-禁止;0-有效ZDIL_K = K1.6 ;选择主轴制动时是否互锁进给轴AGIM_K = K1.4 ;主轴档位反馈信号有效电平;1:高电平;0:低电平AGIN_K = K1.3 ;自动换档时;是否检查档位反馈信号;1:检查;0:不检查AGST_K = K1.2 ;自动换档时;是否需要手动参与;1:需要手工换档并且再次按下启动键AGEARM_K = K1.1 ;选择主轴通过M指令换档1:M指令换档;0:根据S命令自动换档AGEAR_K = K1.0 ;选择主轴自动换档或者手动换档MZRNX_K = K2.5 ;选择回零按键方向MZRNZ_K = K2.4 ;选择回零按键方向ZLOK_K = K2.3 ;选择回零按键自保持RH_AUTO_K = K2.1 ;选择自动润滑机能MPLS_K = K3.7 ;M代码脉冲输出SUOS_K = K3.6 ;选择宏输出功能1:S1-S8为宏输出;0:MNOUT_K = K3.5 ;选择工件计数到达输出机能SAGT_K = K3.4 ;选择防护门有效电平;1:低电平防护门关闭;0:高电平防护门关闭SSGT_K = K3.3 ;选择防护门机能1:有效0:无效TPLS_K = K3.2 ;台尾控制0-输出电平;1-输出脉冲;QPLS_K = K3.1 ;卡盘控制0-输出电平;1-输出脉冲;QPIN_K = K3.0 ;卡盘控制0-不检查卡紧信号;1-检查卡紧信号;TCKI_K = K4.7 ;选择刀位反馈信号检查TTYP_K = K4.6 ;选择刀架类型0:宏达转塔刀架;1:亚兴液压刀架RVX_K = K4.5 ;后刀架机能选择1:选择后刀架TSGN_K = K4.4 ;宏达刀架到位信号电平类型;0:高电平常开;1:低电平常闭TCPS_K = K4.3 ;宏达刀架锁紧信号电平类型;0:低电平常闭;1:高电平常开TTYP_SUP_K = K4.2 ;六鑫亚兴液压刀架的选择TTYP_K=0;TTYP_SUP_K=1:表示选择六鑫刀架;TTYP_K=1;TTYP_SUP_K=1:表示选择亚兴刀架QPTYP_K = K4.1 ;卡盘类型选择;0:外卡盘; 1:内卡盘QPSL_K = K4.0 ;卡盘机能是否有效;0:无效;1:有效MOV_HOT_K = K5.4 ;屏蔽环球刀架电机过热报警;1:屏蔽EHOF_K = K5.3 ;选择外部手轮时;面板手轮方式是否有效..0:无效1:有效HPG_K = K5.2 ;选择外部手轮OV_EXT_ACT_K = K5.0 ;选择外部倍率开关;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PLC数据表信号定义;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;TOOL_TOL_D = D7 ;总刀具数T_POSCTR_CONST_D = D8 ;刀位旋转计数设定值T_POSCTR_CONST1_D = D9T_POSCTR_V AL_D = D12 ;刀位旋转计数当前值;;;;;;;;;;;;;SPCNT 参数区域LOWER_SPA_LIMIT_D = D32 ;D32-D35 主轴最小模拟量输出UPER_SPA_LIMIT_D = D36 ;D36-D39 主轴最大模拟量输出;最大设定为4095 MAX1_SP_LIMIT_D = D40 ;D40-D43 主轴1档最大速度;每档实际的最大速度受UPER_SPA_LIMIT_D限制MAX2_SP_LIMIT_D = D44 ;D44-D47 主轴2档最大速度;每档实际的最大速度受UPER_SPA_LIMIT_D限制MAX3_SP_LIMIT_D = D48 ;D48-D51 主轴3档最大速度;每档实际的最大速度受UPER_SPA_LIMIT_D限制MAX4_SP_LIMIT_D = D52 ;D52-D55 主轴4档最大速度;每档实际的最大速度受UPER_SPA_LIMIT_D限制SOR_SP_D = D56 ;D56-D59 主轴换档低速MCNO_D = D60 ;D60-D63 加工件计数MCNO_D1 = D64 ;D64-D67 加工到达计数MCNO_D2 = D68 ;D68-D71 加工到达设定值;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;PLC定时器定义;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;T_MCODE = T00 ;M代码执行时间定时器T_SCODE = T01 ;S代码执行时间定时器T_TCODE = T02 ;T代码执行时间定时器T_CNG = T03 ;换刀过程定时器T_PSW = T04 ;压力不足延时T_RHON = T05 ;自动润滑打开时间定时器T_RHOFF = T06 ;自动润滑关闭时间定时器T_SP_T1 = T07 ;互锁开始到主轴停止输出的延时T_SP_T2 = T08 ;主轴停止输出到主轴制动输出的延时T_SP_T3 = T09 ;主轴制动输出到互锁解除的延时T_AGEAR1 = T10 ;主轴换档定时器1T_AGEAR2 = T11 ;主轴换档定时器2T_QP = T12 ;卡盘脉冲宽度T_TW = T13 ;台尾脉冲宽度T_MPLS = T14 ;M代码脉冲输出宽度T_CW_CCW = T15 ;宏达转塔刀架;正转停止到反转锁紧输出的延迟时间T_POK_TCP = T16 ;宏达转塔刀架;刀架到位到锁紧到位的允许时间T_TCP_CCWE = T17 ;宏达转塔刀架;刀架锁紧到位到反转锁紧停止的延迟时间T_VOI = T18 ;外部蜂鸣器输出定时器。
调试说明书

调试说明书调试说明书一、概述本文档旨在为开发人员提供一份详细的调试说明书,以帮助他们在开发过程中快速解决问题和调试代码。
本文档将介绍调试的基本原则和常用的调试工具、技术和方法。
二、调试原则在进行调试之前,需要掌握以下几个基本原则:1. **定位问题**:了解出现问题的具体现象,并找到问题的根本原因。
不要只满足于修复表面问题,要深入分析和理解问题。
2. **减少复杂性**:在进行调试时,尽量在简化环境的前提下进行。
减少可能导致问题的复杂性,只保留必要的条件。
3. **有序逐步调试**:从简单的场景开始,逐步添加复杂性。
每次添加后,测试代码是否能够正常运行,这样可以快速定位问题所在。
4. **记录、分析和总结**:在调试过程中,记录每个步骤和结果。
分析和总结问题,形成调试经验和能力。
三、调试工具与技术1. 调试器调试器是调试代码最常用的工具之一,它可以帮助开发人员跟踪代码的执行过程、查看变量的值、设置断点、单步调试等。
常见的调试器有GDB、LLDB、Chrome开发者工具等。
2. 日志和调试信息使用日志和调试信息是调试代码的常用方法之一。
通过在代码中插入日志和调试信息,可以在运行过程中观察代码的执行顺序、变量的值等。
3. 单元测试单元测试是一种自动化测试方法,可以帮助开发人员验证代码的正确性。
在调试过程中,通过编写单元测试用例来模拟和验证问题场景,可以更好地理解问题的本质原因。
4. 远程调试远程调试是在开发人员的本地环境中调试远程运行的代码。
通过远程调试工具,可以在本地环境下调试远程服务端的代码。
四、调试方法1. 分析代码逻辑首先要仔细分析代码逻辑,了解代码的运行过程和各个模块之间的关系。
可以通过代码审查、阅读文档和咨询他人来获取更多的信息。
2. 使用调试器使用调试器可以逐行跟踪代码的执行过程,查看变量的值和修改状态。
可以设置断点,在代码执行到指定位置时暂停执行,并进行进一步的调试操作。
3. 日志调试在关键的代码段中插入调试信息和日志输出语句,以便观察代码的执行流程和变量的值。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
难怪很多前辈说调试是一个程序员最基本的技能,其重要性甚至超过学习一门语言。
不会调试的程序员就意味着他即使会一门语言,却不能编制出任何好的软件。
我以前接触的程序大多是有比较成形的思路和方法,调试起来出的问题都比较小,最近这个是我自己慢慢摸索调试,接触了很多新的调试方法,并查了很多前辈的总结,受益匪浅,总结以前的和新的收获如下:VC调试篇设置为了调试一个程序,首先必须使程序中包含调试信息。
一般情况下,一个从AppWizard创建的工程中包含的Debug Configuration自动包含调试信息,但是是不是Debug版本并不是程序包含调试信息的决定因素,程序设计者可以在任意的Configuration中增加调试信息,包括Release版本。
为了增加调试信息,可以按照下述步骤进行:∙打开Project settings对话框(可以通过快捷键ALT+F7打开,也可以通过IDE菜单Project/Settings打开)∙选择C/C++页,Category中选择general ,则出现一个Debug Info下拉列表框,可供选择的调试信息方式包括:∙选择Link页,选中复选框"Generate Debug Info",这个选项将使连接器把调试信息写进可执行文件和DLL∙如果C/C++页中设置了Program Database以上的选项,则Link incrementally可以选择。
选中这个选项,将使程序可以在上一次编译的基础上被编译(即增量编译),而不必每次都从头开始编译。
调试方法:1、使用 Assert(原则:尽量简单)assert只在debug下生效,release下不会被编译。
2、防御性的编程3、使用Trace4、用GetLastError来检测返回值,通过得到错误代码来分析错误原因5、把错误信息记录到文件中位置断点(Location Breakpoint)大家最常用的断点是普通的位置断点,在源程序的某一行按F9就设置了一个位置断点。
但对于很多问题,这种朴素的断点作用有限。
譬如下面这段代码:void CForDebugDlg::OnOK(){for (int i = 0; i < 1000; i++) //A{int k = i * 10 - 2; //BSendTo(k); //Cint tmp = DoSome(i); //Dint j = i / tmp; //E}}执行此函数,程序崩溃于E行,发现此时tmp为0,假设tmp本不应该为0,怎么这个时候为0呢?所以最好能够跟踪此次循环时DoSome函数是如何运行的,但由于是在循环体内,如果在E行设置断点,可能需要按F5(GO)许多次。
这样手要不停的按,很痛苦。
使用VC6断点修饰条件就可以轻易解决此问题。
步骤如下。
1 Ctrl+B打开断点设置框,如下图:Figure 1设置高级位置断点2 然后选择D行所在的断点,然后点击condition按钮,在弹出对话框的最下面一个编辑框中输入一个很大数目,具体视应用而定,这里1000就够了。
3 按F5重新运行程序,程序中断。
Ctrl+B打开断点框,发现此断点后跟随一串说明:...487 times remaining。
意思是还剩下487次没有执行,那就是说执行到513(1000-487)次时候出错的。
因此,我们按步骤2所讲,更改此断点的skip次数,将1000改为513。
4 再次重新运行程序,程序执行了513次循环,然后自动停在断点处。
这时,我们就可以仔细查看DoSome是如何返回0的。
这样,你就避免了手指的痛苦,节省了时间。
再看位置断点其他修饰条件。
如Figure 1所示,在“Enter the expression to be evaluated:”下面,可以输入一些条件,当这些条件满足时,断点才启动。
譬如,刚才的程序,我们需要i为100时程序停下来,我们就可以输入在编辑框中输入“i==100”。
另外,如果在此编辑框中如果只输入变量名称,则变量发生改变时,断点才会启动。
这对检测一个变量何时被修改很方便,特别对一些大程序。
用好位置断点的修饰条件,可以大大方便解决某些问题。
数据断点(Data Breakpoint)软件调试过程中,有时会发现一些数据会莫名其妙的被修改掉(如一些数组的越界写导致覆盖了另外的变量),找出何处代码导致这块内存被更改是一件棘手的事情(如果没有调试器的帮助)。
恰当运用数据断点可以快速帮你定位何时何处这个数据被修改(最好使用内存来查找,使用变量名的话,IDE不一定能找到。
)。
譬如下面一段程序:#include "stdafx.h"#includeint main(int argc, char* argv[]){char szName1[10];char szName2[4];strcpy(szName1,"shenzhen");printf("%s\n", szName1); //Astrcpy(szName2,"vckbase"); //Bprintf("%s\n", szName1);printf("%s\n", szName2);return 0;}这段程序的输出是szName1: shenzhenszName1: aseszName2: vckbaseszName1何时被修改呢?因为没有明显的修改szName1代码。
我们可以首先在A行设置普通断点,F5运行程序,程序停在A行。
然后我们再设置一个数据断点。
如下图:Figure 2数据断点F5继续运行,程序停在B行,说明B处代码修改了szName1。
B处明明没有修改szName1呀?但调试器指明是这一行,一般不会错,所以还是静下心来看看程序,哦,你发现了:szName2只有4个字节,而strcpy了7个字节,所以覆写了szName1。
数据断点不只是对变量改变有效,还可以设置变量是否等于某个值。
譬如,你可以将Figure 2中红圈处改为条件”szName2[0]==''''y''''“,那么当szName2第一个字符为y时断点就会启动。
可以看出,数据断点相对位置断点一个很大的区别是不用明确指明在哪一行代码设置断点。
上图中的断点设置最好用内存地址来表示,否则vc会出错。
其他调试手段:系统提供一系列特殊的函数或者宏来处理Debug版本相关的信息,如下:使用_ASSETE来debug,这三个都是MFC的。
_ASSERTE的头文件是crtdbg.h。
值WatchVC支持查看变量、表达式和内存的值。
所有这些观察都必须是在断点中断的情况下进行。
观看变量的值最简单,当断点到达时,把光标移动到这个变量上,停留一会就可以看到变量的值。
VC提供一种被成为Watch的机制来观看变量和表达式的值。
在断点状态下,在变量上单击右键,选择Quick Watch,就弹出一个对话框,显示这个变量的值。
单击Debug工具条上的Watch按钮,就出现一个Watch视图(Watch1,Watch2,Watch3,Watch4),在该视图中输入变量或者表达式,就可以观察变量或者表达式的值。
注意:这个表达式不能有副作用,例如++运算符绝对禁止用于这个表达式中,因为这个运算符将修改变量的值,导致软件的逻辑被破坏。
也可以修改某个变量的值。
Memory由于指针指向的数组,Watch只能显示第一个元素的值。
为了显示数组的后续内容,或者要显示一片内存的内容,可以使用memory功能。
在 Debug工具条上点memory按钮,就弹出一个对话框,在其中输入地址,就可以显示该地址指向的内存的内容。
VariablesDebug工具条上的Variables按钮弹出一个框,显示所有当前执行上下文中可见的变量的值。
特别是当前指令涉及的变量,以红色显示。
寄存器Debug工具条上的Registers按钮弹出一个框,显示当前的所有寄存器的值。
调试技巧:1、VC++中F5进行调试运行a)、在output Debug窗口中可以看到用TRACE打印的信息b)、 Call Stack窗口中能看到程序的调用堆栈2、当Debug版本运行时发生崩溃,选择retry进行调试,通过看Call Stack分析出错的位置及原因3、使用映射文件调试a)、创建映射文件:Project settings中link项,选中Generate mapfile,输出程序代码地址:/MAPINFO: LINES,得到引出序号:/MAPINFO: EXPORTS。
b)、程序发布时,应该把所有模块的映射文件都存档。
c)、查看映射文件:见” 通过崩溃地址找出源代码的出错行”文件。
4、可以调试的Release版本Project settings中C++项的Debug Info选择为Program Database,Link 项的Debug中选择Debug Info和Microsoft format。
5、查看API的错误码,在watch窗口输入@err可以查看或者@err,hr,其中”,hr”表示错误码的说明。
6、Set Next Statement:该功能可以直接跳转到指定的代码行执行,一般用来测试异常处理的代码。
7、调试内存变量的变化:当内存发生变化时停下来。
???进程控制VC允许被中断的程序继续运行、单步运行和运行到指定光标处,分别对应快捷键F5、F10/F11和CTRL+F10。
各个快捷键功能如下:Call Stack调用堆栈反映了当前断点处函数是被那些函数按照什么顺序调用的。
单击Debug 工具条上的Call stack就显示Call Stack对话框。
在CallStack对话框中显示了一个调用系列,最上面的是当前函数,往下依次是调用函数的上级函数。
单击这些函数名可以跳到对应的函数中去。
关注一个好的程序员不应该把所有的判断交给编译器和调试器,应该在程序中自己加以程序保护和错误定位,具体措施包括:∙对于所有有返回值的函数,都应该检查返回值,除非你确信这个函数调用绝对不会出错,或者不关心它是否出错。
∙一些函数返回错误,需要用其他函数获得错误的具体信息。
例如accept 返回INVALID_SOCKET表示accept失败,为了查明具体的失败原因,应该立刻用WSAGetLastError获得错误码,并针对性的解决问题。
∙有些函数通过异常机制抛出错误,应该用TRY-CATCH语句来检查错误∙程序员对于能处理的错误,应该自己在底层处理,对于不能处理的,应该报告给用户让他们决定怎么处理。
如果程序出了异常,却不对返回值和其他机制返回的错误信息进行判断,只能是加大了找错误的难度。