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 TessAnonymous
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