Visual Studio 调试技巧

写在前面:假定你在平常的工做中使用到了Visual Studio,并指望了解一些调试技巧来提升工做效率,也许本文适合你。如下Visual Studio简称vs。ide

1、入门

以最简单的控制台应用程序为例,代码以下:工具

 1 class Program
 2 { 3 static void Main(string[] args) 4  { 5 int result = Sum(2, 3); 6 Console.WriteLine("2+3={0}", result); 7  } 8 9 private static int Sum(int a,int b) 10  { 11 return a + b; 12  } 13 }

调试的根本目的是跟踪代码、程序的状态,判断是否按照指望的行为运行。经常使用的跟踪手段有控制台输出、日志输出以及断点调试。spa

  1. 控制台输出用于开发环境,能够在vs输出窗口中查看程序输出的内容以下图所示:

因为是控制台应用程序,Console.WriteLine() 输出的内容不会显示在输出窗口,故采用Trace.WriteLine() 。对非控制台应用程序,Console.WriteLine() 输出的内容会正常显示在输出窗口。3d

2. 日志输出用于开发环境和生产环境,但更多用于生产环境,用来收集程序的运行信息。经常使用的日志组件有Log4Net、NLog以及自定义日志组件。依据问题严重程度大体分为严重错误、错误、警告、信息以及调试信息等几个级别。可结合实际需求灵活配置。调试

3. 断点调试多用于开发环境,经过设置断点,让程序在指定的位置暂停,以便观察上下文环境状况。日志

以上图为例,添加断点后,鼠标移动到变量名上,能够观察一些变量的值。对于复杂类型的变量,经过选中变量,右键选择快速监视的方式。避免鼠标移动后,监视的信息消失。code

以上三种调试方法中,对于开发环境而言,使用最为频繁的方法当数断点调试。后面以断点调试为主,深刻介绍。orm

2、进阶

  • 启动外部程序blog

要使用断点调试,须要知足一些断点调试的条件。对于可执行程序,如控制台应用程序、窗体应用程序、WPF应用程序以及Web应用程序,启动调试后,能够在指望的位置添加断点。而对于如动态库类型,不能够直接启动调试。想要调试这类项目,有两种方式。一种是能够设置项目属性中的启动操做,指定引用该动态库的可执行程序路径。继承

另外一种方式是运行调用了动态库的可执行程序,经过附加可执行程序进程的方式来调试。

  • 附加进程

新建 DllDemo 动态库项目,添加 MyMath 类,添加静态方法 Max(int a,int b) 。代码以下:

 1 using System;
 2 
 3 namespace DllDemo 4 { 5 public class MyMath 6  { 7 public static int Max(int a,int b) 8  { 9 return Math.Max(a, b); 10  } 11  } 12 }

 添加对 DllDemo 动态库项目引用, 并修改控制台应用程序以下。为了方便后续调试,控制台应用程序中添加 Console.Read()。

 1 using DllDemo;
 2 using System; 3 using System.Diagnostics; 4 5 namespace DebugDemo 6 { 7 class Program 8  { 9 static void Main(string[] args) 10  { 11 Console.WriteLine("等待键盘输入..."); 12 13  Console.Read(); 14 15 int result = Sum(2, 3); 16 17 Console.WriteLine(string.Format("2+3={0}", result)); 18 19 result = MyMath.Max(2, 3); 20 21 Console.WriteLine(string.Format("MyMath.Max(2, 3)={0}", result)); 22  } 23 24 private static int Sum(int a, int b) 25  { 26 return a + b; 27  } 28  } 29 }

运行控制台应用程序DebugDemo.exe ,附加该进程,在合适的位置添加断点。

  • 查看调用堆栈

当程序包含接口继承、抽象类继承等逻辑,致使结构过于复杂,知道功能入口以及出口,想要了解过程时,调用堆栈会比较有用。如下面代码为例:

private static void DoWork()
{
    DoWork1();
}

private static void DoWork1() { DoWork2(); } private static void DoWork2() { DoWork3(); } private static void DoWork3() { Console.Write("DoWork3"); }

假设知道功能入口为DoWork,功能结果为DoWork3,想要了解DoWork3的调用逻辑,能够在DoWork3中设置断点,启动调试后打开调用堆栈窗口,以下图:

  • 异常设置

当程序运行之后,结果不是预期的。初步猜想发生了异常,因为某些缘由,捕获了异常,却未妥善处理,致使异常信息被“吞”掉。此时,异常设置会格外有效。如下面代码为例:

private static void TryToDivideByZero()
{
    try { int a = 9; int b = 0; int c = a / b; } catch(Exception ex) { Console.WriteLine(ex.Message); } }

因为方法中存在异常,又有异常捕获,后续逻辑会被打断,此时对异常设置作以下设置:

从新调试程序会有以下结果,方便快速定位异常发生点。

3、高级

在某些场景下,开发环境运行正常,非开发环境运行异常,依赖常规手段没法定位问题缘由,想要断点调试,非开发环境运行缺乏VS时,远程调试会比较有效。

在VS安装目录下拷贝远程调试所需的文件夹x86,x64到非开发环境

依据远程目标机系统环境,运行x86/x64文件夹下msvsmon.exe,选择工具中的选项菜单作以下配置:

运行待调试程序后,在VS中选择调试>附加到进程(ctrl+alt+p),设置链接类型,链接目标(远程ip地址或计算机名)后查找,会自动列出相关内容。

在可用进程中选择对应的进程

在合适的位置添加断点便可开始调试了

相关文章
相关标签/搜索