Extending Visual Studio with managed code can be challenging. This is due in large part to the fact that Visual Studio is a COM application written in native code and its interactions with managed code happen through .NET/COM interoperability. Because of this, you can experience some really weird bugs. And by “really weird”, I mean the wacky, hair-pulling kind of bugs that have driven lesser programmers insane. Debugging these kinds of problems is difficult because, unless you set up Visual Studio appropriately, only the managed code debugger is used when run your managed extensibility project. Without the native code debugger, the vast native code base of Visual Studio remains a complete mystery and, without that knowledge, hair-pulling bugs can only be solved through trial-and-error.
This article gives an overview of how to achieve a rich-debugging experience when Visual Studio itself is the debuggee. By the time we’re through, you'll be debugging Visual Studio in mixed-mode (with both native and managed code debuggers), getting full call stacks with symbols from the IDE itself and watching exceptions that occur in the IDE but are never marshaled across to the managed world. With these tools, you will gain insights that will lead to better-informed solutions to any hair-pulling bugs that you're struggling with.
Before venturing into the world of native code debugging you’ll need to make sure that you have set Visual Studio up properly.
First, Visual C++ must be installed to enable native code debugging. You must have a Professional SKU (or higher) to install Visual C++. If you have a Standard or Express SKU of Visual Studio, this isn’t an option. If you chose not to install C++ when you installed Visual Studio, do so now. Just insert your installer media and it should allow you to modify your existing installation to include C++. Note that, if you aren’t planning to do any C/C++ development, you don’t need any of the extra libraries (e.g. MFC, ATL, etc.) so you can uncheck all of the sub-features and just install the bare-bones C++ language service.
Second, you should install the Microsoft Debugging Tools for Windows. These tools are necessary if you’re doing crazy low-level development (e.g. Windows driver development) and need to debug Windows at the kernel-level. However, we’re only interested in one file: symsrv.dll. After installing the Debugging Tools, browse to the install directory on your hard drive and copy symsrv.dll to the Visual Studio IDE directory, replacing the version of symsrv.dll that is already there. (NOTE: The Visual Studio .NET 2003 IDE directory is {Program Files}\Microsoft Visual Studio .NET 2003\Common7\IDE by default and the Visual Studio 2005 IDE directory is {Program Files}\Microsoft Visual Studio 8\Common7\IDE by default.) Symsrv.dll will allow Visual Studio to interact with the latest version of the Microsoft Symbol Server.
The next step is to set up Visual Studio to use Microsoft’s symbol server to download any .PDB files that it needs and to cache them on disk.
For Visual Studio .NET 2003:
Sometimes Visual Studio .NET 2003 doesn’t seem to keep these settings and you must add them again. Fortunately, in Visual Studio 2005, this feature is much more accessible.
For Visual Studio 2005:
At this point, everything should be set up and ready for debugging. Let’s give it a try by attaching the debugger to another instance of Visual Studio.
This is totally awesome.
If you are an x86 assembler junkie, bring up the Disassembly window to see that the disassembled instructions now include method names as well.
When dealing with the Visual Studio Exceptions dialog (Ctrl+Alt+E), most developers are only concerned with children of the Common Language Runtime Exceptions node. The sad truth is that, other than the Managed Debugging Assistants (MDAs) that were introduced in Visual Studio 2005, none of the other exception types have any effect in the Managed code debugger. However, now that we can load both the Native and Managed code debuggers simultaneously, we can use all of the exception types in this dialog when debugging Visual Studio.
Trapping C++ Exceptions, Native Run-Time Checks, or Win32 Exceptions can be extremely useful if your extensibility project is pushing Visual Studio in ways that it might not like to be pushed. Sometimes, an exception can be thrown and handled in Visual Studio’s code but not surfaced to your managed code. In these cases, it is possible for Visual Studio to be in a state that your code might not be expecting and seeing the exception for yourself is the only way to really solve the problem.
The simple techniques presented in this article are extremely powerful and can help you to create better and more-informed code that interacts with Visual Studio. However, they are not limited to Visual Studio. I’ve used the same tricks with other Microsoft products (anyone working with Visual Studio Tools for Office?). Also, we haven’t exhausted all of the possibilities that can be achieved when debugging Visual Studio. If you have any other tips or tricks, feel free to contact me at blog@diditwith.net.
Page rendered at Wednesday, February 08, 2012 8:50:40 AM (Pacific Standard Time, UTC-08:00)
If feel a bit behind and need to catch up on WPF, this is the book.
Great book on F# containing from Beginner to Advanced. It even has chapters on more arcane features of the language, such as Computation Expressions and Quotations.
Because this book provides source code in Standard ML, it's a fantastic resource for learning F#. One bit of warning: this book does not teach classic data structures. While structures such as binomial heaps and red-black trees are presented, it is assumed that the reader already knows and understands them.
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.