Something that I really miss with the .NET Framework is the source code.
In the early days of the Framework between the PDC versions coming out in 2000 and the final release there were a number of rumours about the possibility that the Framework source code might get shipped as an aid to debugging.
For a C/C++ developer, this seems natural in that you have the source for the ATL, the MFC and the C runtime library all shipped with Visual Studio and it's a real aid to debugging but the rumours around the .NET Framework source code turned out to be false and the Framework code does not ship with VS.
With .NET, it's not so easy. When you wander into the .NET Framework code the best that you've got is the disassembly that's come out of the JIT and most people don't want to step through disassembly these days.
At one time, I used to have an idea that all this could be solved by disassembling a .NET Framework assembly back to IL (or maybe even C# via Reflector) and then rebuilding that IL or C# code with debugging information and trying to replace the real Framework assembly with the "new version" that contains debugging info and then stepping through it.
In practise, this isn't really feasible because of code signatures and so on and I gave up on it a while ago.
Instead of trying to debug this way, I tend to sit with the debugger and also with Reflector and try and figure out what's going on from that kind of interation.
I was doing a bit of this yesterday and I was wondering to myself "Do other people debug this way?" and I thought I might perhaps write it down in case other people don't already do this and might perhaps find it useful.
So...here's the scenario. I'm doing something with the WCF and I'm getting an exception back up in my code;
A first chance exception of type 'System.ServiceModel.MsmqException' occurred in System.ServiceModel.dll
Additional information: An error occurred while opening the queue:Unrecognized error -1072824214 (0xc00e006a). The message cannot be sent or received from the queue. Ensure that MSMQ is installed and running. Also ensure that the queue is available to open with the required access mode and authorization
I've no idea where this is coming from so my first thought is to capture the exception at the time that it's thrown rather than at the time where it's caught/not caught because that might give me more information. For me, this is one of the most useful debugging techniques out there and Visual Studio makes it easy;
and getting the debugger to stop when exceptions are thrown rather than when they're not caught;
so, now when I re-run my code I can get a call-stack from where the exception is actually being thrown rather than where it fails to be caught. This gives me;
So, this tells me that this is happening in MsmqQueue.OpenQueue and I can go and look at the disassembly for this if I like;
And it's important to note that you can set breakpoints on this disassembly although they won't usually survive a re-run of the program (and a re-JITting of the code);
So..that's been useful as I now know that MsmqQueue.OpenQueue is failing on me. I can go and spring up Reflector and take a look at that method;
So, this isn't a huge surprise in that it's just trying to open the queue. But which queue? It'd be quite useful to get hold of that this pointer and grab the formatName member and have a look at it.
Now, I'm sure that there's a better way of doing this in VS (without poking around in the disassembly) but at this point I generally go and load SOS.DLL and make use of it. You need to switch to the "Immediate Window" to make that happen as far as I know as in;
Now...in this particular case the extension isn't showing me the this pointer. As it happens, the string that I want is visible as a parameter further up the stack but there's another way to find that this pointer in that we can have a look for all the MsmqQueue instances kicking around (this works well with a type such as MsmqQueue which doesn't occur frequently in your average managed heap);
That lets me see that there's 2 MsmqQueue's kicking around here so I'll dump them out using their method table;
Dumping out the first one;
and it's formatName;
(I scribbled over my machine name in a rather pathetic attempt to hide its identity :-)) but you can see that I can now see one of the MsmqQueue.formatName members and I could go off and find the other.
Bringing this back to where this post started - it would be a lot easier if the .NET Framework source code was there for me to just step through but a combination of VS + Reflector + SOS lets you do almost as much as the source code would let you do (bearing in mind that some of the Framework is not managed and that we're debugging optimised code here) with a bit more effort.
Hopefully, some pieces of this might be useful in debugging your own code if it's not something that you're already doing.
Wed, Oct 25 2006 1:10 PM