+9  A: 

Of course, check out the VS tip of the day:

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

Brian
+10  A: 

I always make sure to set the "Name" property on new threads that I create. That way, when I'm debugging I can more easily identify different threads.

Jon Tackabury
+12  A: 

Here's another neat trick I learned:

System.Diagnostics.Debugger.Break()

programatically causes the debugger to break on the next instruction. The really nice part is, this also works for a program compiled in Release mode, without debugging information.

Cristi Diaconescu
I prefer to surround that with If (System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debugger.Break() } Otherwise clients can get nasty errors when this isn't taken out!
Gavin Miller
+2  A: 

Conditional breaks are very useful if you have code that is repeated a lot but only fails under a specific set of conditions, such as code in a loop, methods called from a loop, or methods called from multiple threads. Put the break statement at the line of interest and set its conditions to match the error case. (There is a quick example here.)

ARKBAN
+7  A: 

A few from me

  • Uncheck the "Enable Just My Code" option in Tools->Options->Debugging.
  • Conditional breakpoints - they save my life almost every day
  • Use the .NET framework source if things get ugly
korchev
+4  A: 

Tools -> Attach To Process - easy to forget, but with it I can debug script in web pages, managed code loaded up in another process (think an add-in model), or even unmanaged code. Be careful with letting it automatically pick the type of debugging you're interested in.

Tracepoints (and other breakpoint features... right click on the breakpoint and have fun)! - 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

The immediate window is awesome.

Remote Debugging is very useful if you deploy apps (and can get to the machine where the problem can be reproduced).

There are tons more. Try getting into WinDbg and SoS!

David Mohundro
Unfortunately, I just learned that these don't work for Express edition.
Michael Haren
+3  A: 

.load sos in the Immediate window :)

leppie
can u explain this?
Ante B.
What's explain? There are tons of pages on the internet explaining how to use SOS.
leppie
+13  A: 
try {
    // do something big
}
catch {
    // breakpoint set here:
    throw CantHappenException("something horrible happened that should never happen.");
}

How do you see the exception that was originally thrown? In a watch window, enter $exception

plinth
+2  A: 

Two from me: one that I hope everyone uses all over the place:

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

the second 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

Even if you have Debug, Exceptions, Break on thrown exceptions set, exceptions in here will not be caught.

GalleySlave
+3  A: 

I found the Modules window useful a lot of times. It tells whether the debugger has loaded a required dll and which version of the dll is loaded. It also lets you manually load or unload a dll.

etsuba
+5  A: 

Two in-code tricks:

I really like the System.Diagnostics.DebuggerStepThrough attribute; you can attach it to a class, method or property to make VS not enter the code by default when debugging. I prefer it over the DebuggerHidden attribute as it will still allow you to put breakpoints in the ignored code if you really need to debug it.

Another (sometimes) useful call is System.Diagnostics.Debugger.Launch(); when the execution hits it, you will be presented with the "select a debugger" dialog, and a debugger will start. A bit rude, but useful with particularly nasty to attach to processes, like a process that gets spawned by another and immediately executes your code.

Paolo Tedesco
I've recently learned about System.Diagnostics.DebuggerStepThrough - useful. Also, it so happens that I used Debugger.Launch a lot in the last couple of weeks - for a particular project, if I try to attach directly from the 'Attach to process' dialog, the process just dies, but using Debugger.Launch() attaches the (same?!) debugger just fine.
Cristi Diaconescu
A: 

In unmanaged code you can set "data breakpoints". They user the debug registers of the CPU to issue an INT3 and the debugger stops on that instruction with no overhead during run time (in older version the debugger stepped through the program checking the memory..... slow!)

This is useful if you have some corruption at a knwon address (stack / heap vaiable getting clobbered).

Also AutoExp.dat in ide\packages\debugger can be customized to show your data structures.

pointer, mb shows a hex dump in the watch window http://msdn.microsoft.com/en-us/magazine/dd252945.aspx

Yum!

Dominik Weber