`
tansitongba
  • 浏览: 503453 次
文章分类
社区版块
存档分类
最新评论

Visual Studio调试之断点技巧篇

 
阅读更多

不知道能不能算是技巧啦,写出来放到首页贻笑大方而已。

函数断点

在前面的文章Visual Studio调试之避免单步跟踪调试模式里面我讲了如何设置函数断点,说实话,我个人喜欢设置函数断点,而不是在代码行里面设置断点。一般来说,函数断点在下面几种情形下有用:

1. 例如调试一个网站程序,你通过分析网站的日志发现最有可能发生错误的函数,打开调试器并将调试器附加到程序上去,设置函数断点,重新执行网站……这样做的好处是,不用到处打开源文件去找出错的源代码行,调试器会自动打开源代码,并且在函数的入口处中断(岂不是很方便?)。

2. 例如你在阅读源代码的时候,通常在读到虚函数调用的时候,因为通常这种调用都是通过基类指针调用的,而你又一时半会不知道到底有哪个继承类的Overloading函数会被调用到,函数断点可以告诉你。

3. 或者一种特殊的情形,你想读一个程序的源代码,但就是找不到入口Main函数,例如.NET程序,那么直接在Visual Studio里面按F11就能帮你找到入口函数这是函数断点的一个特殊情形。

4. 比如你在调试Web Service函数,设置函数断点也是一个快捷的调试方法,这个技巧跟技巧1类似。

当然,可能有些读者没有办法成功设置函数断点,如果设置函数断点失败,请阅读我的文章“不能设置断点的检查步骤”。如果里面有一些名词术语(术语请参看文章:调试术语)不知道或者不知道如何设置的话,呃,我会另写一篇文章讲解。

断点编程

有的时候你可能会碰到这种情况,触发一个断点以后,你发现需要修改一些值,才能使程序继续正确执行下去。例如我以前在中文版本的操作系统上,使用sscli里面(调试版)的csc.exe编译器编译一些包含语法错误或者语法警告的C#源文件的时候,csc.exe总是会莫名其妙地报告内部严重错误,然后就崩溃了。我将调试器附加上去以后,发现是一个ASSERT错误,ASSERT(lcid == 0x409),表示sscli里面的csc.exe总是默认自己在英文操作系统(或者说英文环境)里面运行。而且这一条语句会被执行很多次,手工修改lcid的值的确有点麻烦。然后我找源代码找来找去都没有找到csc.exe在哪个地方获取到这个lcid值(当然我最后找到了,下一个技巧将告诉你我是怎么找到的),然而我又不想重启系统(呃……也许我就是那种宁愿花1个钟头去找节省花费5分钟重启系统的方法的那种人……)。

这个时候如果调试器可以自动帮你重置lcid的值该有多好?幸运的是,Visual Studio提供了方法让你完成这样的工作。下面是一个简化的代码,因为我一时半会找不到sscli了:

int lcid = System.Globalization.CultureInfo.CurrentUICulture.LCID;

Console.WriteLine("lcid = {0}", lcid);

上面的代码在正常情况下,应该返回当前操作系统语言的lcid值,例如英文就是1033,中文的,呃……我忘记了。假设我们现在希望做的是,每当lcid的值为1033的时候,就自动更正为0。我们需要:

1. Console.WriteLine这一行上设置一个条件断点,条件断点的设置请参看Visual Studio调试之断点进阶篇

2. 点击Visual Studio菜单栏里面的“工具(Tools)”“宏(Macro)”“宏资源管理器(Macro Explorer)”。然后创建一个新的宏:

Imports System

Imports EnvDTE

Imports EnvDTE80

Imports EnvDTE90

Imports System.Diagnostics

Imports Microsoft.VisualBasic

Imports Microsoft.VisualBasic.ControlChars

Public Module Module1

Sub ChangeExpression()

DTE.Debugger.ExecuteStatement("lcid = 0;")

End Sub

End Module

上面DTE.Debugger.ExecuteStatement的作用,你可以理解成在立即窗口中执行lcid = 0;这条语句。

3. 右键点击刚才设置好的断点,在菜单里面选择“When Hit …”,这一次在“When Breakpoint is Hit”窗口中勾选“Run a macro:(执行一个宏)”,然后在下拉框里面选择刚才你创建的宏的名称。如果你是第一次创建宏,名称应该是:Macros.MyMacros.Module1.ChangeExpression

4. 勾选“继续执行(Continue execution)”,因为我们并不想让程序中断下来。

5. 点击确定以后,执行程序看一看结果,lcid是不是已经被自动改成0了?

数据断点

注意,这个技巧仅对C++程序调试有效(或者说native程序),而且你只能在中断模式下才能设置数据断点,另外你还只能在本机设置数据断点。

上一节的例子里,我们提到了,有的时候一个全局变量被修改了以后,你可能都找不到它是什么时候被修改的,于是夜已深,人已寐,你还在辛苦地调试到底是哪个鬼地方把这个变量的值修改了。F11 F10,……,SHIFT + F11,……,F5,靠,调过了,重来,F11F10,……

这种情况下,数据断点就很有用了,Visual Studio允许你在变量被修改的时候,中断程序的执行,是不是很酷?

默认情况下,你是找不到数据断点这个菜单的,需要执行下面的步骤把它拉出来:

1. 打开你要调试的项目。

2. 点击Visual Studio菜单栏里面的“工具(Tools)”“自定义(Customize…)”。然后在“自定义(Customize…)”窗口中选择“命令(Commands)”页签里面的“种类(Categories)”列表框里的“调试(Debug)”,找到“新数据断点(New Data Breakpoint)”,将它拖到菜单栏里面相应的位置。

然后打开或者创建一个C++项目,我们以下面的源代码为例子:

#include "stdafx.h"

int g_Variable = 0;

int _tmain(int argc, _TCHAR* argv[])

{

printf("Before modifying data breakpoints/n");

g_Variable = 1;

printf("After modifying data breakpoints/n");

return 0;

}

我们现在要Visual Studio在更改g_Variable的时候中断程序的执行。

1. 单击F11,这样程序就会在_tmain函数里面中断了,我们也就有机会设置数据断点了。

2. 点击菜单里面的“新数据断点(New Data Breakpoint)”。注意,数据断点是通过监视内存地址某一段区域更改来实现的,因此你必须提供一个内存地址(或者说就是指针吧),这里g_Variable是一个整形变量,因此你需要使用“&g_Variable”的形式来创建一个数据断点,因为整形的 大小是4个字节,因此数据断点监视的区域是4个字节,如下图所示:

3. 继续程序的执行,这时会弹出一个对话框,告诉你有一个内存地址的内容发生了变化(说明我们的数据断点生效了),这时代码行指向的是数据被修改的下一行代码,为什么会是下一行代码,下一篇文章会讲到:

呃,为什么数据断点只能在C++/C程序中才能设置?是因为托管代码有垃圾回收。而数据断点的执行原理应该是Windows内存管理里面的Guard Pages概念和VirtualProtectEx函数的实现。这个概念可以自己去查MSDN的内存管理方面的文档。

分享到:
评论

相关推荐

    Nsight Visual Studio Edition 单机调试+双机调试CUDA程序

    Nsight Visual Studio Edition是一款由NVIDIA提供的开发工具,它允许开发者在Visual Studio环境中对CUDA程序进行单机和双机调试。Nsight支持在单个计算机上进行CPU和GPU代码的调试,也可以进行两台计算机间的双机...

    Visual Studio调试基础篇.docx

    本文主要探讨的是Visual Studio调试的基础知识,尤其是断点的使用。 首先,让我们理解什么是断点。断点并不是我们在Visual Studio界面中看到的那个小红点,而是Intel系列CPU(包括AMD生产的CPU)上的一个特殊指令...

    visual studio调试技巧

    ### Visual Studio调试技巧详解 #### 一、基础知识与基本操作 **1. 如何在`j=5;`前面插入断点?** 当你遇到这样的代码片段:`for(int i=0; i; i++){ if(i==5) j=5; }` 并且所有的语句都在同一行时,可以通过以下...

    Visual Studio的PHP工具 for visual studio 2017 最新版

    2. **调试支持**:集成的PHP调试器允许开发者在Visual Studio中直接设置断点、单步执行、查看变量值,以及进行单元测试,使得调试过程更加直观和便捷。 3. **项目管理**:支持创建和管理PHP项目,包括对文件和目录...

    VisualStudioCode的Java调试器

    《Visual Studio Code的Java调试器深度解析》 Visual Studio Code(VS Code)作为一款轻量级但功能强大的源代码编辑器,已经成为了许多开发者的选择,尤其是对于Java开发来说,其集成的Java调试器更是提升了开发...

    mysql-for-visualstudio-1.2.6.msi 官方下载原版

    在安装`mysql-for-visualstudio-1.2.6.msi`之前,确保你的系统已经安装了Visual Studio 2015,并且检查.NET Framework版本是否满足插件的要求。安装过程中,遵循向导提示即可完成。安装完成后,重启Visual Studio,...

    visual studio使用技巧

    4. **调试工具**:Visual Studio的调试工具非常强大,包括断点、步进执行、查看变量值、条件断点等。`F9` 设置/取消断点,`F10` 逐过程,`F11` 逐语句。 5. **单元测试**:Visual Studio内置了 MSTest 框架,允许...

    Professional Visual Studio® 2005

    7. **调试和测试工具**:Visual Studio 2005提供了强大的调试工具,如断点、监视窗口、调用堆栈和性能分析器,帮助开发者定位和修复代码问题。同时,还引入了单元测试和集成测试工具,以保证代码质量。 8. **版本...

    VisualStudio2019手册,visualstudio2019手册pdf,C#

    Visual Studio 2019作为一款强大的集成开发环境(IDE),集成了代码编辑、调试、版本控制、项目管理等多种功能,广泛应用于Windows、Mac和跨平台应用开发。手册中涵盖了以下关键知识点: 1. **安装与配置**:如何...

    mysql-for-visualstudio-1.2.9_mysqlvs_

    综上所述,"mysql-for-visualstudio-1.2.9.msi"文件是MySQL for Visual Studio 1.2.9版的安装程序,它包含所有这些功能的实现,是Visual Studio开发人员连接和管理MySQL数据库的理想工具。通过安装这个插件,开发者...

    Visual Studio 2022调试文档

    总的来说,Visual Studio 2022的调试文档提供了全面的指导,帮助开发者熟练掌握调试技巧,提高开发效率,确保代码质量。通过深入理解和实践,开发者可以更好地应对各种复杂问题,从而提升软件开发的效率和质量。

    Visual studio express 2010

    5. **调试工具**:内置的调试器是Visual Studio的一大亮点,Express版也不例外。它可以对C#代码进行断点设置、变量查看、调用堆栈分析等,帮助开发者定位和修复问题。 6. **源代码控制**:虽然Express版本的源代码...

    Visual Studio 2022支持Php开发插件

    在Visual Studio 2022中,PHP开发者可以利用强大的调试工具,如断点设置、单步执行、查看变量值等,来定位和修复代码中的问题。这些工具使得调试过程更加直观和高效。 4. **版本控制集成** 与Git和其他版本控制...

    Visual Studio环境下可调式的PostgreSQL-9.3.0源代码

    《在Visual Studio环境下调试PostgreSQL 9.3.0源代码》 PostgreSQL是一种功能强大的开源关系型数据库管理系统,以其高度的稳定性和丰富的特性而受到广大开发者的喜爱。本文将详细探讨如何在Windows环境下,利用...

    Visual Studio 2013新特性体验

    调试器在VS2013中也有了显著改进,例如“断点条件”和“数据断点”的增强,使得调试更精确。此外,“直方图”视图能帮助分析内存分配情况,而“快速查看”(QuickWatch)窗口则能更快地查看变量值。 5. **UI设计...

    qt visual studio tools

    3. **调试支持**:在VS中可以直接调试Qt代码,设置断点、查看变量值,以及调用堆栈信息,这对于调试复杂问题非常有帮助。 4. **资源编辑器**:可以方便地编辑Qt的QRC资源文件,管理应用中的图片、音频、文本等资源...

    Visual Studio 2013 Tools

    9. **协同调试**:在多项目或团队开发环境中,Visual Studio 2013支持协同调试,多个开发者可以在同一时间独立调试自己的部分代码,共享同一套断点设置。 10. **远程调试**:除了本地调试,Visual Studio 2013还...

    Visual Studio 2013 Tools for Unity

    Visual Studio 2013 Tools for Unity 支持Unity的C#脚本断点调试,这意味着开发者可以直接在Visual Studio中设置和管理断点,而无需离开IDE。 以下是一些关于使用Visual Studio 2013 Tools for Unity进行断点调试的...

    Professional Visual Studio Extensibility

    5. **调试器扩展**:深入理解Visual Studio的调试器架构,学习如何扩展调试器功能,如添加新的调试器视图、数据可视化器和断点条件。 6. **源代码控制集成**:如何将第三方源代码控制系统与Visual Studio集成,提供...

    Visual Studio Tools for Unity

    2. **集成调试器**:VSTU允许开发者在Unity中直接设置断点,并在Visual Studio中进行调试。这使得查找和修复错误的过程更为直观,减少了在Unity编辑器和代码编辑器之间切换的时间。 3. **项目同步**:VSTU能够实时...

Global site tag (gtag.js) - Google Analytics