首页 > 学院 > 开发设计 > 正文

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

2019-11-17 03:05:37
字体:
来源:转载
供稿:网友
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 异常抛出时调试器中断的例子。

  更多阅读:

  • 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+ <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的构造函数。

  更多阅读:

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

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

  你可能很少需要将调试器附加

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表