Visual Studio原生开发的10个调试技巧(一)

  最近碰巧读了Ivan Shcherbakov写的一篇文章,《11个强大的Visual Studio调试小技巧》。这篇文章只介绍了一些有关Visual Studio的基本调试技巧,但是还有其他一些同样有用的技巧。我整理了一些Visual Studio(至少在VS 2008下)原生开发的调试技巧。(如果你是工作在托管代码下,调试器会有更多的特性,在CodeProject中有介绍它们的文章),下面是我的整理的一些技巧:

  1. 异常中断 | Break on Exception
  2. Watch窗口中的伪变量 | Pseudo-variables in Watch Windows
  3. 符号越界后查看堆对象 |
  4. 查看数组的值
  5. 避免进入不必要的函数
  6. 从代码启动调试器 | Launch the debugger from code
  7. 在Output窗口打印
  8. 隔离内存泄漏
  9. 调试发行版 | Debug the Release Build
  10. 远程调试

  技巧1: 异常中断

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

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

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

  更多阅读:

  技巧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+ <offset>),<count> 去查看从<offset>位置开始的特定范围的<count>元素(当然,这儿的数组是你的实际对象)。如果想查看整个数组,可以简单使用array,<count>.

  如果你的数组是在堆上,你可以在watch窗口中将它展开,但是要查看某个特定范围的值,用法稍有不同:((T*) array + <offset>),<count>(注意这种用法对于堆上的多维数组也有效)。但是这种情况下,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下浏览)
  2. 值的名字是数字,代表规则的优先级;数字越大,优先级越高。
  3. 值数据是一个正则表达式的REG_SZ值,用于指定怎样过滤和执行。

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

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

  更多阅读:

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

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

void break_for_debugging()
{
   __debugbreak();
}

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

__asm int 3;

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

  更多阅读:

  技巧7:在output窗口打印

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

  更多阅读:

  技巧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
Object dump complete.

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

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

  遵循这些步骤, 在上个例子中,使用分配的编号(341)就可以识别内存泄漏的起因。

  技巧9:调试发行版

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

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

  1. 配置C/C++ >General>Debug Information Format 应该为 “Program Database(/Zi)”
  2. 配置C/C++ >Optimization>Optimization 应该为”Disabld(/Od)”
  3. 配置Linker>Debugging>Generate Debug Info 应该为”Yes/(DEBUG)”

  如图所示:

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

  技巧10:远程调试

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

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

  1. 远程和本地机器上的防火墙必须允许Visual Studio和远程调试监控之间能够通信
  2. 想要调试,PDB文件是关键;为了能够让VisualStudio自动加载它们,必须满足以下条件:

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

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

  远程调试监控下载:

  原文链接: Marius Bancila   翻译: 伯乐在线JingerJoe

Visual Studio原生开发的10个调试技巧(一)

时间: 2024-11-08 08:27:03

Visual Studio原生开发的10个调试技巧(一)的相关文章

Visual Studio 2015开发Android App启动调试始终无法完成应用部署的解决方案

创建一个Android App项目后,直接启动调试发现Visual Studio Emulator for Android已成功运行,但应用始终处于Build中(等待时间超过1小时),并未如预期通过adb部署到模拟器中.将应用直接导出apk,拖拽至模拟器直接部署,提示: File transfer failed. Error: Unable to install the file through Adb. Adb.exe not found. Make sure you have Android

使用Visual Studio Code开发(编译、调试)C++程序

总体安装步骤 安装VSC(Visual Studio Code). 安装C/C++编译器(如MinGW-w64),然后配置好环境变量.//完成这步即可在VSC的终端(命令行)下编译.运行.cpp程序了. 配置Path变量,加入mingw的安装路径,如d:/mingw64/bin/ 安装并配置Code Runner插件,一键编译运行. 打开扩展(文件-首选项-扩展,或者ctrl+shift+x),搜索Code Runner. 为了在控制台输入,需要配置:"文件-首选项-设置-用户设置-扩展-Run

