In this post I am going to be discussing about debugging .Net Framework 4.0 using windbg . I am going to demonstrating how to have a break-point within a method, but without the framework source code. This would help in debugging .NET framework when you don’t have VS in a production environment and the same technique can be used to debug other third party assemblies where you don’t have the source code. This is kind of like .NET Reflector where you can step through third party assemblies, but without any cost. It is not going to be as convenient as the professional version of Reflector.

I am going to be using the same example that I used to debug .NET Framework source 3.5 using windbg.

FYI the .NET framework 4.0 has private symbols available on MS symbol server, but the source code is still not available. To debug .NET framework source code it is important to have correct symbol path and here is my symbol path in the _NT_SYMBOL_PATH environment variable.

Let’s try and have a break-point on line “ ArrayList prefixList = PrefixList;” so that we can check the local variables value. Just because I have the private symbols ,I could have counted the line numbers manually and then set a break-point using !mbp command, but that is no fun. Here is another way of doing this.

.shell -ci "!u 000007fef6ea5a44 " findstr get_PrefixList

In the above command I am disassembling the ip 000007fef6ea5a44 (which is there in the above callstack )to look for get_PrefixList Instruction pointer . Here is the outcome

Voila! now I am able to have a break-point within the framework method and also see locals and parameters like Visual Studio. The same technique can be used to debug third party assemblies where you don’t have source code or symbols.

Like this:

In this post I am going to be discussing about the NullReferenceException which is not trapped “sxe clr” command. FYI “sxe clr” is the command in debugging tools to catch any clr exception. Here is the kind of code that I was debugging.

The application was reporting “something went wrong”, just another day where I had to debug some code which I don’t appreciate debugging. I was asked to debug the issue. And I use windbg for all my production debugging.

Attached the process and issued the command sxe -c “!clrstack;!pe” clr, which instructs the debugger to trap any exception from clr and then print stack-trace and exception whenever an exception is thrown. And to my surprise the debugger didn’t break on the exception and I never got the call-stack. And my debugger was set ignore AV exception so it didn’t report on AV, if not I could have managed to get the call-stack and figure out the exception. And to my surprise when I issued the command !pe I didn’t get any result.

From my past experience of debugging I know if have bp on KERNELBASE!RaiseException I should be able to catch any exception. This is one advantage of understanding code close to metal , comes in handy when everything else fails. So issued the command bp KERNELBASE!RaiseException and here is the call-stack from the breakpoint

Share this:

Like this:

I got to see this amazing video on Pivot from Gary Flake. Pivot is about visualizing data. It’s primarily for visualizing patterns and trends. What other way I would use other than analyzing managed memory using pivot. I spend a lot of time in windbg to look at memory for patterns, analyzing memory leaks. And I also know not many of them want to learn the arcane commands of windbg. So I went ahead took the data from managed memory and ported it in to pivot format , which is cxml. I use the “!Traverseheap –xml” command from sos to generate the xml ,which I port it to cxml format.My initial thought was use dgml to visualize the data, but pivot is way better. Pivot can only be used in Vista+ OS.

FYI I know this is not for everyone, there are geeks who wouldn’t want to look at memory in a visual format, they prefer looking at in cdb. I took Facebook Silverlight client app and got a snapshot of the memory for this demonstration

The few things that can be done with this are

Drill down objects by type with just one click : What I mean by this is , you could probably have 6000 odd types of objects and not instances (instances could be in thousands), but if you wanted to look at all the instance of customer objects , it is as easy as one click from the filter.

Here is an example of filtering securitypermission objects in memory

Drill down members: The objects members can be looked up. So if you are looking at the customer object then you can view strings, ints and all its members. It WILL NOT have the value for these members. It is not provided by the traverseheap command

Filter objects by namespace– All the objects belonging to namespaces can be drilled down.

