After sending my “Stick a Fork In It” goodbye mail, I got a fair amount of comments that roughly could be categorized like this:
- The app crashed, funny. Whatever.
- The app crashed. Dumbass, he sent an app that crashed. Whatever.
- Heh, the app is called BallsDemo. He said balls.
- Cool, the app crashed. Knowing Nithin, there’s something going on here…
Yup, something definitely was going on. And those who know me fairly well, got it. For those of you who didn’t quite get it, or didn’t have the time to dig in (the team is under a fair amount of pressure right now to get stuff done for our current milestones), this post’s for you. Let’s dissect this bad boy.
When you run the app, you’ll quickly see that you have to mouseover it to get the ball to drop and bounce. (If you didn’t even get this far, then stop reading here – this post is clearly not for you.) After a few seconds, the app crashes and looks something like this:
Depending on your JIT debugging settings, you may have the Visual Studio JIT debugging dialog pop up instead, or the app might even just disappear. These are clues people. Assuming you have a dialog up, carefully take a look at the state of the app. Go on, move the error reporting dialog ever slightly to the right. What do you see?
For those who are color blind (sorry Jerry/Herrick), you’ll see the following words in bold orange: “debug this exception”.
Now we split into two camps – those who have debug skillz and those who don’t. If you don’t have the skillz or desire to hit the debugger, I still leave a clue for you. Take a look in the Windows EventLog. Under Windows Logs -> Application, you’ll see an “Application Error” event where the description says, “Faulting application name: BallsDemo.exe, version 1.0.0.0 blah blah blah…” Right under that event, you should have a “.NET Runtime” error event with the following description:
Application: BallsDemo.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: FullCircle.YouMightWantToDebugThisException Stack: at FullCircle.PeaceOut.I_Have_Decided_To_Leave_Microsoft() at FullCircle.PeaceOut.It_Was_Time_For_Me_To_Move_On() at FullCircle.PeaceOut.HopeYouRememberHowToDebug() at FullCircle.PeaceOut.Because_There_Is_Tasty_Info_In_This_Crash() at BallsDemo.MainWindow.MyBallsCrashed(System.Object, System.EventArgs) at System.Windows.Threading.DispatcherTimer.FireTick(System.Object) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
Clearly there’s more to this. But we’ll need a debugger to figure this out.
For the remainder of this post, I’ll show you how to explore this crash in cdb. You can easily do this in Visual Studio, but I’ll leave that as an exercise for the reader. I could have also done this in windbg, but I’m an asshole. (You could also skip this entire post and just use Resharper, but again – exercise for the blah blah). So here goes…
Let’s assume you launched BallsDemo.exe under the debugger: cdb -g BallsDemo.exe. Note, I used -g to skip the initial breakpoint on debugger attach. Once it crashes, let’s try to get a callstack:
0:000> k *** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll - *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll - ChildEBP RetAddr WARNING: Stack unwind information not available. Following frames may be wrong. 0021e518 5d813970 KERNELBASE!RaiseException+0x54 0021e5a8 5d813ba9 clr!CoInitializeEE+0x55126 0021e668 091b2d8f clr!CoInitializeEE+0x5535f 0021e768 091b2bf8 0x91b2d8f 0021e770 091b2a72 0x91b2bf8 0021e780 091b2a18 0x91b2a72 0021e788 091b29e8 0x91b2a18 0021e790 091b29ba 0x91b29e8 *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\eb4e1e70734f6efb9c7de7ec5f452c9e\mscorlib.ni.dll *** ERROR: Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\eb4e1e70734f6efb9c7de7ec5f452c9e\mscorlib.ni.dll 0021e894 5cb64db5 0x91b29ba 0021e8a4 5d7021bb mscorlib_ni+0x234db5 0021e8b4 5d724be2 clr+0x21bb 0021e930 5d724d84 clr!CoUninitializeEE+0x6a3a 0021ea74 5d724db9 clr!CoUninitializeEE+0x6bdc 0021ea90 5d724dd9 clr!CoUninitializeEE+0x6c11 0021eaa8 5d774124 clr!CoUninitializeEE+0x6c31 0021ec8c 5d77427f clr!StrongNameSignatureVerification+0x7055 0021ed38 5cb64cba clr!StrongNameSignatureVerification+0x71b0 0021ed70 5cb67f34 mscorlib_ni+0x234cba 0021ee7c 5cbde0c4 mscorlib_ni+0x237f34 0021ee80 01830fb0 mscorlib_ni+0x2ae0c4 0021ee84 01830810 0x1830fb0 0021ee88 00000000 0x1830810
Oh dear, not good. We need symbols. Let’s use the Microsoft public symbol server and load the local pdb for BallsDemo:
0:000> .sympath SRV*c:\symbols*http://msdl.microsoft.com/download/symbols;C:\foo\BallsDemo Symbol search path is: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols;C:\foo\BallsDemo Expanded Symbol search path is: srv*c:\symbols*http://msdl.microsoft.com/download/symbols;c:\foo\ballsdemo 0:000> .reload Reloading current modules ......................................................... 0:000> k ChildEBP RetAddr 0021e518 5d813970 KERNELBASE!RaiseException+0x58 0021e5a8 5d813ba9 clr!RaiseTheExceptionInternalOnly+0x276 0021e668 091b2d8f clr!IL_Throw+0x14c WARNING: Frame IP not in any known module. Following frames may be wrong. 0021e768 091b2bf8 0x91b2d8f 0021e770 091b2a72 0x91b2bf8 0021e780 091b2a18 0x91b2a72 0021e788 091b29e8 0x91b2a18 0021e790 091b29ba 0x91b29e8 *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\mscorlib\eb4e1e70734f6efb9c7de7ec5f452c9e\mscorlib.ni.dll 0021e894 5cb64db5 0x91b29ba 0021e8a4 5d7021bb mscorlib_ni+0x234db5 0021e8b4 5d724be2 clr!CallDescrWorker+0x33 0021e930 5d724d84 clr!CallDescrWorkerWithHandler+0x8e 0021ea74 5d724db9 clr!MethodDesc::CallDescr+0x194 0021ea90 5d724dd9 clr!MethodDesc::CallTargetWorker+0x21 0021eaa8 5d774124 clr!MethodDescCallSite::Call_RetArgSlot+0x1c 0021ec8c 5d77427f clr!ExecuteCodeWithGuaranteedCleanupHelper+0xbb 0021ed38 5cb64cba clr!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+0x138 0021ed70 5cb67f34 mscorlib_ni+0x234cba 0021ee7c 5cbde0c4 mscorlib_ni+0x237f34 0021ee80 01830fb0 mscorlib_ni+0x2ae0c4 0021ee84 01830810 0x1830fb0 0021ee88 00000000 0x1830810
Ok, that smells better. But not useful. Oh right, we know that this is a managed exception, so let’s load sos.dll and see what’s going on:
0:000> .loadby sos.dll clr 0:000> !pe Exception object: 018f61f4 Exception type: FullCircle.YouMightWantToDebugThisException Message: Oops, I crashed. I wonder why... InnerException: System.Exception, Use !PrintException 018f609c to see more. StackTrace (generated): SP IP Function 0021E670 091B2D8F FullCircle_9190000!FullCircle.PeaceOut.I_Have_Decided_To_Leave_Microsoft()+0x17f 0021E770 091B2BF8 FullCircle_9190000!FullCircle.PeaceOut.After_Almost_14_Years_At_The_Company()+0x18 0021E778 091B2A72 FullCircle_9190000!FullCircle.PeaceOut.It_Was_Time_For_Me_To_Move_On()+0x42 0021E788 091B2A18 FullCircle_9190000!FullCircle.PeaceOut.And_Take_On_New_Challenges()+0x18 0021E790 091B29E8 FullCircle_9190000!FullCircle.PeaceOut.I_Hope_I_Was_Able_To_Teach_A_Thing_Or_Two_While_I_Was_Here()+0x18 0021E798 091B29BA FullCircle_9190000!FullCircle.PeaceOut.HopeYouRememberHowToDebug()+0xba 0021E7A8 091B28E4 FullCircle_9190000!FullCircle.PeaceOut.Because_There_Is_Tasty_Info_In_This_Crash()+0x24 0021E7B0 091B28A8 FullCircle_9190000!FullCircle.PeaceOut.YouDidntThinkIWouldReallyWriteSomethingThatCrashedAccidentallyDidYou()+0x18 0021E7B8 091B2871 BallsDemo!BallsDemo.MainWindow.MyBallsCrashed(System.Object, System.EventArgs)+0x21 0021E7CC 09152994 WindowsBase_48b0000!System.Windows.Threading.DispatcherTimer.FireTick(System.Object)+0x24 0021E7D8 0388ED6D WindowsBase_48b0000!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)+0xfd ...
I used the !PrintException (shortened to “!pe”) to grab the exception info. I cut off the callstack above for brevity. See how this matches with what we saw in the EventLog? Also, note that there’s an InnerException. This means, there’s more to dump:
0:000> !PrintException 018f609c Exception object: 018f609c Exception type: System.Exception Message: Hint: Some clues are stack-ed up for you. You might ask !dso what? InnerException: <none> StackTrace (generated): SP IP Function 0021E704 091B2ED1 FullCircle_9190000!FullCircle.PeaceOut.BangSOS_dsoIsMyFavorite()+0x41 0021E710 091B2D4A FullCircle_9190000!FullCircle.PeaceOut.I_Have_Decided_To_Leave_Microsoft()+0x13a
Hmm, alright, let’s use !dso. This is an alias for DumpStackObjects and shows the following (cut for brevity):
0:000> !dso OS Thread Id: 0x27cc (0) ESP/REG Object Name 0021E534 018f61f4 FullCircle.YouMightWantToDebugThisException 0021E56C 018f61f4 FullCircle.YouMightWantToDebugThisException 0021E5B0 018f61f4 FullCircle.YouMightWantToDebugThisException 0021E5C4 0184e854 System.Windows.Threading.DispatcherTimer 0021E5D8 0184e854 System.Windows.Threading.DispatcherTimer 0021E600 018f609c System.Exception 0021E640 018f61f4 FullCircle.YouMightWantToDebugThisException 0021E654 018f61f4 FullCircle.YouMightWantToDebugThisException 0021E710 018f6248 System.String Oops, I crashed. I wonder why... 0021E714 018f6084 System.Object[] (System.String[]) 0021E718 018f6084 System.Object[] (System.String[]) 0021E71C 018f61f4 FullCircle.YouMightWantToDebugThisException 0021E720 018f609c System.Exception 0021E724 018f6084 System.Object[] (System.String[]) 0021E728 018f606c FullCircle.ContactInfo 0021E72C 018f606c FullCircle.ContactInfo 0021E730 018f5c88 FullCircle.GoodbyeMessage 0021E734 018f5c78 FullCircle.Clue 0021E738 018f609c System.Exception 0021E73C 018f606c FullCircle.ContactInfo 0021E740 018f5c88 FullCircle.GoodbyeMessage 0021E744 018f5c78 FullCircle.Clue 0021E760 0184e854 System.Windows.Threading.DispatcherTimer 0021E778 018f57f8 FullCircle.AnotherClue 0021E77C 018f57f8 FullCircle.AnotherClue 0021E798 018f55fc System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]] 0021E79C 018f55fc System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]] 0021E7B8 0184e854 System.Windows.Threading.DispatcherTimer 0021E7BC 0184e684 BallsDemo.MainWindow
Starting from the top, the first interesting object is FullCircle.ContactInfo. Dumping that shows the following:
0:000> !do 018f606c Name: FullCircle.ContactInfo MethodTable: 09172584 EEClass: 09189ee4 Size: 24(0x18) bytes File: C:\Users\nithins\Documents\Visual Studio 2010\Projects\FullCircle\BallsDemo\bin\Debug\FullCircle.dll Fields: MT Field Offset Type VT Attr Value Name 5cc06c28 4000001 4 System.Object[] 0 instance 018f6084 EmailAddresses 5cc4f9ac 4000003 c System.String 0 instance 018f5b84 Blog 5cc4f9ac 4000004 10 System.String 0 instance 018f5bf4 Twitter
Strings can easily be dumped out just using !do. Let’s do this for the Blog string (and repeat for the other strings):
0:000> !do 018f5b84 Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 66(0x42) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: http://repne.wordpress.com Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 26 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 68 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 <<
However, EmailAddresses appears to be an array. The SOS extension has a !dumparray command to help out:
0:000> !dumparray 018f6084 Name: System.String[] MethodTable: 5cc06c28 EEClass: 5c989698 Size: 24(0x18) bytes Array: Rank 1, Number of elements 2, Type CLASS Element Methodtable: 5cc4f9ac [0] 018f5b04 [1] 018f5b44 0:000> !do 018f5b04 Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 64(0x40) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: <REDACTED> Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 25 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 6e m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 <<
Great, one object done. Looking back at the results of the !dso command, you’ll see that I left a “GoodbyeMessage” and some “Clues” to look at:
0:000> !do 018f5c88 Name: FullCircle.GoodbyeMessage MethodTable: 091724e8 EEClass: 09189e78 Size: 12(0xc) bytes File: C:\Users\nithins\Documents\Visual Studio 2010\Projects\FullCircle\BallsDemo\bin\Debug\FullCircle.dll Fields: MT Field Offset Type VT Attr Value Name 5cc4f9ac 4000005 4 System.String 0 instance 018f5c94 message 0:000> !do 018f5c94 Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 982(0x3d6) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: After nearly 14 years of debugging stress crashes,profiling and analyzing this and that, and causing trouble, I've decided to leave Microsoft and pursue an opportunity outside of the company. It's been an exceptional ride, but sadly it's time to say farewell. Microsoft is a fantastic place and the work this company continues to do astound me. You all are an extremely talented set of folks who can make some amazing things happen.Keep continuing to kickass. And remember - Have Fun. Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 484 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 41 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> !do 018f57f8 Name: FullCircle.AnotherClue MethodTable: 091723e8 EEClass: 09189c38 Size: 16(0x10) bytes File: C:\Users\nithins\Documents\Visual Studio 2010\Projects\FullCircle\BallsDemo\bin\Debug\FullCircle.dll Fields: MT Field Offset Type VT Attr Value Name 5cc4f9ac 400000a 4 System.String 0 instance 018f5760 hint 09172470 400000b 8 FullCircle.FunFacts 0 instance 018f5808 fact 0:000> !do 018f5760 Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 150(0x96) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: A Dictionary is a cool way to store a string,string of special info. Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 68 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 41 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> * Let's look at its FullCircle.FunFacts 0:000> !do 018f5808 Name: FullCircle.FunFacts MethodTable: 09172470 EEClass: 09189ce8 Size: 32(0x20) bytes File: C:\Users\nithins\Documents\Visual Studio 2010\Projects\FullCircle\BallsDemo\bin\Debug\FullCircle.dll Fields: MT Field Offset Type VT Attr Value Name 5cc4a380 4000006 4 System.Double 1 instance 13.800000 YearsAtMicrosoft 5cc4a380 4000007 c System.Double 1 instance 8.500000 YearsInTheSameOffice 5cc4f9ac 4000008 14 System.String 0 instance 018f5828 FirstAssignment 5cc52978 4000009 18 System.Int32 1 instance 5 YearsInNewYork
Hmm, a Dictionary, eh? Are there any Dictionaries to look at from !dso ?
0:000> !do 018f55fc Name: System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]] MethodTable: 5cc52438 EEClass: 5c9899ac Size: 52(0x34) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll Fields: MT Field Offset Type VT Attr Value Name 5cc52938 4000bd3 4 System.Int32[] 0 instance 018f5684 buckets 5d3f0924 4000bd4 8 ...non, mscorlib]][] 0 instance 018f56ac entries 5cc52978 4000bd5 20 System.Int32 1 instance 5 count 5cc52978 4000bd6 24 System.Int32 1 instance 5 version 5cc52978 4000bd7 28 System.Int32 1 instance -1 freeList 5cc52978 4000bd8 2c System.Int32 1 instance 0 freeCount 5cc52fd8 4000bd9 c ...Canon, mscorlib]] 0 instance 01813228 comparer 5cc4568c 4000bda 10 ...Canon, mscorlib]] 0 instance 00000000 keys 5cc4b730 4000bdb 14 ...Canon, mscorlib]] 0 instance 00000000 values 5cc4f5e8 4000bdc 18 System.Object 0 instance 00000000 _syncRoot 5cc4b794 4000bdd 1c ...SerializationInfo 0 instance 00000000 m_siInfo 0:000> * Let's look at the entries 0:000> !dumparray 018f56ac Name: System.Collections.Generic.Dictionary`2+Entry[[System.String, mscorlib],[System.String, mscorlib]][] MethodTable: 5cc52f20 EEClass: 5ca091a0 Size: 124(0x7c) bytes Array: Rank 1, Number of elements 7, Type VALUETYPE Element Methodtable: 5cc52e70 [0] 018f56b4 [1] 018f56c4 [2] 018f56d4 [3] 018f56e4 [4] 018f56f4 [5] 018f5704 [6] 018f5714
Since it’s a Dictionary<string,string> we need to dump the Key and Value for each. The Key is what the entry is pointing to, and the Value is the pointer next to it. To illustrate this, let’s dump the DWORDs at the location of the first entry:
0:000> dd 018f56b4 018f56b4 018f5254 018f52c8 63a2ad11 ffffffff 018f56c4 018f5354 018f5384 27d1ab3a ffffffff 018f56d4 018f53ec 018f5420 6e5934e6 00000000 ...
The address 0x018f5254 is the Key object, and 0x18f52c8 is the Value. You can then dump it as follows:
0:000> !do 018f5254 Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 116(0x74) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: What did the http://datawall ascii text really say? Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 51 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 57 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 <<
Or, more succintly, we can use the poi() function in cdb to give us the contents of the what the address is pointing to:
0:000> !do poi(018f56b4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 116(0x74) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: What did the http://datawall ascii text really say? Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 51 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 57 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> * And now the Value 0:000> !do poi(018f56b4+4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 138(0x8a) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: "go fuck yourself" . No really, it said that encoded in ascii. Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 62 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 22 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 <<
Backstory: Back when I was young and stupid, I was tasked with building the IE team’s first stress reporting site. Our lead wanted it to be this grand SQL backed data store that had a wall of data. Everything would go into it and could be datamined. It would be our great “Datawall.” He was passionate. After spending several weeks, I needed to take a break and work on something fun, so I started to make the front default.asp. This was back in the heyday of animated GIFs (no Flash back then). I created a big fat graphic that had DATAWALL in black letters with a Matrix like set of numbers slowly scrolling in the background. The numbers happened to be a string that was 16 characters long with their ASCII representation encoded in binary. Hey, it worked.
0:000> * And the next entry 0:000> !do poi(018f56c4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 48(0x30) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Where am I going? Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 17 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 57 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> !do poi(018f56c4+4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 104(0x68) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Read my blog in the coming weeks to find out. Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 45 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 52 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> !do poi(018f56d4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 50(0x32) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Some useful advice Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 18 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 53 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> !do poi(018f56d4+4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 102(0x66) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Have fun. If you're not having fun, get out. Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 44 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 48 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> !do poi(018f56e4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 76(0x4c) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: How is InsertFib() implemented? Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 31 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 48 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> !do poi(018f56e4+4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 110(0x6e) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Come now, I'm not going to reveal everything!Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 48 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 43 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 << 0:000> !do poi(018f56f4) Name: System.String MethodTable: 5cc4f9ac EEClass: 5c988bb0 Size: 60(0x3c) bytes File: C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: Private Twitter account Fields: MT Field Offset Type VT Attr Value Name 5cc52978 40000ed 4 System.Int32 1 instance 23 m_stringLength 5cc51dc8 40000ee 8 System.Char 1 instance 50 m_firstChar 5cc4f9ac 40000ef 8 System.String 0 shared static Empty >> Domain:Value 00420fd0:01811228 <<
You can dump out the last value yourself.
There it is. Fairly simple and straightforward, just using some very basic cdb and sos.dll commands. Educational, fun, and slightly demented. That’s how I roll.


What is the story behind the InsertFib?
InsertFib is the interview question I’ve been using forever. Insert a node into a singly linked list of Fibonacci numbers. The function should look like: int InsertFib(node **pHead, int iNum). Next time I’m hiring, stop by and we can go over this…