Mac上使用Visual Studio Code开发/调试.NET Core代码

Mac上使用Visual Studio Code开发/调试.NET Core代码 .Net Core 1.0终于发布了,Core的一大卖点就是跨平台.这个跨平台不只是跨平台运行,而且可以跨平台开发.今天抽空研究了下在Mac下如何使用VS Code来开发.NET Core程序,并且调试代码. 1.安装.NET Core 在mac上打开终端: ~$ brew update ~$ brew install openssl ~$ brew link --force openssl 如果不能使用brew命

在Visual Studio上开发Node.js程序(2)——远程调试及发布到Azure

[题外话] 上次介绍了VS上开发Node.js的插件Node.js Tools for Visual Studio(NTVS),其提供了非常方便的开发和调试功能,当然很多情况下由于平台限制等原因需要在其他机器上运行程序,进而需要远程调试功能,不过还好,NTVS提供的远程调试也非常方便. [系列索引] 在Visual Studio上开发Node.js程序——NTVS介绍及使用 在Visual Studio上开发Node.js程序(2)——NTVS远程调试及发布到Azure [文章索引] NTVS远

在Visual Studio上开发Node.js程序

[题外话] 最近准备用Node.js做些东西,于是找找看能否有Visual Studio上的插件以方便开发.结果还真找到了一个,来自微软的Node.js Tools for Visual Studio(NTVS),虽然现在仅发布了1.0 Alpha版本,但使用起来已经非常方便.而且,其开发团队与Python Tools for Visual Studio(PTVS)是同一个,而PTVS就是Visual Studio 2013中要创建自带的Python项目需要安装的那个程序,所以大可放心的使用NT

使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(一)-- 起步

本文记录了在Windows环境下安装Visual Studio Code开发工具..Net Core 1.0 SDK和开发一个简单的Web-Demo网站的全过程. 一.安装Visual Studio Code 安装文件下载地址:VS Code,当前最新版本是1.3. 推荐安装最新版,因为附带Debug插件,支持在vs code上进行断点调试. 二.安装.Net Core 1.0 SDK 安装文件下载地址:.Net Core SDK 三.创建一个.Net Core应用程序 1. 打开cmd窗口,创

Visual Studio中开发

如何在Visual Studio中开发自己的代码生成器插件  Visual Studio是美国微软公司开发的一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代码管控工具.集成开发环境(IDE)等等,且所写的目标代码适用于微软支持的所有平台.可以说.NET开发人员离不开它,它可以极大的提高编写软件的效率. Visual Studio作为一个世界级开发工具,当然支持通过插件方式对其功能进行扩展,开发人员可以定制自己的插件来进一步提升Visual Studio的功

使用Visual Studio Code开发.NET Core看这篇就够了

原文:使用Visual Studio Code开发.NET Core看这篇就够了 作者:依乐祝 原文地址:https://www.cnblogs.com/yilezhu/p/9926078.html 在本文中,我将带着大家一步一步的通过图文的形式来演示如何在Visual Studio Code中进行.NET Core程序的开发,测试以及调试.尽管Visual Studio Code的部分功能还达不到Visual Studio的水平,但它实际上已经足够强大来满足我们的日常开发.而且其轻量化,插件化

Visual Studio跨平台开发(1):Hello Xamarin!

前言 应用程序发展的脚步, 从来没有停过. 从早期的Windows 应用程序, 到网络时代的web 应用程序, 再到近几年相当盛行的行动装置应用程序(Mobile Application), 身为C#的开发人员与Visual Studio的使用者. Windows Phone与Windows Store App的开发是否已满足不了你了呢? 如果能夠让你使用C#及Visual Studio 来开发iOS及Android的app. 是否能再度唤醒你的开发魂? Xamain 正是为了这样的需求而诞生的