热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:继续分享5个实用的vs调试技巧

本文由编程笔记#小编为大家整理,主要介绍了继续分享5个实用的vs调试技巧相关的知识,希望对你有一定的参考价值。
本文由编程笔记#小编为大家整理,主要介绍了继续分享 5 个实用的 vs 调试技巧相关的知识,希望对你有一定的参考价值。



继续分享 5 个实用的 vs 调试技巧


前言

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


1. 条件断点

作用简介:

顾名思义,带条件的断点。满足条件才中断。条件断点非常非常有用,使用得当,可以极大缩短我们调试问题的时间。比如,有一个大循环,只在第 1024 次循环的时候有问题,我们如果单步(在 vs 中可以按 F10),恐怕手得按残了。又比如,我们想在特定条件下中断。这时候条件断点就是我们的救星。

技术图片

 




2. 内存断点

作用简介:

顾名思义,针对内存设置的断点。对于调试逻辑复(hun)杂(luan)的程序,非常非常有用。比如,有一个全局变量的值,在代码中有 N 个地方会改动它,在调试程序的时候,不知道这个全局变量在哪里被改变了,如果能在改动的那一刻中断下来该有多好啊!这可是内存断点的专长!

 


技术图片

memoryaccess-breakpoint


 

打开方式:

调试的时候,通过 调试 -> 窗口 -> 断点 即可打开断点窗口。在 vs2013 中对应的快捷键是 ctrl + alt + b 。打开后可以 通过 新建 -> 新建数据访问断点(D)... 创建一个数据访问断点。

注意:


  1. 只有在程序中断到调试器的时候才允许新建数据访问断点。


  2. 输入的是内存地址,可以直接输入地址值,也可以通过 & 获取地址。


  3. vs 中好像只支持指定的内存范围的值发生变化时才中断。windbg 中的 ba 命令更强大,感兴趣的小伙伴儿可以查看 windbg 的帮助文档。






3. 异常开关

作用简介:

异常最多分发两轮,每轮都会优先分发给调试器。如果调试器没处理,会继续分发给异常处理函数。具体的分发过程可以参考《软件调试》。

比如,在下面的示例代码中。我在 ExceptionDemo() 中加上了 try {} catch {} 来捕获一些异常。在 FunctionE() 中的某一行设置好断点,如果一切正常是可以断下来的。但是在 FunctionD() 中有可能抛出异常,如果根据设置,vs 不处理这个异常,该异常会被 ExceptionDemo() 处理,还没运行到设置断点的地方就被异常改变了执行流程。

#include "stdafx.h"
#include
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;
}
}

 


技术图片

exception


 

p.s. 虽然在代码中增加 try {} catch {} 有助于提高程序的健壮性,但有时候可能不利于我们发现问题,有些问题可能就被“默默”吞掉了。

打开方式:

调试的时候,通过 调试 -> 异常(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;
}
}

 


技术图片

manual-modify-variable


 

小贴士:不仅可以通过悬浮窗口改变变量的值,我们还可以通过监视窗口内存窗口等其它方式改变变量的值。




5. 拖动到指定位置执行

作用简介:

相信,大家都有过手滑的情况,本来想的是单步步入(在 vs 中按 F11)特定函数,没想到却按成了 F10,华丽丽的错过了想调试的函数,这时候我们可以拖回来。又或者如上面的代码,当执行到第24行的时候,发现 totalMoney 的值不是我们想要的,我们想重新回到前面跟踪一下totalMoney 的值是怎么来的,而我们又不想重新走一遍整个流程(因为可能很慢)。这时候我们可以手动拖动黄色小箭头到第 22 行。请看下图:

 


技术图片

drag-to-specific-line


 

注意:

拖动功能是通过设置 eip(rip) 的值来实现的,拖动需谨慎,有些情况下可能导致程序崩溃!




测试工程下载地址

百度云盘 链接: https://pan.baidu.com/s/1MSjUNPF-JHoY1t3l1xXFeg 提取码: jew2

CSDN:https://download.csdn.net/download/xiaoyanilw/12640122




总结

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




参考资料

《软件调试》



推荐阅读
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文介绍了[从头学数学]中第101节关于比例的相关问题的研究和修炼过程。主要内容包括[机器小伟]和[工程师阿伟]一起研究比例的相关问题,并给出了一个求比例的函数scale的实现。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
author-avatar
sen0226714
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有