1

I would like to locate a .NET object nearest to a specific address on the heap.

Example situation

Imagine that from some source I got an address 0x00000000ffaaa690. When I try to dump an object (using SOS !do command) I receive:

0:000> !do 00000000ffaaa690
<Note: this object has an invalid CLASS field> Invalid object

Apparently this address does not point to a valid MT. But I know it's on the .NET heap. How can I locate the nearest MT address (the beginning of the object instance address)?

In the example case the searched object would be at address 00000000ffaaa680:

0:000> !do 00000000ffaaa680 Name: System.String MethodTable: 000007fee6a47d90 EEClass: 000007fee664e560 Size: 36(0x24) bytes (C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) String: 16457 Fields: MT Field Offset Type VT Attr Value Name 000007fee6a4f000 4000096 8 System.Int32 1 instance 6 m_arrayLength 000007fee6a4f000 4000097 c System.Int32 1 instance 5 m_stringLength 000007fee6a497d8 4000098 10 System.Char 1 instance 31 m_firstChar 000007fee6a47d90 4000099 20 System.String 0 shared static Empty 000007fee6a49688 400009a 28 System.Char[] 0 shared static WhitespaceChars

Update 1:

As Oguz pointed in the comment, there is the lno command in SOS, but I see that it was probably introduced in .NET4.0. My dump is from .NET2.0/3.5 and it seems that this command is missing :(

Sebastian
  • 3,764
  • 21
  • 28
  • 3
    Can lno help? [ListNearObj (lno) ](https://msdn.microsoft.com/en-us/library/bb190764(v=vs.110).aspx) Displays the objects preceding and following the specified address. The command looks for the address in the garbage collection heap that looks like a valid beginning of a managed object (based on a valid method table) and the object following the argument address. – Oguz Ozgul Nov 27 '15 at 12:44
  • Thanks @OguzOzgul - I remembered that something like this existed and when I didn't find it in SOS I wrote this question. Now I see that this was probably introduced in .NET4.0 and I have a dump for .NET2.0 :/ I am updating the question. – Sebastian Nov 27 '15 at 13:14
  • 2
    Try !sosex.mln. if your address lands inside an object, method, or any kind of .Net data structure, it will tell you what it is. – Steve Johnson Nov 27 '15 at 15:54
  • @SteveJohnson I ran !mln against an address on the managed heap a few days ago and the command was still running after 20 minutes. I had to restart Windbg. – Χpẘ Nov 27 '15 at 17:16
  • @user2460798 That is highly unusual. How large is the dump? Would you be able to share it with me? – Steve Johnson Nov 28 '15 at 18:02
  • @SteveJohnson it wasn't a dump. I was live debugging. I created a dynamic assembly using Powershell and was stepping through some of the CIL code, and wanted to know what a particular pointer was. Don't know if I can repro, and not sure how I would "give" the repro to you even if I did. One thing you could do is periodically look for Ctrl-Break while executing potentially long running commands. – Χpẘ Nov 28 '15 at 21:26
  • @SteveJohnson I was able to reproduce this. I got a FieldInfo from a type I created with Reflection.Emit. I then accessed the private field m_fieldHandle. I entered the value of that pointer as the arg to !mln. I let Windbg run for 20 minutes w no response. It may be the pointer was unmanaged, but it seems like !mln is not as useful if it can't report that it 's argument was to unmanaged memory. – Χpẘ Dec 10 '15 at 20:28

1 Answers1

3

Try !sosex.mln. It will show you the type of object the address lies in. It can also tell you if the address is in a managed method or other type of managed data structure.

Steve Johnson
  • 2,958
  • 13
  • 15