Razor#

Because we all love bleeding edge technology

Month List

Search

Calendar

<<  May 2013  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar

Managed (.NET) breakpoints using WinDBG

I often find myself needing to debug production applications and .NET applications I did not write myself or third party components in my own applications. Often, when doing so, we find ourselves thinking “Geez, I wonder if this component or this application is invoking this method at this point”, or “I’d like to be able to break on exception System.Foo, so I can see what is happening”. You can’t install Visual Studio on productions server, and even if you could, it wouldn’t help if you’re not debugging your own application. Do note this post only applies to .NET 2.0

Fortunately, WinDBG can help, and it isn’t as hard as one would think!

First, load up WinDBG, and attach to the process we want to debug:

image

 

For this exercise, I made a small application that makes an instance of a class, and invokes two methods within it, one that returns a Hello World, and one that throws an exception:

class Program
{
    static void Main(string[] args)
    {
        Console.ReadKey(true);
 
        BrokenClass broken = new BrokenClass();
        broken.HelloWorld();
        broken.BrokenWorld();
    }
}
namespace PhoenixMatrix.Windbg.Demo
{
    public class BrokenClass
    {
        public string HelloWorld()
        {
            return "Hello World!";
        }
 
        public void BrokenWorld()
        {
            throw new NotSupportedException("Hello World!");
        }
    }
}

 

 

 

Simple enough. All right, lets get started. So we have our process running, and it is waiting on a user action (Read key). Then, we have multiple options, depending on what we want to do.

Option A – Break on all Exceptions

Without doing anything else, we use the following commands:

sxe clr

!loadby sos mscorwks

What this does, is instructing WinDBG to break on all CLR exceptions, both first chance (the ones that didn’t bubble up yet) and second chance (the ones that did bubble up, usually because there was no catch blocks waiting for them). The second command, !loadby sos mscorwks, will load up a special set of extensions especially made to debug managed code. To be sure we’re loading the version that matches the .NET framework we are using, we load sos.dll at the same location mscorwks (part of the .NET runtime) was loaded. If we run:

g

our process now continues, we hit any key, and sure enough, WinDBG breaks on an exception. Now let see where it stopped (from now on I will be showing the output of WinDBG, bolding and underlining the command I executed)

0:000> !pe
Exception object: 01cd8988
Exception type: System.NotSupportedException
Message: Hello World!
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131515

!pe, shortcut for !PrintException, will give us the details of the exception. Now there’s no stacktrace because this is a first chance exception. Lets hit “g” to go a step further. The exception will enter second chance stage, and we can print it out for real this time:

0:000> !pe
Exception object: 01cd8988
Exception type: System.NotSupportedException
Message: Hello World!
InnerException: <none>
StackTrace (generated):
    SP       IP       Function
    002FEE38 001C01A6 PhoenixMatrix_Windbg_Demo!PhoenixMatrix.Windbg.Demo.BrokenClass.BrokenWorld()+0x46
    002FEE48 001C00CE PhoenixMatrix_Windbg_Demo!PhoenixMatrix.Windbg.Demo.Program.Main(System.String[])+0x5e
 
StackTraceString: <none>
HResult: 80131515

Now we have the stack trace, complete with method information. This is great if we want to break on any and all exception, but what if we wanted to break on a particular one?

Option B – Break on a specific exception

Instead of simply using sxe clr, we can create a breakpoint on a particular exception, as follow (Note that it is possible at this point WinDBG will give a big output complaining about lack of symbols. You can ignore that safely, i just removed them from my output below):

 

0:003> !soe -create System.NotSupportedException 1
Breakpoint set
 

The !soe (Stop On Exception) lets us create a breakpoint on a particular exception. Note that you must fully qualify the name of the exception, with the namespace. The number (1 in this case) after the exception is a “speudo register”, which can be used in more advanced WinDBG scripted commands to examine the result of the breakpoint. For now we don’t need that, but it is still needed to set a normal breakpoint. Now, lets allow our application to continue with “g”, hit a key, and see what we get.

0:000> !pe
Exception object: 01de8988
Exception type: System.NotSupportedException
Message: Hello World!
InnerException: <none>
StackTrace (generated):
<none>
StackTraceString: <none>
HResult: 80131515

 

Great! same result as last time! However, if other exceptions had been thrown first (common in an ASP.NET application, for example), we would have ignored name, and only stopped on System.NotSupportedException. Now, this is great for exceptions. But what if we wanted to break on a method?

Option C – Break on a method name

It is possible to have a breakpoint on an actual method. First, we need to do the initial steps again (attack to the process, load sos), and run the following:

0:003> !bpmd PhoenixMatrix.Windbg.Demo.exe PhoenixMatrix.Windbg.Demo.BrokenClass.HelloWorld
Found 1 methods...
MethodDesc = 003e3060
Adding pending breakpoints...

 

That one is a mouthful. !bpmd (break point method description) lets us break on a method within a module. In C#, the module is virtually always the fully qualified name of the executable or the dll (so, the assembly) the method is in. So we type !bpmd, followed by the full module name, followed by the fully qualified method name, complete with namespace and parent class. We also see this added a “pending” breakpoint in our case: that is because the method has not been JITted, or compiled to native code, yet. Now lets allow our program to continue.

 

0:003> g
(16b8.14bc): CLR notification exception - code e0444143 (first chance)
JITTED PhoenixMatrix.Windbg.Demo!PhoenixMatrix.Windbg.Demo.BrokenClass.HelloWorld()
Setting breakpoint: bp 00990120 [PhoenixMatrix.Windbg.Demo.BrokenClass.HelloWorld()]
Breakpoint 0 hit
eax=003e3060 ebx=0038ecfc ecx=01c18950 edx=01c1895c esi=004b5308 edi=00000000
eip=00990120 esp=0038ecb4 ebp=0038ecd0 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
00990120 55              push    ebp

 

And here we see that the breakpoint worked, and stopped on the now JITted HelloWorld method. We can also pull the stacktrace, to see how that method was invoked:

 

0:000> !clrstack
OS Thread Id: 0x14bc (0)
ESP       EIP     
0038ecb4 00990120 PhoenixMatrix.Windbg.Demo.BrokenClass.HelloWorld()
0038ecb8 009900c2 PhoenixMatrix.Windbg.Demo.Program.Main(System.String[])
0038eeec 71cf1b4c [GCFrame: 0038eeec] 

 

While using !bpmd is great in cases where we are sure of the method’s name and module, do keep in mind that the compiler will happily mangle the method names when it suits its needs (such as public property definitions, which are compiled to get/set methods), and that it is possible to define custom modules in certain languages (such as VB.NET), so it is not always trivial.

Option D – Break directly on the method

With the following commands, we can fetch the actual pointer to the method, and break on it, as well as browse the methods in the class, letting us more easily select the one we want. First, we need to find our class within the available modules.

0:003> !name2ee * PhoenixMatrix.Windbg.Demo.BrokenClass
Module: 706f1000 (mscorlib.dll)
--------------------------------------
Module: 002c2c5c (PhoenixMatrix.Windbg.Demo.exe)
Token: 0x02000003
MethodTable: 002c3080
EEClass: 002c134c
Name: PhoenixMatrix.Windbg.Demo.BrokenClass

 

!name2ee will get us the class information within a module. Using the * as the second parameter will search all modules, but if we wanted, we could give it the fully qualified module name instead (in this case, PhoenixMatrix.Windbg.Demo.exe). The command will go through the modules, and if it finds the Class, outputs its details. The part we’re interested in is the MethodTable, so we can output all of the class’s methods.

