VC调试器高级应用-高级断点篇(补全)

上传人:tia****nde 文档编号:36843932 上传时间:2018-04-03 格式:DOC 页数:20 大小:85.50KB
返回 下载 相关 举报
VC调试器高级应用-高级断点篇(补全)_第1页
第1页 / 共20页
VC调试器高级应用-高级断点篇(补全)_第2页
第2页 / 共20页
VC调试器高级应用-高级断点篇(补全)_第3页
第3页 / 共20页
VC调试器高级应用-高级断点篇(补全)_第4页
第4页 / 共20页
VC调试器高级应用-高级断点篇(补全)_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《VC调试器高级应用-高级断点篇(补全)》由会员分享,可在线阅读,更多相关《VC调试器高级应用-高级断点篇(补全)(20页珍藏版)》请在金锄头文库上搜索。

1、VCVC 调试器高级应用调试器高级应用-高级断点篇高级断点篇CND8 学院 VC 教程 发布日期:2008 年 12 月 15 日VC 调试器高级应用-高级断点篇一一. .高级断点语法高级断点语法 高级断点语法由两部分组成:1.上下文部分.2.位置,表达式,变量或 Windows 消息条件. 用函数,源文件和二进制模块来指定上下文,上下文的表示方法: 函数,源文件,二进制模块 必须指定唯一的,足够的上下文信息才能获取断点位置.如在 TEST.CPP 的 20 行设一位置断点,语法为:,TEST.CPP,.20,如 A.DLL 或 B.DLL 都使用了该行,又只想在 B.DLL 的调用中触发,则

2、必须使用:,TEST.CPP,B.DLL.20. VC 调试器中可直接输入上下文语法:Breakpoints 对话框的 Location 选项卡BreakAt 编辑框中.更容易的方法是使用 BreatAt 框右的箭头打开菜单,选择Advanced 项,然后在 Context 框中输入断点的相应信息. 如想在一个绝对地址上中断,直接在 BreakAt 框中输入地址就行. 二二. .任何函数上快速中断任何函数上快速中断 将函数名输入 BreadAt 框中.如果是 C+代码,同时还需要类限定符.支持重载了的函数,调试器会列出所有满足条件的函数供选择,如输入时提供足够的信息,完全可略过选择过程.如输入

3、:“CString:operator=(const char *)“可唯一确定要中断的函数. 三三. .在系统或在系统或 DLLDLL 输出的函数中设置断点输出的函数中设置断点 在程序中从 DLL 输入的函数中设置一个断点可能是毫无作用的,调试器需要知道在何处可以找到该函数上下文信息,同时,函数名取决于是否加载了 DLL 的符号.只有在 W2K 以上版本中才能在系统 DLL 中设置断点-原因在于其它系统没有提供边写入边复制保护的功能,若一定要启用这种方法,必须要有 COFF(Common Object File Format),并在调试器中输出启动的装载-在 Options 对话框的 Debu

4、g 页,将 Load COFF 否则说明没有装载 DLL 的符号. 没有装入符号时,使用的位置字符串是 DLL 输出的名称,可能用 DUMPBIN 程序查看这个名称:DUMPBIN /EXPORTS DLLname.例:在 LoadLibraryA 中设置中断:“,Kernel32.dllLoadLibraryA“. 如装入了符号,则要根据输出函数和调用协议来计算函数名.如上例,LoadLibraryA 使用_stdcall 调用协议,据该协议,函数名以下划线为前缀,所跟有进栈的字节数为后缀的号.一般说来,参数个数*4,就是参数占用栈空间的总字节数,LoadLibary 的名称便是:_Load

5、LibraryA4,故最后的语法是:或“,Kernel32.dll_LoadLibraryA4“ 附附: :常用的调用协议常用的调用协议 1、_stdcall 调用约定相当于 16 位动态库中经常使用的 PASCAL 调用约定。在 32 位的 VC+5.0 中 PASCAL 调用约定不再被支持(实际上它已被定义为_stdcall。除了_pascal 外,_fortran 和_syscall 也不被支持),取而代之的是_stdcall 调用约定。两者实质上是一致的,即函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈,但不同的是函数名的修饰部分(关于函数名的修饰部分在后面将详

6、细说明)。 _stdcall 是 Pascal 程序的缺省调用方式,通常用于 Win32 Api 中,函数采用从右到左的压栈方式,自己在退出时清空堆栈。VC 将函数编译后会在函数名前面加上下划线前缀,在函数名后加上“和参数的字节数。 2、C 调用约定(即用_cdecl 关键字说明)按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于传送参数的内存栈是由调用者来维护的(正因为如此,实现可变参数的函数只能使用该调用约定)。另外,在函数名修饰约定方面也有所不同。 _cdecl 是 C 和 C程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall

7、 函数的大。函数采用从右到左的压栈方式。VC 将函数编译后会在函数名前面加上下划线前缀。是 MFC 缺省调用约定。 3、_fastcall 调用约定是“人”如其名,它的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用 ECX 和 EDX 传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。 _fastcall 方式的函数采用寄存器传递参数,VC 将函数编译后会在函数名前面加上“前缀,在函数名后加上“和参数的字节数。 4、thiscall 仅仅应用于“C+”成员函数。this 指

8、针存放于 CX 寄存器,参数从右到左压。thiscall 不是关键词,因此不能被程序员指定。 5、naked call 采用 1-4 的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存 ESI,EDI,EBX,EBP 寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call 不产生这样的代码。naked call 不是类型修饰符,故必须和_declspec 共同使用。 关键字 _stdcall、_cdecl 和_fastcall 可以直接加在要输出的函数前,也可以在编译环境的 Setting.C/C+ Code Generation 项选择。当加在输出函数前的关键字与编

