Visual Studio高级调试技巧
副标题[/!--empirenews.page--]
1. 设置软件断点,运行到目标位置启动调试器 方法①:使用汇编指令(注:x64 c++不支持汇编) _asm int 3 方法②:编译器提供的方法 __debugbreak(); 方法③:使用windows API DebugBreak(); WerFault.exe进程(Windows Error Reporting)弹出ConsoleTest.exe已停止工作: 要想出现“调试程序”选项,需要将Windows Error Reporting注册表信息设置成如下图所示(注:特别是红框的内容) 如果在注册表AeDebug的Debugger项配置了VSJitDebugger路径,且VSJitDebugger运行正常 HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionAeDebug HKEY_LOCAL_MACHINESoftwareWow6432NodeMicrosoftWindows NTCurrentVersionAeDebug // 注:64位系统上的32位程序使用该注册表项 点击“调试程序”选项就会弹出Visual Studio实时调试器对话框,选择对应的调试器后,点击“是”就可以启动调试器并中断到软件断点位置了 需要注意的是,软件断点也是一种异常,一旦被处理,就不会传到WerFault.exe进程上,那么这种方法也就失效了! 下面两种情况软件断点异常会被处理: ① 被SEH异常捕获并处理 ② 被自定义的全局异常函数处理 注:可以将上面两种情况中的EXCEPTION_EXECUTE_HANDLER修改为EXCEPTION_CONTINUE_SEARCH来指明异常未得到处理 2. 修改变量(注:在悬停出来小面板、Locals窗口、Autos窗口、Watch窗口、或Quick Watch窗口中进行修改;也可以在Immediate窗口中执行:bFlag=false) 3. 格式化变量 注:d,i:有符号的十进制数 4. 修改内存(注:在内存窗口中,将光标定位到要修改的地方,直接按0-9输入十六进制;要输入a-f则需通过右键菜单中的“Edit Value”进行输入) 5. 格式化显示内存
6. 设置下一个运行位置(注:直接拖动黄色箭头到想要的运行位置) 示例中:传入的bFlag为true,代码开始运行到断点处(43行),然后重新把黄色箭头拖回39行,此时bFlag的值为false,,按F10会进入else分支 注:(1)跳过中间所有指令。意味着:printf("Truen")及CTest的析构函数均不会被执行 (2)当拖动箭头到一个新的函数中时,vs会将原来的函数从栈中弹出,将新函数压入栈顶; 由于新函数与上层函数没有调用关系,输出类型的参数及返回值很有可能写坏上层函数的栈数据 (3)该调试技巧为一种事后行为,应谨慎使用,最好是只在函数内局部使用 7. 编辑然后继续运行 (1)不能在64位代码上使用 (2)使用“Program Database for Edit & Continue (/ZI)”生成pdb文件 (3)仅适用于函数内部改变(若要修改函数原型或增加新函数,只能选择重启程序) 8. 变量的一些特殊查看方法 以$和@开头的伪变量:(注:$和@两个符号是一样的,随便用哪个都可以) $err -- 获取GetLastError()的返回值 $err,hr -- 获取GetLastError()的返回值并解释返回值的含义 @eax -- 查看eax的值(64位为@rax) @esp+4 -- 函数的第一个参数地址 $handles -- 查看打开的句柄数 $tid -- 当前线程id $vframe -- 当前栈帧的ebp $clk -- 以时钟周期为单位显示时间 $ReturnValue -- 查看函数的返回值 Message,wm --以windows消息的宏形式显示 如:Message为15时,显示为WM_PAINT(注:Message为unsigned int类型) hResult,hr --hResult为0x80070005时,显示为E_ACCESSDENIED(注:hResult为void*类型) pArray,10 --从pArray地址起显示后续10个int类型的数据(注:pArray为int*类型) (pArray+5),3 --从pArray[5]地址起显示后续3个int类型的数据(注:pArray为int*类型) 9. 获取简单类型的函数返回值 注1:不能为inline函数 注2:执行函数的下一条语句时,查看eax或伪变量ReturnValue的值 10. 使用指针类型转换查看某个地址的变量 注:有时候,尽管对象仍然存在,在调试符号越界后,watch窗口中的变量是被禁用的,不能再查看(也不能更新)。 若知道对象的地址,则可以将地址转换为该对象类型的指针,放在watch窗中来继续观察它。 11. Command窗口 (编辑:淮北站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |