Visual Studio调试器 .NET技巧和诀窍

70

我多年来一直在使用VS的调试器,但偶尔会发现一个以前从未注意到的功能,并想:“该死!我怎么会错过它呢?它太有用了!”

[免责声明:这些技巧适用于C#项目的VS 2005版本,在旧版本的VS或其他语言中不保证可用]

跟踪对象实例

正在使用给定类的多个实例?如何区分它们? 在垃圾回收之前的编程时代,很容易跟踪引用-只需查看内存地址。在.NET中,你不能这样做-对象可能会移动。 幸运的是,监视视图可以让你右键单击监视并选择“创建对象ID”。

这将在实例的值后附加{1#}、{2#}等,有效地为实例赋予了唯一的标签。

标签将在该对象的生命周期内保留。

监视变量的有意义的值

默认情况下,监视变量的值是其类型。如果要查看其字段,必须展开它,如果字段很多或者它们执行一些复杂操作,这可能需要很长时间(甚至超时!)。

然而,一些预定义的类型显示了更有意义的信息:

  • 字符串显示它们的实际内容
  • 列表和字典会显示它们的元素计数等。

如果我的自定义类型也能这样该多好啊?

嗯...

...通过.NET反编译器进行一些质量时间,就可以轻松完成这个任务,只需要在我的自定义类型上使用DebuggerDisplay属性即可:

[System.Diagnostics.DebuggerDisplay("Employee: '{Name}'")]
public class Employee {
    public string Name { get { ... } }
    ...
}

重新运行,它可以正常工作。

关于这个主题,这里有更多的信息:MSDN

在所有异常处中断

...即使是在代码中被处理过的异常! 我知道,我是个萌新,竟然没有从出生以来就知道这个,但是无论如何,这里还是有帮助到别人的可能性:

您可以强制调试过程在每次抛出异常时都进入调试模式。 您是否曾经进行了几个小时的错误查找,最终发现了像这样的代码段?

try {
    runStrangeContraption();
} catch(Exception ex) {
    /* TODO: Will handle this error later */
}

在这些情况下捕获所有异常真的很方便。
可以通过 调试 > 异常... (Ctrl-Alt-E) 启用此功能。选中每种需要的异常类型的 '抛出' 列中的框。


那些对我来说是一些令人头痛的时刻。
你想分享你的吗?


这更像是一个备忘录式的帖子,而不是一个问题,但也许其他人会发现它有用。希望我自己也能学到一些新东西。 - Cristian Diaconescu
可能是"Visual Studio .NET调试器的"隐藏秘密"?的重复问题。 - Roger Pate
14个回答

2

以下是我的两个建议,其中一个希望大家广泛使用:

Debug.Assert(<condition>, <message>)

第二个DebuggerHidden:
<DebuggerHidden()> _
Public Sub ReadDocumentProperty(ByVal propertyName As String, ByRef PropVal As Integer, ByVal DefaultVal As Integer)
    Try
        Dim prop As Office.DocumentProperty
        prop = CustomProps.Item(propertyName)
        PropVal = CType(prop.Value, Integer)
    Catch
        PropVal = DefaultVal
    End Try
End Sub

即使您设置了Debug,Exceptions和Break on thrown exceptions,此处的异常也不会被捕获。

1

将IDE设置为在异常发生时中断,即使我们没有设置任何调试点,这个怎么样?

调试--> 异常-->公共语言运行时异常-->已抛出

这使得查找隐藏的异常处理问题变得轻而易举。实际上,每个开发人员都应该在整个开发过程中设置这种设置,以避免任何未处理或甚至已处理的异常。


非常有用,但是如果开发人员依赖异常来进行“正常”代码流程,它可能会被破坏。在我工作的大型项目中,仅在程序初始化所需的时间内就会“随意”抛出和捕获多个异常。我通常会启动进程,等待其初始化,然后才启用“在抛出异常时中断”。 - Cristian Diaconescu

1
创建一个宏,将其附加到进程并分配给未使用的键盘快捷方式。比起手动操作:调试 -> 附加到进程 -> 在进程列表中搜索进程 -> ... 要快得多。

2
Ctrl-Sh-P 是指“附加到进程”。但你仍需要查找和输入进程名称。 - Cristian Diaconescu

0
在非托管代码中,您可以设置“数据断点”。它们使用CPU的调试寄存器发出INT3,调试器会在该指令上停止,而在运行时没有任何开销(在旧版本中,调试器通过检查内存逐步执行程序......速度慢!)
如果您在已知地址(堆栈/堆变量被破坏)上有一些损坏,则此功能非常有用。
此外,ide\packages\debugger中的AutoExp.dat可以自定义以显示您的数据结构。
指针、mb在监视窗口中显示十六进制转储 http://msdn.microsoft.com/en-us/magazine/dd252945.aspx 好吃!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接