The above code converts the xml format from !traverseheap to pivot xml format. This is CPU intensive and I have not profiled and fine tuned it. I use plinq for conversion primarily because I have quad-core box. I use pictures from powerpoint for visualizing objects and I also wrote SplitEx method to avoid splitting namespaces that are part of the type name within generics “GenericEqualityComparer`1[[System.String, mscorlib]]”

And here is the command to get the xml input for the above code as input

!TraverseHeap -xml c:\temp\mem.xml

Share this:

Like this:

Recently I had to debug an issue which was running on Client OS box. I had to do a live debugging more than post-mortem debugging. FYI the box didn’t have VS.NET and it had copy of debugger’s folder (windbg) along with Powershell v2.0. I couldn’t terminal server onto the box because it would kick the other user out and the application would terminate. So only choice was to either go-down actual box and debug it or instruct someone to start a .server process within cdb/windbg. Both the options had its own set of problems. That’s when I realized that I could use powershell remoting to start remote session and then start a remote cdb session. I like to debug from my Dev box because of the tools and settings that I have on my box. Here is what I did

Started a Powershell ISE environment

Connected to the remote system. (there were quite a few issues is authentication when trying to connect)

Share this:

Like this:

I wanted to understand about UnhandledExceptions in .NET because of the few questions that I saw in the CLR Forum ,which had watson buckets in the event viewer. To get deep understanding unhandled exception filter there is a article on MSDN from CLR Team.

In this post I will be demonstrating how to get the Watson Bucket from within your code . FYI this is the same information you can get !WatsonBuckets from sos within Windbg whenever there is a termination of the .NET process. !WatsonBuckets is undocumented. I am using the CLR hosting interfaces to get the watson bucket. Here is the code that throws an unhandled exception and invokes clr to get watson bucket info.

In the above code WatsonBuckets is a structure to get watson bucket information back from CLR. In the code I use 3 hosting interfaces, IClrRuntimeHost which is the main interface, the next interface is IClrControl which has GetCLRManager method to get ErrorReportingManger. IClrErrorReportingManager which has the method to get the exception buckets which is GetBucketParametersForCurrentException. I know that there isn’t going to be much of use for this code. But it gives me better understanding of CLR integrates with watson when ever there is termination of an application.

Like this:

With the latest release of sosex comes a new set of functions to debug. It is pretty awesome that one person (Steve) alone could pull of such cool things. In this blog post, I am just going to demonstrate how easy it is to debug managed code using sosex compared to sos.

Notice the dict object is in the 8th offset . To dump contents dict object I would use the command !do poi(0000000002761e20+8) , which is pointer deference of Test object on it is 8th offset. And here is the output

And the dictionary object in turn stores them within an array which is again the 8th offset. This time because we know it is an array we are going to use the !dumparray command on the memory location. The command to get the details is

Now lets try and do the same thing using sosex. The one thing that I really like about the new sosex is that I can use names rather than pointer deference which is way much easier. Launched the app and then loaded sosex using the command

.load F:\Work\Tools\debuggers\sosex.dll

and then switched the thread from 4th to 0th thread using ~0s. By default the debugger injects a thread into the process for debugging and that was the 4th thread. The next command I issued was to get stack trace

FYI the command !mk has been part of sos from the initial version. I am interested in only looking at the code that I wrote so I would like to move stack frame to 0c which is MemCheck.Test.Main . To do that the command is !mframe 0c, which moves to that stackframe. The reason to move the particular stack frame is to look for variables in the stack and the command to variables is !mdv , which display managed local variables

I didn’t have to get memory address , I am using the names which is very intuitive ,especially when we have to debug large application with N levels of nesting.So to get the dict values from p the command to issue is !mdt -e p.dict

Here is the partial output. Notice I never had to use a memory pointer or do a pointer deference .This is very similar to VS.NET debugging where I am used to the variable names compared the memory address. Thanks to Steve for providing such a cool extension.

Like this:

With the latest release of PSSCOR2release from Microsoft comes with a set Undocumented functions. FYI PSSCOR2 is a superset of sos.dll for .NET framework 2.0/3.5, it also has bunch of functions which are available in the .NET 4.0 sos.dll.

The .NET 4.0 also has few undocumented functions and PSSCOR2 does have them. But these functions are totally new and is not even available in .NET 4.0 sos

!FindInterestingStrings

!SaveSnapshot

!LoadSnapshot

!dumpconfig

!GCUsage

!VerifyDAC

I did manage to figure out the usage of few of these, but I let you explore them before I blog about this.