掌握VS2010调试 -- 入门指南

1 导言

在软件开发周期中,测试和修正缺陷(defect,defect与bug的区别:Bug是缺陷的一种表现形式,而一个缺陷是可以引起多种Bug的)的时间远多于写代码的时间。通常,debug是指发现缺陷并改正的过程。修正缺陷紧随debug之后,或者说二者是相关的。如果代码中存在缺陷,我们首先要识别造成缺陷的根本原因(root cause),这个过程就称作调试(debugging)。找到根本原因后,就可以修正缺陷。

那么如何调试代码呢?Visual Studio提供了很多用于调试的工具。有时调试需要花费大量时间去识别root cause。VS提供了许多辅助调试的便捷的工具。调试器(Debugger)包含错误列表、添加断点、可视化的程序流程、控制执行流程、Data Tips、监视窗口(watch windows)、多线程调试、线程窗口、并行调试概览以及IntelliTrace调试概览。我希望本文能够对调试功能的使用者有所裨益。请注意,本文使用VS2010。某些功能在旧版本中也是一致的,但是VS2010新增了许多features(Labeling breakpoint, Pinned DataTip, Multithreaded Debugging, Parallel debugging and IntelliTrace)。

2 如何启动调试?

可以通过VS的调试(Debug)菜单启动调试。点击调试菜单下的“启动调试”或者按F5键启动。如果你已经在代码中加入了断点,那么执行会自动开始。


图 启动调试(Start Debugging)

“附加到进程(Attach to Process)”是另一种启动调试的方法。Attach Process会为应用程序启动一个调试会话。可能我们更熟悉ASP.NET Web应用的Attach Process调试。我发了另外两篇相关的帖子。如下:

  • Debug Your ASP.NET Application that Hosted on IIS
  • Remote IIS Debugging: Debug your ASP.NET Application which is hosted on "Remote IIS Server"

通常我们通过在可能存在问题代码处加断点来启动调试。因此,我们从断点开始讲起。

3 断点(Breakpoints)

断点用于通知调试器何时何处暂停程序的执行。通过点击左边栏或者按F9键在当前行添加断点。在加断点之前,你需要知道你的代码将会出现什么错误,在什么地方停止执行。当调试器执行到断点处时,你可以使用其他的调试工具核对代码何处出现错误。


图 设置断点(Set Breakpoint)

3.1 使用断点进行调试

你已经在你想要暂停执行的地方设置了断点。现在按F5键启动调试,当程序执行到断点处时,自动暂停执行。此时你有多种方式来检查代码。命中断点(hit the breakpoint)后,加断点的行变为黄色,意指下一步将执行此行。

在中断模式下,你有多条可使用的命令,使用相应命令进行进一步的调试。


图 断点工具条(Breakpoint Toolbar)

3.1.1 逐过程(Step Over)

调试器执行到断点后,你可能需要一条一条的执行代码。”Step Over“[F10]命令用于一条一条的执行代码。这将执行当前高亮的行,然后暂停。如果在一条方法调用语句高亮时按F10,执行会停在调用语句的下一条语句上。Step Over会一次整个方法。
debug51
图: 逐过程(Step Over - F10)

3.1.2 逐语句(Step Into)

它与Step Over相似。唯一的不同是,如果当前高亮语句是方法调用,调试器会进入方法内部。快捷键是”F11“
debug52
图: 逐语句(Step Into - F11)

3.1.3 跳出(Step Out)

当你在一个方法内部调试时会用到它。如果你在当前方法内按Shift - F11,调试器会完成此方法的执行,之后在调用此方法的语句的下一条语句处暂停。

3.1.4 继续(Continue)

它像是重新执行你的程序。它会继续程序的执行直到遇到下一个断点。快捷键是”F5“

3.1.5 设置下一语句(Set Next Statement)

