- 1、本文档共32页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
国际产品中心
Windows调试技巧
版本管理
版本号 修订发布时间 修订人 备注 1.0 2007/06/22 Silver 初始版本
概要
调试Windows程序是一件繁琐而又复杂的事情,掌握必要的调试策略可以使这些工作变得轻松
调试
Windows调试器类型
用户模式(USER-MODE)调试器
基于win32 Debugging API,有使用方便的界面,主要用于调试用户模式下的应用程序。这类调试器包括Visual C++调试器、WinDBG、BoundChecker、Borland C++ Builder调试器、NTSD等
内核模式(KERNEL-MODE)调试器
内核调试器位于CPU和操作系统之间,一旦启动,操作系统也会中止运行,主要用于调试驱动程序或用户模式调试器不易调试的程序。这类调试器包括WDEB386、WinDBG和softice等。其中WinDBG和softice也可以调试用户模式代码。
准则
调试前要求
编写便于调试的代码
少用全局变量
所有变量都要初始化,成员变量在构造函数中初始化
尽量使用const
详尽的注释
使用 Assert(原则:尽量简单)
例子:
char* strcpy(char* dest,char* source)
{
assert(source!=0);
assert(dest!=0);
char* returnstring = dest;
while((*dest++ = *source++)!= ‘\0’)
{
;
}
return returnstring;
}
使用Trace
a)、TRACE
CString csTest = “test”;
TRACE(“CString is %s\n”,csTest);
b)、ATLTRACEc)、afxDump
CTime time = CTime::GetCurrentTime();
#ifdef _DEBUG
afxDump time “\n”;
#endif
用GetLastError来检测返回值,通过得到错误代码来分析错误原因
程序设计时一定要考虑到异常如何处理,当错误发生后,不应简单的报告错误并退出程序,应当尽可能的想办法恢复到出错前的状态或者让程序从头开始运行,并且对于某些错误,应该能够容错,即允许错误的存在,但是程序还是能够正常完成任务。
总是使用/W4警告级别
在调试版本里总是使用/GZ编译选项,用来发现在Release版本中才有的错误
没有警告的编译:保证在编译后没有任何警告,但是在消除警告前要进行仔细检查
确定错误的存在
收集错误的信息
分析错误的信息
消除错误
修改的验证
知识补充
汇编知识
FUNC(参数1,参数2, ……..参数n)
{
局部变量1
局部变量2
。。。。。
局部变量n
}
原则
无论函数的调用规范,参数都是从右往左压栈
栈是向低地址发展的,栈顶在低地址
《-------------------低地址
按照以上原则,调用函数FUNC时的栈情况为
先把函数最右边的参数N入栈,以此类推压入函数的参数
将调用此函数前下一指令位置(也就是此函数执行完后的返回地址)压入栈
进入了新的函数内部,有了新地EBP地址把,把外层的EBP地址压入栈,便于返回后可以利用,然后为局部变量预留空间,可能先调整ESP的地址,在把局部变量入栈
之所以每调用一次函数,都要更新他的EBP,把前一个的EBP的地址入栈,是为了返回后方便查找调用函数的局部变量等信息,
更新新的EBP,对于被调用函数而言也是方便查找本函数内部的局部变量和参数
堆栈
堆栈是一种先进后出的数据结构 , 数据的存取在栈顶进行 , 数据入栈使堆栈向地址减小的方向扩展
堆栈常用于保存子程序调用和中断响应时的断点以及暂存数据或中间计算结果
堆栈总是以字为单位存取
以下的问题可能在堆栈里发生
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
}
void main() {
function(1,2,3);
}
void function(char *str) {
char buffer[16];
strcpy(buffer,str);
}
void main() {
char large_string[256];
int i;
for( i = 0; i 255; i++)
large_string[i] = A;
function(large_string);
}
这里发生了什么事?
文档评论(0)