Freigeben über


Using Reflector to search through code and resolve .NET issues

As you already know, i spend my days analyzing dumps for customers, and more often than not I don't have access to the customers code. 

I could probably ask for it but it usually takes a long time and even then I often just get partial code, and sometimes, if the customer has multiple environments or if there has been recent changes, the code I would get may not correspond exactly to what was running in production when the dump was taken.   

I'm sure many of you are familiar with Lutz Roeder's Reflector already...  I just have to say, I just love this tool... it has made my life soo much easier over the years that it's not even funny.  I constantly have 2-3 sessions open and in case you are not familiar with some of its features I wanted to show how I use it on a daily bases...

Before I do though, here is a presentation about all the 5.0 features

Saving the modules

If I have a dump of a process and want to look at the code running inside it I can open it up in windbg and use sos to save the dlls using

!savemodule <base address> <path to save>

And I can get the base address by running lmv mmodulename, or just lm to get all start/base addresses for all modules... anyways, it gets pretty tedious to do that for all modules so instead I automate it a bit with windbgs !for_each_module, so the command below, saves out all the dlls/exes loaded in the process in binary form so they will be stored on disk pretty much as an exact replica of the dll loaded in the process...

 0:000> !for_each_module !savemodule ${@#Base} f:\blog\modules\${@#ModuleName}.dll
01000000
5 sections in file at 00990000
section 0 - VA=1000, VASize=7f749, FileAddr=400, FileSize=7f800
section 1 - VA=81000, VASize=490, FileAddr=7fc00, FileSize=600
section 2 - VA=82000, VASize=237c, FileAddr=80200, FileSize=2000
section 3 - VA=85000, VASize=3d8, FileAddr=82200, FileSize=400
section 4 - VA=86000, VASize=5404, FileAddr=82600, FileSize=5600
Successfully saved file: f:\blog\modules\oleaut32.dll
01000000
4 sections in file at 00a20000
section 0 - VA=1000, VASize=498f4, FileAddr=400, FileSize=49a00
section 1 - VA=4b000, VASize=1054, FileAddr=49e00, FileSize=c00
section 2 - VA=4d000, VASize=1598, FileAddr=4aa00, FileSize=1600
section 3 - VA=4f000, VASize=26ec, FileAddr=4c000, FileSize=2800
Successfully saved file: f:\blog\modules\shlwapi.dll
00040000
3 sections in file at 00f60000
section 0 - VA=2000, VASize=2954, FileAddr=200, FileSize=2a00
section 1 - VA=6000, VASize=2a8, FileAddr=2c00, FileSize=400
section 2 - VA=8000, VASize=c, FileAddr=3000, FileSize=200
Successfully saved file: f:\blog\modules\y9w_t4cv.dll
00040000
3 sections in file at 00f70000
section 0 - VA=2000, VASize=2954, FileAddr=200, FileSize=2a00
section 1 - VA=6000, VASize=2a8, FileAddr=2c00, FileSize=400
section 2 - VA=8000, VASize=c, FileAddr=3000, FileSize=200
Successfully saved file: f:\blog\modules\ibyunanw.dll
00040000
3 sections in file at 00f80000
section 0 - VA=2000, VASize=2954, FileAddr=200, FileSize=2a00
section 1 - VA=6000, VASize=2a8, FileAddr=2c00, FileSize=400
section 2 - VA=8000, VASize=c, FileAddr=3000, FileSize=200
Successfully saved file: f:\blog\modules\th5r9oei.dll
00040000
3 sections in file at 00f90000
section 0 - VA=2000, VASize=2954, FileAddr=200, FileSize=2a00
section 1 - VA=6000, VASize=2a8, FileAddr=2c00, FileSize=400
section 2 - VA=8000, VASize=c, FileAddr=3000, FileSize=200
Successfully saved file: f:\blog\modules\t0i_pxyo.dll
...

Opening in reflector

In order to get all the code running in the process i just open a new instance of reflector, clean out any previously opened dlls and do file/open, selecting all the modules i just saved. 

Sometimes you need to close out dlls like System.dll System.Xml.dll etc. that have native images and open those directly from the framework directory instead.

Searching in reflector

Let's say I want to debug the issue described in this post, where we are leaking dynamic assemblies because we are creating new XmlSerializers, and we want to know where in our code we might be creating these...

I would use the search function, searching for types to find XmlSerializer

And then just double click on the XmlSerializer option to explore that class...

Btw, it has great member search and string/constant search options as well if you need that...

Finding out who calls it

Once we have found the XmlSerializer class we can take one of the methods we are interested in (in this case any of the XmlSerializer constructors that generate dynamic assemblies without caching them) and right-click and choose Analyze...

 

This opens the Analyzer pane where we can expand the Used By node to find out who is calling this method...

And in this case it tells us that the only method that is using this constructor, in the code loaded in the process, is Lab3_2.Page_Load.  And if we right click and choose Go To Member we can even see the code for this in the Disassembler pane so we can see how it calls it.

And that way we can pinpoint the exact line of code that caused this assembly leak...

Laters

Tess

Comments

  • Anonymous
    January 10, 2008
    I loved the automation of exporting of modules, I hope that our Support team will also be able to do such operations.

  • Anonymous
    January 10, 2008
    So niiiiiiicee!!! I didn't know the Analyze feature although I have been using Reflector for over 2 years now.

  • Anonymous
    January 11, 2008
    Really great post.  You can never be 100% sure that what you have deployed matches the source code you have. Thanks so much for helping us all.

  • Anonymous
    January 25, 2008
    Like Andrei I had no idea the Analyze function existed/what it did, even though I'm in Reflector all day long (a MUST for SharePoint development).  VERY handy...

  • Anonymous
    January 27, 2008
    Is there a new version of Reflector for Visual Studio 2008? I  plan to use Reflector to find all references among solutions since the Find All References in VS2008 is limited to single solution.

  • Anonymous
    January 27, 2008
    Since 2008 runs 2.0 of the CLR  (3.0 and 3.5 runs on v2.0 of the CLR) you can just use the reflector that works for 2.0. Thanks Tess

  • Anonymous
    February 08, 2008
    Reflector is great, too bad every Microsoft EULA says you are not permitted to actually use reflector on Microsoft code. Would be nice for things like Sharepoint.

  • Anonymous
    March 03, 2008
    .NET: VisualStudio2008NewMulti-ThreadedDebuggingFeature Howto:buildfromtheWindowsSD...

  • Anonymous
    September 14, 2008
    I was helping a colleague out with an OOM (OutOfMemory) situation he was dealing with. Problem description:

  • Anonymous
    September 15, 2008
    Can you email me a copy of the .net reflector 5.0 presentation? My email is mcp111@gmail.com.

  • Anonymous
    September 15, 2008
    the presentation is located here http://www.authorstream.com/Presentation/Mentor-6838-reflector-5-NET-Reflector-0-Overview-C-3-support-2-Code-URL-Assembly-Browser-Disassembler-Analyzer-Search-reflector5-ppt-powerpoint/ I dont have a copy of the ppts but you may want to ask whomever owns that site