这是一个非常有趣的特性。设置下一语句允许你在调试的时候改变程序的执行路径。如果你的程序在某一行处暂停而且你想改变执行路径,跳到指定行,在这一行上右击,在右击菜单中选择”设置下一语句“。这样程序就会转到哪一行执行而不执行先前的代码。这在如下情况中非常有用:当你发现代码中某些行可能会导致程序的中断(break)而你不想让程序在那个时候中断。快捷键是Ctrl + Shift + F10
debug3_small
图: 设置下一语句(Set Next Statement)

3.1.6 显示下一语句(Show Next Statement [Ctrl+*])

这一行用黄色箭头标记。这行是程序继续执行时下一条将执行的语句。

3.2 断点标签(Labeling in Break Point)

这是VS2010提供的新特征(feature)。用于更好的管理断点。它使得我们能够更好的分组和过滤断点。这像是对断点的归类。如果我们添加了与某一功能相关的不同类型的断点,我们可以根据需要使能(enable)、取消(disable)、过滤(filter)这些断点。例如,假设我们要调试一下代码块。
[csharp] view plain copy
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             string[] strNames = { "Name1""Name2""Name3""Name4""Name5""Name6" };  
  6.   
  7.             foreach (string name in strNames)  
  8.             {  
  9.                 Console.WriteLine(name);   // BreakPoint  
  10.             }  
  11.             int temp = 4;  
  12.             for (int i = 1; i <= 10; i++)  
  13.             {  
  14.                 if (i > 6)  
  15.                     temp = 5;  
  16.             }  
  17.         }  
  18.   
  19.         public static void Method1()  
  20.         {  
  21.             Console.WriteLine("Break Point in Method1");   // BreakPoint  
  22.         }  
  23.   
  24.         public static void Method2()  
  25.         {  
  26.             Console.WriteLine("Break Point in Method2");  // BreakPoint  
  27.             Console.WriteLine("Break Point in Method2");  // BreakPoint  
  28.         }  
  29.   
  30.         public static void Method3()  
  31.         {  
  32.             Console.WriteLine("Break Point in Method3");  // Breakpoint  
  33.         }  
  34.     }  
执行程序将停在第一个断点处。下图给出了断点列表。
debug11_small.png
图: 断点列表
上图中Labels列都为空。下面介绍如何给断点设置标签(label)以及如何使用标签。只需在特定代码行的断点符号上右击(①)或者在断点窗口中设置(②)即可对任何断点设置标签。
debug12_small
图: 设置断点标签(Setting Breakpoint Label)
右击断点,点击编辑标签(Edit Labels),即可对任意断点添加标签。对于示例代码,我为所有断点的标签起了易于理解的名字。
debug13
图: 添加断点标签(Adding Breakpoint Label)
这些标签如何辅助我们调试呢?现在,所有断点都是使能的(enabled)。如果你不想调试method2,一般情况下你必须去对应的方法中一个一个的取消断点,但这里你可以通过标签名过滤或者搜索它们,然后选中它们以方便的取消它们。
debug14_small
图: 使用标签过滤断点(Filter Breakpoint Using Labels)
断点标签到此介绍完毕。我举的例子非常简单,但是断点标签在你调试大量代码,多个工程等情况下非常有用。

3.3 条件断点(Conditional Breakpoint)

假设你在多次迭代(循环)处理数据而你只想调试其中某几次迭代。这意味着你想根据某些特定条件暂停你的程序。Visual Studio断点允许你设置条件断点。当且仅当条件满足时,调试器才会停住。
首先,你需要在你想暂停执行处设置断点。然后右击红色的断点图标。右键菜单中点击”条件“。
debug5_small
图: 设置断点条件(Set Breakpoint Condition)
点击右键菜单中的”条件“后,会弹出下面的对话框设置断点的条件。
debug6
图: 断点条件设置
假设你要调试下面的代码块:
[csharp] view plain copy
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.          string [] strNames = { "Name1","Name2""Name3""Name4""Name5""Name6"};  
  6.   
  7.             foreach(string name in strNames)  
  8.             {  
  9.                  Console.WriteLine(name); // Breakpoint is here  
  10.             }  
  11.         }  
  12.     }  
