VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 279|回复: 5

[原创] 继续分享 5 个 vs 调试技巧

[复制链接]
70_avatar_middle
最佳答案
0 
在线会员 发表于 2020-7-20 07:01:41 | 显示全部楼层 |阅读模式

声明:本文最先发表在我的个人公众号 【编程难】 上,在咱们驿站也发表了一份,我觉得标原创应该没问题。

前言我在上一篇文章《5 个非常实用的 vs 调试技巧》 中分享了 5 个我认为非常值得了解的 vs 调试技巧,本周继续分享 5 个很基础但同样实用的调试技巧。

1. 条件断点作用简介:
顾名思义,带条件的断点。满足条件才中断。条件断点非常非常有用,使用得当,可以极大缩短我们调试问题的时间。比如,有一个大循环,只在第 1024 次循环的时候有问题,我们如果单步(在 vs 中可以按 F10),恐怕手得按残了。我们可以通过条件断点快速中断。
继续分享 5 个 vs 调试技巧

2. 内存断点作用简介:
顾名思义,访问指定内存地址的时候就会中断的断点。对于调试逻辑复(hun)杂(luan)的程序,非常非常有用。比如,有一个全局变量的值,在代码中有 N 个地方会改动它,在调试程序的时候,不知道这个全局变量在哪里被改变了,如果能在改动的那一刻中断下来该有多好啊!这可是内存断点的专长!
继续分享 5 个 vs 调试技巧
打开方式:
调试的时候,通过 调试 -> 窗口 -> 断点 即可打开断点窗口。在 vs2013 中对应的快捷键是 ctrl + alt + b 。打开后可以 通过 新建 -> 新建数据访问断点(D)... 创建一个数据访问断点。
注意:
  • 只有在程序中断到调试器的时候才允许新建数据访问断点。
  • 输入的是内存地址,可以直接输入地址值,也可以通过 & 获取地址。
  • vs 中好像只支持指定的内存范围的值发生变化时才中断。windbg 中的 ba 命令更强大,感兴趣的小伙伴儿可以查看 windbg 的帮助文档。


3. 异常开关作用简介:
异常分发最多有两轮,每轮都会优先分发给调试器。如果调试器没处理,会继续分发给异常处理函数。具体的分发过程可以参考《软件调试》。
比如,在下面的示例代码中。我在 ExceptionDemo() 中加上了 try {} catch {}  来捕获一些异常。在 FunctionE() 中的某一行设置好断点,如果一切正常是可以断下来的。但是在 FunctionD() 中有可能抛出异常,如果根据设置,vs 不处理这个异常,该异常会被 ExceptionDemo() 处理,还没运行到设置断点的地方就被异常改变了执行流程。
#include "stdafx.h"
#include <exception>

bool application_quit = false;
int g_runningLoop = 0;

void FunctionA();
void FunctionB();
void FunctionC();
void FunctionD();
void FunctionE();

void ExceptionDemo()
{
    try
    {
        while (!application_quit)
        {
            FunctionA();
        }
    }
    catch (std::exception)
    {
    }
}

void FunctionA() { FunctionB(); }
void FunctionB() { FunctionC(); }
void FunctionC() { FunctionD(); }
void FunctionD()
{
    if (++g_runningLoop > 6)
    {
        throw std::exception("too many loops!");
    }
    FunctionE();
}

void FunctionE()
{
    if (g_runningLoop > 10)
    {
        application_quit = true;
    }
}
p.s. 虽然在代码中增加 try {} catch {} 有助于提高程序的健壮性,但有时候可能不利于我们发现问题,有些问题可能就被“默默”吞掉了。
继续分享 5 个 vs 调试技巧

打开方式:
调试的时候,通过 调试 -> 异常(X)... 即可打开异常设置对话框。在 vs2013 中对应的快捷键是 Ctrl + Alt + E。
注意:只有在调试的时候才能设置,不调试的时候是看不到异常设置菜单的。

4. 调试时修改值作用简介:
假设我们正在调试如下代码,跟踪到了 if (bRich) 这一行,期待的 bRich 的值是 true,而实际值是 false。我们可以手动修改 bRich 的值为 true 来强行进入 if 分支,而不是 else 分支。(BTW,改完就真的有钱了么?)
#include "stdafx.h"
#include <iostream>

bool HaveIMakeEnoughMoney()
{
    return false;
}

void ManualModifyValueDemo()
{
    auto bRich = HaveIMakeEnoughMoney();
    if (bRich)
    {
        std::cout << "Finally, I'm rich!" << std::endl;
    }
    else
    {
        std::cout << "Oops, I'm still poor!" << std::endl;
    }

}
继续分享 5 个 vs 调试技巧
小贴士:不仅可以通过悬浮窗口改变变量的值,我们还可以通过监视窗口,内存窗口等其它方式改变变量的值。

5. 拖动到指定位置执行作用简介:
相信,大家都有过手滑的情况,本来想的是单步步入(在 vs 中按 F11)特定函数,没想到却按成了 F10,华丽丽的错过了想调试的函数,这时候我们可以拖回来。又或者如上面的代码,当执行到第24行的时候,发现 totalMoney 的值不是我们想要的,我们想重新回到前面跟踪一下totalMoney 的值是怎么来的,而我们又不想重新走一遍整个流程(因为可能很慢)。这时候我们可以手动拖动黄色小箭头到第 22 行。请看下图:
继续分享 5 个 vs 调试技巧
注意:
拖动功能是通过设置 eip(rip) 的值来实现的,拖动需谨慎,有些情况下可能导致程序崩溃!

总结本次介绍的 5 个调试技巧虽然都很基础,但是却非常实用,而且使用频率比较高。不知道你是否有所收获呢?

参考资料《软件调试》



评分

参与人数 3驿站币 +4 热心值 +4 收起 理由
70_avatar_small tony666 + 1 + 1 感谢分享!
37_avatar_small 麒NULL + 1 + 1 支持原创!
58_avatar_small thzzl + 2 + 2 支持原创!

查看全部评分





上一篇:一天学会并使用mysql。
下一篇:修复被破坏的 vs 工程设置
98_avatar_middle
最佳答案
0 
在线会员 发表于 2020-7-20 07:38:12 | 显示全部楼层
继续跟进学习。

70_avatar_middle
最佳答案
21 
在线会员 发表于 2020-7-20 09:09:48 | 显示全部楼层
学习了,感谢大佬继续分享 5 个 vs 调试技巧
58_avatar_middle
最佳答案
43 
online_vip 发表于 2020-7-20 15:11:14 | 显示全部楼层
学习了,催更
70_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2020-8-9 18:40:28 | 显示全部楼层

感谢支持,正在整理,凑够5个 再发一波。继续分享 5 个 vs 调试技巧
79_avatar_middle
最佳答案
0 
在线会员 发表于 2020-9-23 16:23:53 | 显示全部楼层
受教了,感谢楼主分享
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-10-24 22:29

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表