我已经和VS的调试器一起工作多年了,但我偶尔会遇到一个我以前从未注意过的功能,并且想想“该死的!我怎么能错过它?它是如此有用!“
[免责声明:这些提示适用于VS 2005中的C#项目,不保证VS或其他语言的旧版本]
使用给定类的多个实例?你怎么能分开他们? 在垃圾收集前编程时,很容易跟踪引用 - 只需查看内存地址即可。使用.NET,你不能这样做 - 对象可以移动。 幸运的是,通过手表视图,您可以右键单击手表并选择“创建对象ID”。
watches view http://img403.imageshack.us/img403/461/52518188cq3.jpg
这会在实例的值之后附加{1#},{2#}等,从而有效地为实例提供唯一标签。它看起来像这样:
numbered instance http://img383.imageshack.us/img383/7351/11732685bl8.jpg
标签在该对象的生命周期内保持不变。
默认情况下,监视变量的值是它的类型。如果你想看到它的字段,你必须扩展它,如果有很多字段或它们做了一些复杂的事情,这可能需要很长时间(甚至超时!)。
但是,某些预定义类型显示更有意义的信息:
meaningful info http://img205.imageshack.us/img205/4808/37220487md1.jpg
为我自己的类型拥有它不是很好吗?
嗯...
...使用.NET Reflector的一些高质量时间显示了使用我的自定义类型上的DebuggerDisplay
属性轻松完成此操作:
[System.Diagnostics.DebuggerDisplay("Employee: '{Name}'")]
public class Employee {
public string Name { get { ... } }
...
}
...重新开始,......
ta da! http://img60.imageshack.us/img60/926/79816018ha1.jpg
此处有关于此主题的更多信息:MSDN
...甚至是代码中处理的那些! 我知道,自从我出生以来,我就是一个不知道这件事的人,但无论如何它仍然存在 - 也许有一天这会对某人有所帮助:
每次抛出异常时,您都可以强制调试进程进入调试模式。曾经花了几个小时寻找一个只是为了遇到这样的代码吗?
try {
runStrangeContraption();
} catch(Exception ex) {
/* TODO: Will handle this error later */
}
在这些情况下捕获所有异常非常方便。 这可以从 Debug>启用。例外...(Ctrl-Alt-E)。勾选“Thrown”列中的框,了解您需要的每种类型的异常。
这对我来说是一些前额拍打的时刻。 你愿意和你分享吗?
答案 0 :(得分:19)
try {
// do something big
}
catch {
// breakpoint set here:
throw CantHappenException("something horrible happened that should never happen.");
}
您如何看待最初抛出的异常?在观察窗口中,输入$ exception
答案 1 :(得分:17)
这是我学到的另一个巧妙的技巧:
System.Diagnostics.Debugger.Break()
以编程方式使调试器在下一条指令上中断。 真的很好的部分是,这也适用于以发布模式编译的程序,没有调试信息。
答案 2 :(得分:12)
我总是确保在我创建的新线程上设置“Name”属性。这样,当我调试时,我可以更容易地识别不同的线程。
答案 3 :(得分:9)
当然,请查看当天的VS提示:
答案 4 :(得分:7)
我的一些人
答案 5 :(得分:7)
两个代码内的技巧:
我非常喜欢System.Diagnostics.DebuggerStepThrough属性;您可以将它附加到类,方法或属性,以使VS在调试时默认不输入代码。我比DebuggerHidden属性更喜欢它,因为如果你真的需要调试它,它仍然允许你在被忽略的代码中放置断点。
另一个(有时)有用的电话是System.Diagnostics.Debugger.Launch();当执行命中时,您将看到“选择调试器”对话框,调试器将启动。有点粗鲁,但有用,特别讨厌附加到进程,比如由另一个进程生成的进程并立即执行您的代码。
答案 6 :(得分:6)
.load sos
:)
答案 7 :(得分:4)
工具 - >附加到进程 - 容易忘记,但有了它我可以在网页中调试脚本,在另一个进程中加载托管代码(想想加载项模型),甚至是非托管代码。小心让它自动选择你感兴趣的调试类型。
跟踪点(和其他断点功能......右键点击断点并享受乐趣)! - http://blogs.msdn.com/saraford/archive/2008/06/13/did-you-know-you-can-use-tracepoints-to-log-printf-or-console-writeline-info-without-editing-your-code-237.aspx
即时窗口非常棒。
如果您部署应用程序(并且可以访问可以重现问题的计算机),Remote Debugging非常有用。
还有更多。尝试进入WinDbg和SoS!
答案 8 :(得分:4)
我发现模块窗口很多次都很有用。它告诉调试器是否加载了所需的dll以及加载了哪个版本的dll。它还允许您手动加载或卸载DLL。
答案 9 :(得分:3)
如果你的代码重复很多但只在一组特定的条件下失败,例如循环中的代码,从循环中调用的方法或从多个线程调用的方法,则条件中断非常有用。将break语句放在感兴趣的行上并设置其条件以匹配错误情况。 (有一个简单的例子here。)
答案 10 :(得分: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 exception set,也不会捕获此处的异常。
答案 11 :(得分:1)
创建一个宏以附加到进程并分配给未使用的键盘快捷方式。比去快得多:debug - &gt;附加到流程 - &gt;在流程列表中搜索流程 - &gt; ...
答案 12 :(得分:1)
如果设置IDE在发生异常时将其分解,即使我们没有任何调试点集也是如此。
调试 - &GT;例外 - &gt; Commmon语言运行时异常 - &gt;抛出
这使得查找隐藏的异常处理问题变得轻而易举。实际上,这是每个开发人员应该在开发过程中设置的一种设置,以避免任何无法处理或甚至处理下面的异常。
答案 13 :(得分:0)
在非托管代码中,您可以设置“数据断点”。他们使用CPU的调试寄存器来发出INT3,调试器在运行时没有开销就停止在该指令上(在旧版本中,调试器逐步通过程序检查内存.....慢!)
如果你在knwon地址有一些损坏(堆栈/堆可变得破坏),这很有用。
还可以自定义ide \ packages \ debugger中的AutoExp.dat以显示您的数据结构。
指针,mb在监视窗口中显示十六进制转储 http://msdn.microsoft.com/en-us/magazine/dd252945.aspx
百胜