你在Console.WriteLine()语句处设置了断点。当执行程序时,每次for-each循环都会停住。如果你想让代码只在name="Name3"时停住,该怎么办呢?非常简单,你只需使用条件name.Equals("Name3")。
debug7
图: 设置断点条件
查看断点符号。它应该看上去像是一个加(+)号在断点符号内部,这表示该断点是条件断点。
debug9
图: 条件断点符号(Conditional Breakpoint Symbol)
设置断点的条件之后,在调试程序,调试器只会在满足给定条件时才停住。
debug10
图: 条件断点命中(Conditional Breakpoint hit)
条件输入框的自动补全(intellisense):上面给出的断点条件非常简单,可以非常容易的写到条件文本框中。有时你可能需要定义很大很复杂的条件。不必担心,VS为条件文本输入框也提供了自动补全功能。因此,在条件框中输入就像是在编辑器中一样方便。如下图。
debug8_small
图: 条件文本框的自动补全(intellisense in condition textbox)
我几乎讲解了条件断点的所有内容。除了下面这点。在条件窗口中有两个选项:
  1. Is True
  2. Has Changed
我们已经看到”Is True“选项的用途了。”Has Changed“用在当你想在某些值变为某些特定值的时候停住。

3.4 导入/导出断点(Import / Export Breakpoint)

3.5 断点命中计数(Breakpoint Hit Count)

3.6 Breakpoint When Hit

3.7 断点筛选器(Breakpoint Filter)

你可以限制断点只对特定进程或线程有效。这在进行多线程程序的调试时非常有用。右击断点选”筛选器“即可打开筛选器窗口。
debug40
图: 断点筛选器(Breakpoint Filter)
在筛选规则中,你可以设置进程名,进程Id,机器名,线程ID等。我会在多线程调试小节中详述其用法。

4 数据便签(Data Tip)

数据便签是应用程序调试期间用于查看对象和变量的一种高级便签消息。当调试器执行到断点时,将鼠标移到对象或者变量上方时,你会看到它们的当前值。你甚至可以看到一些复杂对象(如dataset,datatable等等)的细节。数据便签左上角有一个“+”号用于展开它的子对象或者值。
debug20
图: 调试时的数据便签(DataTips During Debugging)
几个月前,我发过一篇关于VS 2010 DataTip Debugging Tips的文章。
下面是一些在调试时有用的特性。

4.1 Pin Inspect Value During Debugging

4.2 Drag-Drop Pin Data Tip

4.3 Adding Comments

4.4 Last Session Debugging Value

4.5 Import Export Data Tips

4.6 Change Value Using Data Tips

4.7 Clear Data Tips

5 监视窗口(Watch Windows)

5.1 局部变量(Locals)

列出当前方法中的所有变量。当调试器停在某特定断点并打开Autos窗口时,将展示当前范围中与此值相关的变量。
debug30_small
图:Local Variables

5.2 自动窗口(Autos)

这些变量由VS调试器在调试的时候自动检测。VS检测与当前语句相关的对象或变量,基于此列出Autos变量。Autos Variable的快捷键是Ctrl + D + A。
debug31_small
图:Autos - Ctrl + D, A

5.3 监视(Watch)

Watch窗口用于添加变量。你可以添加任意多个变量。添加方法是,右击变量并选择“Add to Watch”。
debug32_small
图:Watch - Ctrl + D, W
也可以使用拖放(Drag and Drop)将变量添加到监视窗口中。从监视窗口中删除变量的方法是,右击变量并选择“Delete Watch”。通过调试窗口,也可以在运行时编辑这些变量值。

有4个可同时使用的监视窗口。
debug33_small
图:多个监视窗口

若果变量中含有对象实例,左边会有一个“+”号用于查看对象的属性和成员。
debug34_small
图:展开监视变量

5.3.1 Creating Object ID