0:003> !dumpmt -md 002c3080
EEClass: 002c134c
Module: 002c2c5c
Name: PhoenixMatrix.Windbg.Demo.BrokenClass
mdToken: 02000003  (C:\PhoenixMatrix.Windbg.Demo.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 7
--------------------------------------
MethodDesc Table
   Entry MethodDesc      JIT Name
708b6aa0   70734924   PreJIT System.Object.ToString()
708b6ac0   7073492c   PreJIT System.Object.Equals(System.Object)
708b6b30   7073495c   PreJIT System.Object.GetHashCode()
70927410   70734980   PreJIT System.Object.Finalize()
002cc045   002c3078     NONE PhoenixMatrix.Windbg.Demo.BrokenClass..ctor()
002cc03d   002c3060     NONE PhoenixMatrix.Windbg.Demo.BrokenClass.HelloWorld()
002cc041   002c306c     NONE PhoenixMatrix.Windbg.Demo.BrokenClass.BrokenWorld()

 

Now this is a lot of information, but !dumpmt simply dumps out the method table’s information. The last part is what we’re interested in, the list of method. Notice that we can see the JIT state of the methods (remember when I said HelloWorld was not JITted yet? We see it now, though that doesn’t stop us from setting a breakpoint on it). Lets take the MethodDesc code of the method we want to break on, HelloWorld (so the second code from the left)

 

0:003> !bpmd -md 002c3060
MethodDesc = 002c3060
Adding pending breakpoints...

 

 

The breakpoint is successfully set. If we run the application, we can see it will correctly break on HelloWorld, as per the clrstack again:

 

0:000> !clrstack
OS Thread Id: 0x1074 (0)
ESP       EIP     
002bf264 008e0120 PhoenixMatrix.Windbg.Demo.BrokenClass.HelloWorld()
002bf268 008e00c2 PhoenixMatrix.Windbg.Demo.Program.Main(System.String[])
002bf4a0 71cf1b4c [GCFrame: 002bf4a0] 

 

And there you have it, the primary ways of setting breakpoints using WinDBG on managed code. These little tricks have tons of applications, such as finding out the behavior of third party components, debugging third party applications (SharePoint comes to mind), as well as doing the diagnostic of nasty production issues that you simply cannot reproduce. And since WinDBG doesn’t need to load all symbols the way Visual Studio does before letting you use it, it can be a real timesaver, once you get the hang of it.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Permalink | Comments (0) | Post RSSRSS comment feed

A story of Windows 7 and memory usage

It comes up a lot on web forums lately. “I heard Windows 7 uses less memory than Vista! Is that true?”

Well, yes and no. Windows 7 is not a full redesign of the operating system like Vista was, so obviously they had a lot more time to optimize it, and it paid off. I do have a feeling however, that it also reports cached memory differently, to fool the “Task Manager Power Users”, that is, people who think they know a lot about computers because they can read the task manager’s data, and do not understand the principle of wasted resources. This post blog entry isn’t to debate that however, but just to show how little memory Windows 7 can use with a default install (without Aero however. Though Windows 7 Aero uses very, very little memory).

Here you have it. Keep in mind that, like Vista, Windows 7 adjusts to the current hardware, so you will see vastly different numbers on a machine with 4 gigs of RAM. Also at around 150 megs of RAM (give or take, I forget the exact number), it doesn’t boot at all anymore, so this should be somewhat close to the minimum usage you will see:

Windows7RAMUsageMin

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Permalink | Comments (0) | Post RSSRSS comment feed

Visual Studio 2010 Beta 1: First Impressions

So, I've just noticed via the MSDN's downloads RSS feed that VS2010 Beta 1 was made available for download. This is significant, because the earlier VS2010 CTP was only released as a cumbersome virtual machine for Virtual PC, and did not have the new WPF based UI, but this one is an ISO, and does have all of the new goodies...

So there I went, making a new Windows 7 VM in VMware Server and started installing.

All I can say is Wow. Major improvement all over, of a scale not seen since .NET was released, and the major performance boost due to the WPF based editor, especially the ASP.NET one.

Just to get started, the New Project window got revamped. Now everything is well organized and easy to find. Note that VS2010 supports all framework from 2.0 and on.

image

The first thing I looked at is the new Windows Workflow Foundation in .NET 4.0. This was rewritten from scratch, because the .NET 3.0/3.5 version had as a “default” development pattern to be self contained. That's no good: Windows Workflow rely heavily on serialization/serialization, so the slightest change in code, and persistence doesn’t work anymore. And if you think of a Workflow as the business logic equivalent to a “view” in MVC, then the workflow should be mostly empty, and only call outside logic. This is what .NET 4.0’s workflow bring to us: an enhanced interface for development, communication via WCF for the business logic, and even integration with powershell!

State Machine workflow (the one everyone should have been using back then, but no one used) was replaced by the Flowchart workflow, which seems to be an hybrid between state machine and sequential. It really feels like making a diagram in Visio. Oh, and right click –> copy image is available, of course! (see result below, as well as the actual Visual studio UI). Another notable improvement is the available activities. We finally get a Foreach.

 image

image

Now, for the web editor. Like everything else, it was revamped in WPF. I like the new look, reminds me a bit of Code Rush (which I love, but prefer the features of Resharper, especially as of 4.5). Aside for the look, it is definitely faster, and has a few novelties.

image

But what about the code?! Well, again, code editor in WPF. Prettier, smoother, more responsive, easier on the eyes. There’s a couple of new features I can spot, but I’ve been using Resharper for a while now, so i cannot easily tell if they were there in 2008. The editor does locate identifiers (if you have a method call selected, it will automatically highlight the definition) and other such sugars. If nothing else, the stuff that was present in VS2008 potentially more visible because of the more organized GUI. Oh, and intellisense now automatically filter selects as you type in C# like it does in VB or with Resharper. Much better!

image

Refactoring is still lacking, so we’re not getting rid of Refactor! and Resharper anytime soon.

One thing of interest is Consume First mode. In this mode (toggled by ctrl + alt + space within Intellisense), Visual Studio will stop trying to auto-complete identifiers that are not there. This is mostly useful with test driven development: when coding against classes that do not exist yet. That said, the new menus, enhanced syntax highlighting and performance improvements make it quite enjoyable indeed. One thing of interest is how the F# interactive window is accessible at all time. That may be able to replace Powershell for me when it comes to test a new API or the Sharepoint object model. More on this later!

image

 

 

 

 

Interesting: there are new items templates for the T4 code generation, a feature that has been available in Visual Studio for a long time, but never truly integrated. Not much around it, but this is still a beta:

image

Next is the XSD schema editor. I feel a bit cheated on that one: it was supposed to be part of VS2008 (thus why the original editor was removed), and silently replaced by a Viewer, with no word of the editor. Well, now we get the real thing, if quite late (I feel for those who have to pay to upgrade Visual Studio…)

So, what do we get for 2-3 years of wait? First, a nice statistic view (followed by Visual Studio 2010 crashing on me):

image

And….that's it (that isn’t available in VS2008 anyway). There’s a bunch of buttons that should allow you to see the XSD in graph view (I saw some screenshots online of it), but it didn’t work for me. They did absolutely nothing. Now maybe its the XSD I’ve used, or maybe the feature plain isn’t there.

I also wanted to try the supposed improvements to VS2010 and C++, but the intellisense doesn’t work yet (it says it is unavailable in the status bar when you try to invoke it), so the IDE has a long way to go before it is ready for release, as it is far from feature complete. The Sharepoint stuff is only barely present in the form of .NET 3.0 workflows, a far cry from what we’ve seen online with the full blown integration. I figure we’ll see it in the next beta.

 

Finally, the DEBUGGING EXPERIENCE!

That is the best part yet. I’ve only had time to test it a little, but here are the two things I’d like to point out (I unfortunately didn’t look at the parallel programming debugging yet):

First, the F5 experience is much better. Taking a 1 line console application and hitting F5 doesn’t take several seconds on a Core 2 Duo 3ghz with 4 gigs of RAM anymore. It is almost instant.

Second, as I’ve told to many of you already: we can debug managed memory in a dump directly within visual studio! No need for WinDbg anymore (while I still think WinDBG is one of the best, most powerful tools there is, it is a fact that it has a learning curve and is not as accessible. Plus, nothing beats being able to see visually where your code is going).

Just File –> Open –> File, point to the memory dump while your project is open, and you’re good to go! I’ve also noticed you can add comments to the debug visualization. I’ll have to look more into what can be done with it:

image

(the dump interface. Lets you F5 the dump, which will bring me to the following)

image 
(this is a dump taken while the process was running. Notice how all the values are there, how it knows which line I’m at, everything that the symbols can get me!)

All around a MAJOR boost to debugging in production, and put within reach of even junior developers (and much easier to use even for veterans). Again, WinDBG will stay the first line of defence when you need to debug something FAST and in depth, but for the common scenarios, this is vastly superior.

And that’s it for now, as I’m running out of time. I’ll keep playing with it in the following days and compare notes with other bloggers, and see what I can find.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Permalink | Comments (0) | Post RSSRSS comment feed