千家信息网

Visual Studio原生开发的调试技巧有哪些

发表于:2024-10-01 作者:千家信息网编辑
千家信息网最后更新 2024年10月01日,本篇内容介绍了"Visual Studio原生开发的调试技巧有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能
千家信息网最后更新 2024年10月01日Visual Studio原生开发的调试技巧有哪些

本篇内容介绍了"Visual Studio原生开发的调试技巧有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!



技巧1: 异常中断

在处理被调用之前,异常发生时可以 启动调试器进行中断,可以让你在异常发生后立即调试程序。操作调用栈便于你去查找异常发生的根本原因。

Vistual Studio允许你去指定想要中断的异常类型或者特殊异常。选择菜单Debug>Exceptions弹出对话框,你可以指定原生的(或者托管的)异常,除了调试器自带的一些默认异常,你还可以添加自己的自定义异常。

下面是一个std::exception 异常抛出时调试器中断的例子。

更多阅读:

  • 1. 异常抛出时如何中断

  • 2. 如何添加新的异常

技巧2:Watch窗口中的伪变量

Watch窗口或QuickWatch对话框提供一些特定的(调试器可识别的)变量,被称为伪变量。文档包含以下:

$tid--当前线程的线程ID
$pid--进程ID
$cmdline----启动程序的命令行字符串
$user----正在运行程序的账户信息
$registername--显示寄存器registername 的内容
不管怎么样,关于最后一个错误的伪变量是非常有用的:

$err---显示最后一个错误的错误码
$err,hr-显示最后一个错误的错误信息

更多阅读:伪变量

技巧3:符合越界后查看堆对象

有时候,在调试符号越界后,你还想查看对象的值,这个时候,watch窗口中的变量是被禁用的,不能再查看(也不能更新),尽管对象仍然存在。你如果知道对象的地址,可以继续充分地观察它。你可以将地址转换为该对象类型的指针,放在watch窗中。

下面的例子中,当单步跳出do_foo()之后,_foo不能再被访问。但是,将它的地址转换为foo*后,就可以继续观察这个对象。

技巧4:查看数组的值

如果你在操作一个很大的数组(我们假设至少有几百个元素吧,但是可能更少),在Watch窗口中展开数组,查找一些特定范围内的元素很麻烦,因为你要不停地滚动.如果数组是分配在堆上的话,你甚至不能在watch窗口中展开数组元素.对此,有一个解决办法。你可以使用(array+ ), 去查看从位置开始的特定范围的元素(当然,这儿的数组是你的实际对象)。如果想查看整个数组,可以简单使用array,.

如果你的数组是在堆上,你可以在watch窗口中将它展开,但是要查看某个特定范围的值,用法稍有不同:((T*) array + ),(注意这种用法对于堆上的多维数组也有效)。但是这种情况下,T是指数组元素的类型。

如果你在用MFC,并使用其中的'array'容器,像 CArray, CDWordArray,CStringArray等等。你当然可以使用同样的过滤方法。除此之外,你必须查看array的m_pData成员,它是保存数据的真实缓存。

技巧5:避免进入不必要的函数

很多时候,你在调试代码时可能会进入到你想跳过的函数,像构造函数,赋值操作或者其他的。其中最困扰我的是CString构造函数。下面是一个例子,当你准备单步执行take_a_string()函数时,首先进入到CString的构造函数。

void take_a_string(CString const &text){}void test_string(){ take_a_string(_T("sample"));}


幸运的是可以告诉调试器去跳过哪些方法,类或者整个命名空间。实现它的方法也已经改变了,回到使用VS6的日子,通常是通过autoexp.dat文件来指定的。Vistual Studio 2002改成了使用注册表设置。想要跳过一些函数,你需要在注册表里添加一些值(详情如下):

  1. 实际位置取决于你使用的Vistual Studio版本和操作系统平台(x86或x64,因为注册表只能在64位的Windows下浏览)值的名字是数字,代表规则的优先级;数字越大,优先级越高。值数据是一个正则表达式的REG_SZ值,用于指定怎样过滤和执行。

为了避免进入任何CString方法,我添加了下面的规则:

有了这个,即使你强制进入上例中的take_a_string(),调试器也会跳过CString的构造函数。

更多阅读:

  • 使用Visual C++调试器怎样避免进入函数

  • 使用AutoExp.dat调整调试器

技巧6:从代码启动调试器 Launch the debugger from code

你可能很少需要将调试器附加到程序中,但你不能在Attach窗口这样做(可能因为中断发生太快而没有捕获到),你也不能一开始就在调试器中启动程序。你可以在程序中产生中断给调试器一个机会通过调用内部的_degbugbreak()来附加。

复制代码 代码如下:


void break_for_debugging() {
__debugbreak();
}

实际上还有其他的方法来完成,例如触发中断3,但这仅仅适用于x86平台(C++64位不再支持ASM)。另外还有DebugBreak()函数,但它的使用不怎么简便,所以这里推荐使用内部方法。

复制代码 代码如下:

__asm int 3;

程序运行内部方法时会停止运行,这时你就有机会将调试器附加到该进程。