Visual Studio调试器提供另外一个强大的功能,支持我们为对象的任何一个特定实例创建一个对象ID(object ID)。这可以用于在任何时间监控任意对象,甚至是该对象位于范围(scope)之外。在监视窗口(watch window)右击特定对象变量,再单击“Make Object ID”即可创建Object ID。
debug35_small
图: 创建Object ID
在对特定对象变量创建Object ID之后,Visual Studio会给这个对象添加一个数码和“#”号,用来表示。
debug36_small
图:添加Object ID后

5.4 

6 即时窗口(Immediate Window)

即时窗口是开发人员常用的功能。它可以在不改变当前调试步骤的情况下修改变量值或者执行一些语句。我们可以通过菜单调试 > 窗口 > 即时(Debug > Window > Immediate Window)打开即时窗口。即时窗口支持一组命令,可在调试的任何时刻执行。它也支持Intellisense。在调试期间,我们可以在即时窗口中执行任何命令或者代码语句。
debug37
图:基本即时窗口(Basic Immediate Window)
这是对所有开发人员来说最为常用的特性,因此我就不一一介绍即时窗口的每一条命令了。

7 调用堆栈(Call Stack)

8 调试多线程程序(Debugging Multithreaded Program)

8.1 Exploring Threads Window

8.2 Flag Just My Code

8.3 Break Point Filter - Multithread Debugging

9 调试并行程序(Debugging Parallel Program)

9.1 Parallel Task and Parallel Stacks

10 Debugging with IntelliTrace

10.1 Overview

10.2 Mapping with IntelliTrace

10.3 Filter IntelliTrace Data

11 调试常用快捷键(Useful Shortcut Keys For VS Debugging)

Shortcut Keys Descriptions
Ctrl-Alt-V, A Displays the Auto window
Ctrl-Alt-B Displays the Breakpoints dialog
Ctrl-Alt-C Displays the Call Stack
Ctrl-Shift-F9 Clears all of the breakpoints in the project
Ctrl-F9 Enables or disables the breakpoint on the current line of code
Ctrl-Alt-E Displays the Exceptions dialog
Ctrl-Alt-I Displays the Immediate window
Ctrl-Alt-V, L Displays the Locals window
Ctrl-Alt-Q Displays the Quick Watch dialog
Ctrl-Shift-F5 Terminates the current debugging session, rebuilds if necessary, and starts a new debugging session.
Ctrl-F10 Starts or resumes execution of your code and then halts execution when it reaches the selected statement.
Ctrl-Shift-F10 Sets the execution point to the line of code you choose
Alt-NUM * Highlights the next statement
F5 If not currently debugging, this runs the startup project or projects and attaches the debugger.
Ctrl-F5 Runs the code without invoking the debugger
F11 Step Into
Shift-F11 Executes the remaining lines out from procedure
F10 Executes the next line of code but does not step into any function calls
Shift-F5 Available in break and run modes, this terminates the debugging session
Ctrl-Alt-H Displays the Threads window to view all of the threads for the current process
F9 Sets or removes a breakpoint at the current line
Ctrl-Alt-W, 1 Displays the Watch 1 window to view the values of variables or watch expressions
Ctrl-Alt-P Displays the Processes dialog, which allows you to attach or detach the debugger to one or more running processes
Ctrl-D,V IntelliTrace Event
到此本文结束。希望你喜欢本文。请分享你的反馈和建议。

12 深入学习(Further Study)

  • Debugging Task-Based Parallel Applications in Visual Studio 2010 By Daniel Moth and Stephen Toub
  • Debugging With IntelliTrace

13 总结(Summary)

本文介绍了调试过程的基本内容。介绍了如何使用VS调试一个应用程序。我解释了几乎所有重要的工具以及它们的使用方法。对于并行程序调试,我只讲了基础部分。在深入学习小节中,深入讲解了并行调试过程。如果你感兴趣,请阅读。我的主要目的是涵盖Visual Studio中提供的几乎所有调试工具。希望你从本文中学到了一些新知识。

“自动窗口”(Autos):当前使用的变量

“局部窗口”(Locals):在范围内的所有变量

“监视N”(Watch):可定制(N从1到4)


