Visual Studiodebugging器提示和技巧

我已经和VS的debugging工作了好几年了,但是我偶尔偶尔会遇到一个我从未注意过的特性,并且觉得“该死!我怎么可能错过了这个function呢?这非常有用!

[免责声明:这些技巧在VS 2005中的C#项目中工作,没有保证VS或其他语言的旧版本]

跟踪对象实例

处理给定类的多个实例? 你怎么能把他们分开? 在预先垃圾回收编程的日子里,很容易跟踪引用 – 只要看内存地址即可。 使用.NET,你不能这样做 – 对象可以移动。 幸运的是,手表视图可让您右键单击手表并select“制作对象ID”。

手表视图http://img403.imageshack.us/img403/461/52518188cq3.jpg

这会在实例的值之后追加一个{1#},{2#}等,有效地给这个实例一个唯一的标签。 它看起来像这样:

编号实例http://img383.imageshack.us/img383/7351/11732685bl8.jpg

该标签在该对象的生命周期中被持久化。

观察variables的有意义的值

默认情况下,监视variables的值是types。 如果你想看到它的领域,你必须扩展它,如果有很多领域或者做了一些复杂的事情,这可能需要很长时间(甚至超时)。

但是,一些预定义types显示更有意义的信息:

  • string显示其实际内容
  • 列表和字典显示其元素计数等

有意义的信息http://img205.imageshack.us/img205/4808/37220487md1.jpg

这对我自己的types不是很好吗?

嗯…

…使用.NET Reflector的一些高质量时间显示了使用我的自定义types上的DebuggerDisplay属性可以轻松实现这一点:

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

…重新运行,并…

达达! http://img60.imageshack.us/img60/926/79816018ha1.jpg

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

打破所有例外

甚至在代码中处理的 我知道,自从我出生以来,我一直都不知道这件事,但是无论如何,这个事情总是会发生的 – 也许这有助于某个人某一天:

每次抛出exception时,都可以强制debugging进程进入debugging模式。 曾经花了几个小时才find这样一段代码?

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

捕获所有的exception在这些情况下非常方便。 这可以从debugging>例外…(Ctrl-Alt-E)启用。 在“Thrown”列中勾选您需要的每种types的exception。


那些是我的一些额头拍打的时刻。 你愿意分享你的吗?

两个代码中的技巧:

我真的很喜欢System.Diagnostics.DebuggerStepThrough属性; 你可以将它附加到一个类,方法或属性,以使VS在debugging时默认不input代码。 我更喜欢DebuggerHidden属性,因为如果你真的需要debugging,它仍然允许你在被忽略的代码中放置断点。

另一个(有时)有用的调用是System.Diagnostics.Debugger.Launch() ; 当执行命中时,你将看到“select一个debugging器”对话框,一个debugging器将启动。 有点粗鲁,但有用特别讨厌附加到进程,就像一个进程被其他人产生并立即执行你的代码。

 try { // do something big } catch { // breakpoint set here: throw CantHappenException("something horrible happened that should never happen."); } 

你如何看到最初抛出的exception? 在监视窗口中,input$ exception

这是我学到的另一个巧妙的技巧:

 System.Diagnostics.Debugger.Break() 

以编程方式使debugging器在下一条指令中断开。 真正好的部分是,这也适用于在发布模式下编译的程序,无需debugging信息。

我总是确保在我创build的新线程上设置“名称”属性。 这样,当我在debugging时,我可以更容易地识别不同的线程。

当然,请查看当天的VS提示:

http://blogs.msdn.com/SaraFord/

一些来自我

  • 在工具 – >选项 – >debugging中取消选中“启用我的代码”选项。
  • 有条件的断点 – 他们几乎每天都拯救我的生命
  • 如果事情变得糟糕, 请使用.NET框架源代码

在即时窗口中.load sos

工具 – >附加到进程 – 容易忘记,但是用它可以在网页中debugging脚本,在另一个进程中加载​​托pipe代码(认为插件模型),甚至是非托pipe代码。 要小心让它自动select你感兴趣的debuggingtypes。

跟踪点(和其他断点function…右键点击断点,玩得开心)! – http://blogs.msdn.com/saraford/archive/2008/06/13/did-you-know-you-can-use-tracepoints-to-log-printf-or-console-writeline-info-without -编辑-你的代码,237.aspx

即时窗口真棒。

如果部署应用程序(并可以到达可以复制问题的机器),则远程debugging非常有用。

还有更多。 尝试进入WinDbg和SoS!

我发现模块窗口很有用。 它告诉debugging器是否加载了所需的dll以及加载了哪个版本的dll。 它也可以让你手动加载或卸载一个DLL。

条件中断是非常有用的,如果你有很多重复的代码,但是只在特定条件下失败,比如循环中的代码,从循环中调用的方法,或者从多个线程调用的方法。 将break语句放在关注的位置,并设置其条件以匹配错误情况。 (这里有个简单的例子。)

我从两个人那里得到一个希望大家都用到的地方:

 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 

即使你有debugging,例外,抛出抛出exception设置,这里的exception不会被捕获。

创build一个macros用于附加到进程并分配给一个未使用的键盘快捷方式。 比去往快得多:debug – > attach to process – >在进程列表中search进程 – > …

如何将IDE设置为发生exception时突破,即使我们没有设置任何debugging点。

debugging – >exception – > Commmon语言运行时exception – >抛出

这使得查找隐藏的exception处理问题变得轻而易举。 事实上,这是每个开发者都应该设定的开发环境,以避免任何不受控制的甚至是处理下面的exception。

在非托pipe代码中,您可以设置“数据断点”。 他们使用CPU的debugging寄存器来发出一个INT3,debugging器在该指令停止运行时没有任何开销(在较旧的版本中,debugging器通过程序检查内存…..慢!

如果你在knwon地址有一些腐败(堆栈/堆可变),这是很有用的。

也可以定制ide \ packages \ debugger中的AutoExp.dat以显示您的数据结构。

指针,mb在监视窗口中显示一个hex转储http://msdn.microsoft.com/en-us/magazine/dd252945.aspx

百胜!