9、译环境中的选择不同时,直接加在输出函数前的关键字有效。它们对应的命令行参数分别为/Gz、/Gd 和/Gr。缺省状态为/Gd,即_cdecl。 要完全模仿 PASCAL 调用约定首先必须使用_stdcall 调用约定,至于函数名修饰约定,可以通过其它方法模仿。还有一个值得一提的是 WINAPI 宏,Windows.h 支持该宏,它可以将出函数翻译成适当的调用约定,在 WIN32 中,它被定义为_stdcall。使用 WINAPI 宏可以创建自己的 APIs。 四四. .位置断点修饰符位置断点修饰符 1.跳跃计数. 功能是执行断点但不在断点处停止,直到执行完了一个特定的次数为止. 使用中首先设置一

10、个标准的位置断点,打开 BreadPoint 对话框,选中该断点,单击 Condition,然后在弹出的对话框最下面的编辑控件中输入次数. 只有当程序全速运行时,未执行的循环次数才有用.单步执行跨过断点时不会更新跳跃计数. 例:已知循环可能崩溃,但不清楚在哪次循环时,输入远远大于总循环次数的跳跃计数修饰符,则在崩溃时可打开 Breakpoint 框,其中将列出还未执行的循环次数,与总次数相减就可得已执行的次数. 2.条件表达式. 只有表达式为真时触发.Breakpoint 框 Condition 按钮,选第一个编辑框,输入表达式即可.规则: .只可使用 C 类型比较运算符. .表达式中不能调用

11、任何函数. .表达式中不能包含任何宏值. 表达式为TIB=Thread Infomation Block Linear Address,则程序只在该特定线程中才会中断.例:线程TIB 地址值为 0E000,则输入“TIB=0xE000“,则在切换到该线程时中断.对 W98,可用FS=thread specific value. 如在某特定错误后中断,则可用ERR,如“ERR=2“表示在最后错误为ERROR_FILE_NOT_FOUND.除CLK 外,所有可在 WATCH 窗口中使用的伪寄存器均可用于条件表达式. 条件表达式可与跳跃断点组合使用. 3.变量更改 在变量更改时中断程序.只有当位置断

12、点执行时才能检查变量.常用用调用栈高层的函数中发现出错,需要深入调用栈,压缩范围找出根源时. 添加时在 Breakpoint 框第一个编辑框中输入变量名(可以是指针指向听对象:*p),在第二个编辑框中输入要查看的项目数量. 五五. .全局表达式和条件断点全局表达式和条件断点. . 调试器可监控某一地址和该地址上的 1,2 或 4 字节的内容.如可用硬件调试寄存器,则不影响速度;否则程序将单步执行 ASM 指令并在每一步中检查条件,这将严重影响程序运行速度. 总共有 4 个调试寄存器.硬件调试寄存器不能处理超过 1 个双字长的引用.确保利用硬件调试寄存器的最好方法是使用表达式和数据更改位置的实际

13、地址值.例如:g_szGlobal 是全局数组指针,地址为 0x5000,则在 Breakpoint 对话框中DATA 选项卡中将表达式断点设为“*(char*)0x5000=G“,但如果写为“WO(0x5000)=G,则用不到硬件调试寄存器,会单步执行每条指令. 与全局表达式断点类似,使用变量的 16 进制地址给定长指针计算地址,并将要查看的单元数设为 1,则全局变量断点可发挥最付佳功效.如上例要在变量改动时中断,则输入:“*(long*)0x5000“. 六六.WINDOWS.WINDOWS 消息断点消息断点. . Breakpoint 框的 Message 页.需要指定一个窗口过程,注意

14、:MFC 世界中 AfxWndProc 是多数窗口的一个窗口过程. WinDbg:(它和 VS 里的调试器有什么区别呢?难道只是因为它不要钱?) WinDbg 是微软开发的免费源码级调试工具。Windbg 可以用于 Kernel 模式调试 和用户模式调试,还可以调试 Dump 文件。由于大部分程序员不需要做 Kernel 模式调试, 我在这篇文章中不会介绍 Kernel 模式调试。Kernel 模式调试对学 习 Windows 核心极有帮助。如果你对此感兴趣,可以阅读 Inside Windows 2000 和 Windbg 所带的帮助文件。在同一个进程中可能有多个线程。命令可以 用来显示和切

15、换线程(批:似乎这是我唯一感兴趣的.看完之后,我只想说一局, OH,MY GOD,我想我一般不会去使用它)。 Visual C+的调试功能是从早期的调试工具 CodeBase 发展而成,这个名叫 CodeBase 调试工具研究成为一种工业标准。(批:呵,新鲜,第一次听到) 首先我们看一下使用异常处理的几种情况: A 用来处理非致命的错误 B 对 API 函数的参数合法性的检验(假设参数都是合法的,只有遇到异常的 时候进行合法性检验) C 处理致命错误(退出时最好的选择,但是有的时候可以用异常处理函数在 程序退出前释放资源,删除临时文件等,甚至可以详细记录产生异常的指令位 置和环境) D 处理“

16、计划内”的异常(我们可能更关心这种情况) 接着我们看看 Windows 下异常处理的两种方式:1 使用筛选器 2 SEH 异常处理 一、 使用筛选器(批:这个就稍微看一下吧.) 因为这里我要重点关注的是 SEH 的处理方式,所以还是简单的提一下筛选器处 理方式。筛选器异常处理是通过异常回调函数来指定程序处理异常。这种方式 的回调函数必须是唯一的,设置新的回调函数后以前的将失效。适用于进程范 围。看一下这个函数的定义 Invoke SetUnhandledExecpionFilter,offset_Handler Mov lpPrevHandler,eax 回调函数的格式: _Handlerproc pExecptionInfo 看看 p

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 试题/考题

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号