Step Into(逐语句):执行并移动到下一条语句(实际上,跳入上一条语句的代码块,此代码块的第一条)

Step Over(逐过程):执行并跳到下一条语句,但不进入上一条语句的代码块

Step Out(跳出):执行到代码块结尾


命令窗口(Command)

即时窗口(Immediate):主要用于计算表达式

参考资料:

[1] Mastering Debugging in Visual Studio 2010 - A Beginner's Guide

[2] bug和缺陷的区别

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统】进程管理

进程管理 进程的基本概念 程序的顺序执行及其特征 程序的顺序执行:仅当前一操作(程序段)执行完后&#xff0c;才能执行后续操作。 程序顺序执行时的特征&#xff1a;顺序性&#xff0c;封闭性&#xff0c;可再见性。 前趋图 前趋图(Precedence Graph)是一个有向无循环图&#…

va_list va_start va_end的使用

<pre name"code" class"cpp" style"color: rgb(51, 51, 51); white-space: pre-wrap; word-wrap: break-word;"><strong>一、 从printf()开始</strong> 从大家都很熟悉的格式化字符串函数开始介绍可变参数函数。 原型&#xf…

Linux学习之CentOS(三)----将Cent0S 7的网卡名称eno16777736改为eth0

【正文】 Linux系统版本&#xff1a;CentOS_7&#xff08;64位&#xff09; 一、前言&#xff1a; 今天又从Centos 6.5装回了Centos 7&#xff0c;毕竟还是要顺应潮流嘛。安装完成之后&#xff0c;发现发现CentOS 7默认的网卡名称是eno16777736&#xff0c;如图所示&#xff1a…

数据库事务的隔离机制

数据库事务(Database Transaction) &#xff0c;是指作为单个逻辑工作单元执行的一系列操作&#xff0c;要么完全地执行&#xff0c;要么完全地不执行。----百度百科就是说你定义一组数据库操作&#xff0c;然后告诉数据库说这些操作要么都成功&#xff0c;要么都不成功。类似于…

如何使用CppUnit进行单元测试

http://www.vckbase.com/document/viewdoc/?id1762 一、前言 测试驱动开发(TDD)是以测试作为开发过程的中心&#xff0c;它坚持&#xff0c;在编写实际代码之前&#xff0c;先写好基于产品代码的测试代码。开发过程的目标就是首先使测试能够通过&#xff0c;然后再优化设计结构…

iOS开发网络篇—Reachability检测网络状态

前言&#xff1a;当应用程序需要访问网络的时候&#xff0c;它首先应该检查设备的网络状态&#xff0c;确认设备的网络环境及连接情况&#xff0c;并针对这些情况提醒用户做出相应的处理。最好能监听设备的网络状态的改变&#xff0c;当设备网络状态连接、断开时&#xff0c;程…

网络七层协议 五层模型 TCP连接 HTTP连接 socket套接字

socket&#xff08;套接字&#xff09;是通信的基石&#xff0c;是支持TCP/IP协议的网络通信的基本操作单元&#xff0c;包含进行网络通信必须的五种信息&#xff1a;连接使用的协议&#xff0c;本地主机的IP地址&#xff0c;本地进程的协议端口&#xff0c;远地主机的IP地址&a…

【VC++技术杂谈005】如何与程控仪器通过GPIB接口进行通信

在工控测试系统中&#xff0c;经常需要使用到各类程控仪器&#xff0c;这些程控仪器通常具有GPIB、LAN、USB等硬件接口&#xff0c;计算机通过这些接口能够与其通信&#xff0c;从而实现自动测量、数据采集、数据分析和数据处理等操作。本文主要介绍如何与程控仪器通过GPIB接口…

标题在上边框中的html(fieldset标签)

<fieldset> <legend>标题</legend> 内容 </fieldset> 转载于:https://www.cnblogs.com/lswbk/p/4952820.html

移除项目中的CocoaPods