更多阅读:

  • 内部方法_debugbreak

  • 任何时候都离不开设置断点和断言

  • Visual Studio 20005/2008的调试,第四部分:为调试器设置代码

技巧7:在output窗口打印

通过调用DebugOutputString可以在调试器的output窗口显示一段特定的文本。如果没有附加的调试器,该函数什么也不做。

更多阅读:

  • 函数OutputDebugString

  • 函数OutputDebugString的调用机制

技巧8:隔离内存泄漏

内存泄漏是在原生开发中的一个很重要的问题,要检测内存泄漏是一个很严峻的挑战,尤其是在大型项目中。Vistual Studio可以提供检测内存泄漏的报告,还有其他的一些应用程序(免费的或商业的)也可以帮助你检测内存泄漏.有些情况下,在一些内存分配最终会导致泄漏时,可以使用调试器去中断。但是你必须找到可再现的分配编号(尽管没那么容易)。如果能做到这一点,执行程序时调试器才会中断。

我们来看下面的代码,分配了8个字节,却一直没释放分配的内存。Visual Studio提供了造成内存泄漏的对象的报告,多运行几次,会发现一直是同一个分配编号(341)。

复制代码 代码如下:


void leak_some_memory()
{
char* buffer = new char[8];
}
Dumping objects ->
d:\marius\vc++\debuggingdemos\debuggingdemos.cpp(103) : {341} normal block at 0x00F71F38, 8 bytes long.
Data: < > CD CD CD CD CD CD CD CD



在一个特定的(可复现的)位置中断的步骤如下:

确定你有足够的关于内存泄漏的报告模式(参考 使用CRT库检测内存泄漏)
多次运行程序直到你能在程序运行结束后的内存泄漏报告里找到一个可复现的分配编号,例如上个例子中的(341)
在程序一开始的地方设置一个断点以便你能够尽早地进行中断。
当最初的中断发生时,watch窗口的Name栏里会显示:{,,msvcr90d.dll}_crtBreakAlloc,在Value栏里写入你想要查找的位置编号
继续调试(F5)
程序执行到指定位置会停止,你可以使用调用栈被指引找到被该位置触发的那段代码。
遵循这些步骤, 在上个例子中,使用分配的编号(341)就可以识别内存泄漏的起因。

技巧9:调试发行版

调试和发布是两个不同的目的。调试配置是用于开发的,而发布配置,顾名思义,是用来作为程序的最终版本,因为它必须严格遵循发布的质量要求,该配置包含优化部分和调试版本的中断调试的设置。而且,有时候,要像调试调试版本一样去调试发行版。要做到这一点,你需要在配置里做一些改变。但是这种情况下,你就不再是在调试发行版,而是调试和发行的混合版。

你还应该做一些事儿,以下是必须要做的:

配置C/C++ >General>Debug Information Format 应该为 "Program Database(/Zi)"
配置C/C++ >Optimization>Optimization 应该为"Disabld(/Od)"
配置Linker>Debugging>Generate Debug Info 应该为"Yes/(DEBUG)"
如图所示:

更多阅读:怎样调试发行版

技巧10:远程调试

另一个重要的调试就是远程调试,这是一个更大的话题,多次被提到,这里我只做一下简单的概括:

你需要在远程机器上安装远程调试监控
远程调试监控必须以管理员身份运行,并且用户必须属于管理员组
在你运行监控时,会开启一个新的服务,该服务的名字必须用Visual Studio的Attach to Progress窗口的Qualifier组合框的值。

  1. 远程和本地机器上的防火墙必须允许Visual Studio和远程调试监控之间能够通信

  2. 想要调试,PDB文件是关键;为了能够让VisualStudio自动加载它们,必须满足以下条件:

1)本地的PDB文件必须可用(在远程机器的相同路径下放置一个对应的模块)。

2) 远程机器上的托管PDB文化必须可用。

远程调试监控下载:

  • Visual Studio 2008 Service Pack 1 Remote Debugger

  • Microsoft Visual Studio 2010 Remote Debugger

"Visual Studio原生开发的调试技巧有哪些"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

调试器 程序 函数 技巧 内存 代码 数组 对象 方法 更多 分配 运行 配置 位置 变量 例子 元素 错误 发行 监控 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 软件开发一个般做什么产权 寻甸上门软件开发报价表 金赛药业软件开发笔试题 网络安全中职需要学什么课程 杭州新宏基软件开发 服务器配置最高的主机 谷歌服务器怎么连接视频 怎么用 sci数据库 杭州锄禾互联网科技有限公司 线上服务器部署在哪里呢 软件开发刚进公司需要干什么 老王网络安全法 json 转数据库 网络安全运维的单词 sql数据库c连接不上 移动平台软件开发教科书 数据库服务器与web服务器分离 2网络安全绘画入门 服务器二次电源 嘉兴集合点网络技术有限公司 数据库端口号90 瑞庭网络技术有限公司合肥分公司 江夏定制软件开发电话 龙华区光纤网络技术开发推荐厂家 网络安全2.0国家标准5个等级 数据库的恢复技术保证事务的 提供软件开发哪家便宜 云南塔式服务器多少钱 乐牌北京网络技术有限公司客服 上海菲陆网络技术有限公司
0