在项目中移除CocoaPods cocoaPods虽然很方便&#xff0c;但是我是真心的不喜欢用它&#xff0c;总是出错如果你觉得CocoaPods让你的项目出现了问题&#xff0c;不好用甚至是恶心&#xff0c;想将其从项目中彻底移除&#xff0c;也有方法&#xff1a; 1.删除工程文件夹下的Podf…

popoverController(iPad)

一、设置尺寸 提示&#xff1a;不建议&#xff0c;像下面这样吧popover的宽度和高度写死。 1 //1.新建一个内容控制器2 YYMenuViewController *menuVc[[YYMenuViewController alloc]init];3 4 //2.新建一个popoverController&#xff0c;并设置其内容控制器5 s…

fastQC

Fastqc用途 FastQC aims to provide a simple way to do some quality control checks on raw sequence data coming from high throughput sequencing pipelines. It provides a modular set of analyses which you can use to give a quick impression of whether your data …

C++ Handle(句柄) part1

本文是我学习C&#xff0b;&#xff0b;沉思录第6章的笔记 本文主要讲述了Handle类的概念&#xff0c;定义方法以及写时复制技术。 在前文(Surrogate代理类)的讲解中我们了解到了代理的实现方法. 代理类有很多好处,但是麻烦的是每次都得进行复制.如果该类是经常使用并且member很…

Swift调用Objective C的FrameWork

很多Github的库经过很多年的发展&#xff0c;源码都是OC写的&#xff0c;&#xff0c;所以&#xff0c;用Swift调用OC的库就是开发中难免遇到的的一个问题&#xff0c;本文以AFNetworking为例&#xff0c;讲解如何跨语言调用。 第一步 创建一个空的工程 注意&#xff0c;语言选…

显式(静态)调用: LIB + DLL + .H

1、编程时用ad.h,ad.lib,放在项目当前目录里2、在头文件中加入#include "ad.h"3、在Project Setting–>Link–>Object/library modules加入ad.lib执行时将ad.dll跟你的程序放在同一目录。 就可以直接调用dll中的函数了 当前目录 转载于:https://www.cnblogs.co…

接入支付宝出现交易订单处理失败,请稍后再试(ALI64)的错误

上次在接入支付宝的时候就碰到了交易订单处理失败&#xff0c;请稍后再试&#xff08;ALI64&#xff09;这样的错误&#xff0c;后来经过排查和总结&#xff0c;一般来讲这种问题都是公钥和私钥没有正确配置造成的。支付宝这边为了保证数据在传输时不被篡改&#xff0c;使用了r…

支付宝集成交互流程

交互流程 功能流程 流程说明&#xff08;以Android平台为例&#xff09;&#xff1a; 第4步&#xff1a;调用支付接口&#xff1a;此消息就是本接口所描述的开发包提供的支付对象PayTask&#xff0c;将商户签名后的订单信息传进pay方法唤起支付宝收银台&#xff0c;订单格式具体…

VxLAN基础

转自&#xff1a;http://blog.csdn.net/freezgw1985/article/details/16354897 一 . 为什么需要Vxlan1. vlan的数量限制4096个vlan远不能满足大规模云计算数据中心的需求2. 物理网络基础设施的限制基于IP子网的区域划分限制了需要二层网络连通性的应用负载的部署3. TOR交换机MA…

C语言程序代码优化

我认为一个好的用于科学计算的程序代码应该&#xff1a;算法漂亮精妙&#xff0c;程序简洁易懂&#xff0c;运算快速&#xff0c;节省内存。这里有的地方是矛盾的&#xff0c;比如简洁vs易懂&#xff0c;时间vs空间&#xff0c;找个平衡吧。目前来看时间要比空间宝贵一些。写程…

如何在苹果官网下载旧版本的Xcode 方法

1 在百度里输入“苹果开发者中心“&#xff0c;进入以下页面。点击页面中的“Member Center" 2 出现登录界面。这是需要苹果开发者帐号的&#xff0c;没有帐号的可以选择“Create Apple ID”进行注册。已经注册的选择“Sign In"登录 3 页面跳转后&#xff0c;选择…