NetInverse Developers Blog

November 14, 2009
Category: Debugging — Tags: , , , — admin @ 11:59 pm

Managed Memory Leak will be reported by an OutOfMemoryException exception thrown by the CLR. There are a few reasons will result in it.

1) Too many objects are alive.
2) Object handle leak. Use !sos.objsize to list handles.
3) Heap fragmentation. Use !sos.dumpheap to get excessive GC Heap fragmentation report.

Category: .Net — Tags: , , , — admin @ 11:42 pm

There are two types of heap corruptions: 1) NT Heap Corruption 2) GC Heap Corruption.

GCSTRESS is a checked or debugging build with some registry keys set used to debug the GC Heap Corruption. It forces the garbage collection to occur very oftern to shake out a bug.

May 2, 2009
Category: CLR — Tags: , , , , — admin @ 12:23 am

Precode

In .Net v2.x Precode is used to do the similar thing like Prepad.

Prepad

In .Net v1.x MethodDesc has a Prepad which contains code to call Prestub (before jitting) or jitted code.

typedef struct MethodDesc {
#ifdef _DEBUG

    LPCSTR         m_pszDebugMethodName;
    LPSTR          m_pszDebugClassName;
    LPSTR          m_pszDebugMethodSignature;
    PVOID          m_pDebugEEClass;
    PVOID          m_pDebugMethodTable;

#ifdef STRESS_HEAP
    PVOID          m_GcCover;
#else
    DWORD_PTR       m_DebugAlignPad;
#endif

    unsigned short  m_iPrestubCalls;
    unsigned short  m_iSharedSlots;
    unsigned short  m_iDirectCalls;

    unsigned short  m_DebugAlignPad2;
#endif

    DWORD_PTR      m_CodeOrIL;         // pointer to code
    WORD           m_wSlotNumber;      // entry in VTable
    WORD           m_wFlags;           // IL vs native, static vs instance ...
} MethodDesc;

When you use SOS command !dumpmd, if IsJitted is “yes,” you can run !U on the m_CodeOrIL pointer to see a disassembly of the JITTED code.

Prestub

In a CLR MethodTable, a method points to a Prestub or Jitted code. Prestub traps first calls on methods so it can JIT generate native code for them.

April 26, 2009
Category: Debugging — Tags: , , , , — admin @ 12:00 pm

Prepare the tools you need for advanced system level debugging

You can use Debugging Tools for Windows to debug drivers, applications, and services on systems that are running Windows NT 4.0, Windows 2000, Windows XP, Windows Server 2003, Windows Vista, or Windows Server 2008. You can also use Debugging Tools for Windows to debug the operating system itself. Versions of the Debugging Tools for Windows package are available for 32-bit x86, native Intel Itanium, and native x64 platforms.

The latest release of Debugging Tools for Windows is available for download (see the Using Debugging Tools for Windows section on this page). You can also install the package from the Windows Driver Kit (WDK), the Platform SDK, or a Customer Support Diagnostics CD.

Note: If you have a system with a 64-bit processor and you are debugging an application on it, you must use one of the native 64-bit packages.

Download the right tools from MSDN.

-Run windbg.exe or cdb.exe

>.hh [keyword] for help

Set up Symbols

April 23, 2009
Category: .Net, CLR, Debugging — Tags: , — admin @ 10:53 pm

CLR Internal - ObjHeader

Every Object is preceded by an object header -ObjHeader (at a negative offset). ObjHeader is a DWORD and has a combination of different bit masks (defined in Syncblk.h) like hash code, AppDomain index, flags to facility string operations, thin lock bit and etc.

When the DWORD is not large enough, CLR will create a SyncBlock for the object and set the SyncBlock index in object header.

Category: .Net, CLR, Debugging — Tags: , , — admin @ 10:14 pm

CLR Internal: SyncBlock

CLR Object Internal - from Shared Source CLI Essentials

CLR Object Internal - from Shared Source CLI Essentials

Every Object is preceded by an ObjHeader (at a negative offset). The ObjHeader has an index to a SyncBlock. This index is 0 for the bulk of all instances, which indicates that the object shares a dummy SyncBlock with most other objects. All SyncBlocks are stored in SyncTable as an array and managed by SyncBlockCache.

The SyncBlock is primarily responsible for object synchronization. However, it is also a “kitchen sink” of sparsely allocated instance data. For instance, the default implementation of Hash() is based on the existence of a SyncTableEntry. And objects exposed to or from COM, or through context boundaries, can store sparse data here.

SyncTableEntries and SyncBlocks are allocated in non-GC memory. A weak pointer from the SyncTableEntry to the instance is used to ensure that the SyncBlock and SyncTableEntry are reclaimed (recycled) when the instance dies.

The organization of the SyncBlocks isn’t intuitive (at least to me). Here’s the explanation:

Before each Object is an ObjHeader. If the object has a SyncBlock, the ObjHeader contains a non-0 index to it.

The index is looked up in the g_pSyncTable of SyncTableEntries. This means the table is consecutive for all outstanding indices. Whenever it needs to grow, it doubles in size and copies all the original entries. The old table is kept until GC time, when it can be safely discarded.

Each SyncTableEntry has a backpointer to the object and a forward pointer to the actual SyncBlock. The SyncBlock is allocated out of a SyncBlockArray which is essentially just a block of SyncBlocks.

The SyncBlockArrays are managed by a SyncBlockCache that handles the actual allocations and frees of the blocks.

Each allocation and release has to handle free lists in the table of entries and the table of blocks.

We burn an extra 4 bytes for the pointer from the SyncTableEntry to the SyncBlock.

The reason for this is that many objects have a SyncTableEntry but no SyncBlock. That’s because someone (e.g. HashTable) called Hash() on them.

- syncblk.h

April 22, 2009
Category: CLR, Debugging — Tags: , , , , , — admin @ 12:08 am

An object’s CLR internal structure is:

[DWORD: SyncBlock][DWORD: MethodTable Pointer][DWORD: Reference type pointer]…[Value of Value Type field]…

Object Header: [DWORD: SyncBlock]
Object Pointer: [DWORD: MethodTable Pointer][DWORD: Reference type pointer]…[Value of Value Type field]…

Every Object is preceded by an ObjHeader (at a negative offset). The ObjHeader has an index to a SyncBlock.

Sample C# code for exploring CLR object’s internal structure

namespace ObjectInternal
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    class Program
    {
        static void Main(string[] args)
        {
            Product p = new Product();
            p.Price = 99;
            p.Index = 25;
            p.Name = "Super Product";
            p.Cat = new Cateogry();
        }
    }

    class Product
    {
        public int Price { get; set; }
        public byte Index { get; set; }
        public string Name { get; set; }
        public Cateogry Cat { get; set; }
    }

    public class Cateogry
    {
        public string Name;
    }
}

Sample output from SOS.dll debugger extension:

.load sos
extension C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll loaded

!dumpstackobjects
PDB symbol for mscorwks.dll not loaded
OS Thread Id: 0xbb4 (2996)
ESP/REG  Object   Name
0012f0d4 012c2c10 System.Object[]    (System.String[])
0012f20c 012c2c10 System.Object[]    (System.String[])
0012f218 012c2c4c ObjectInternal.Product
0012f21c 012c2c64 ObjectInternal.Cateogry
0012f438 012c2c64 ObjectInternal.Cateogry
0012f43c 012c2c4c ObjectInternal.Product
0012f440 012c2c4c ObjectInternal.Product
0012f444 012c2c10 System.Object[]    (System.String[])
0012f534 012c2c10 System.Object[]    (System.String[])
0012f6e0 012c2c10 System.Object[]    (System.String[])
0012f708 012c2c10 System.Object[]    (System.String[])

!dumpobj 012c2c4c
Name: ObjectInternal.Product
MethodTable: 00933138
EEClass: 00931384
Size: 24(0x18) bytes
 (C:\temp\ObjectInternal\ObjectInternal\bin\Debug\ObjectInternal.exe)
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79332c4c  4000001        c         System.Int32  1 instance       99 <Price>k__BackingField
79333520  4000002       10          System.Byte  1 instance       25 <Index>k__BackingField
79330a00  4000003        4        System.String  0 instance 012c2c20 <Name>k__BackingField
009331b0  4000004        8 ...Internal.Cateogry  0 instance 012c2c64 <Cat>k__BackingField

!dumpobj 012c2c20
Name: System.String
MethodTable: 79330a00
EEClass: 790ed64c
Size: 44(0x2c) bytes
 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: Super Product
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79332c4c  4000096        4         System.Int32  1 instance       14 m_arrayLength
79332c4c  4000097        8         System.Int32  1 instance       13 m_stringLength
793316e0  4000098        c          System.Char  1 instance       53 m_firstChar
79330a00  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  0015d370:012c1198 <<
79331630  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  0015d370:012c1790 <<

Physical memory layout of CLR objects:

CLR Object's Internal Structure

CLR Object's Internal Structure

We use !dumpobj to examine Product object instance, which is located at address: 0×012c2c4c. You can see that: field Name(String “Super Product”)’s address is 0×012c2c20, MethodTable is 0×79330a00. Field Cateogry’s address is 0×012c2c64 and MethodTable is 0×009331b0. Value types are directly stored as 0×63(99) and 0×19(25).

April 18, 2009
Category: Debugging — Tags: , , , , — admin @ 9:40 pm

You can use !DumpStackObjects and !DumpObj to explore an object’s internal structure.

CLR Internal - string object's internal structure

CLR Internal - string object's internal structure

A string object’s CLR internal structure is:

[DWORD: SyncBlock][DWORD: MethodTable Pointer][DWORD: length as array][DWORD: length as string][WCHAR: 1st char]…[WCHAR: NULL]

From above screenshot, you can see that the SyncBlock: 80000000 Method table pointer is: 79330a00, m_arrayLength: 9, m_stringLength: 8, m_firstChar, …

!dumpobj 012c2b2c
Name: System.String
MethodTable: 79330a00
EEClass: 790ed64c
Size: 34(0x22) bytes
 (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: abcdefgh
Fields:
      MT    Field   Offset                 Type VT     Attr    Value Name
79332c4c  4000096        4         System.Int32  1 instance        9 m_arrayLength
79332c4c  4000097        8         System.Int32  1 instance        8 m_stringLength
793316e0  4000098        c          System.Char  1 instance       61 m_firstChar
79330a00  4000099       10        System.String  0   shared   static Empty
    >> Domain:Value  0015d318:012c1198 <<
79331630  400009a       14        System.Char[]  0   shared   static WhitespaceChars
    >> Domain:Value  0015d318:012c1774 <<
April 17, 2009
Category: Debugging — Tags: , , , , — admin @ 9:21 pm

SOS Command: !DumpArray

	[-start <startIndex>]
	[-length <length>]
	[-details]
	[-nofields]
	<array object address>

This command allows you to examine elements of an array object. The arguments in detail:

-start <startIndex>: optional, only supported for single dimension array. Specify from which index the command shows the elements.
-length <length>: optional, only supported for single dimension array. Specify how many elements to show.
-details: optional. Ask the command to print out details of the element using !DumpObj and !DumpVC format.
-nofields: optional, only takes effect when -detail is used. Do not print fields of the elements. Useful for array of objects like String.

April 15, 2009
Category: Debugging — Tags: , — admin @ 12:19 am

CLR Object-Method-Type Relationship

CLR Object MethodTable EEClass Relationship

CLR Object MethodTable EEClass Relationship

Object

Object is the building block in the managed world.

Debugging Commands: !DumpObj, !DumpStackObjects, !DumpArray

Type

A type describes fields and properties that hold data, as well as methods and events that describe its behavior. The information stored in a type can include the following:

  1. The storage space that a variable of the type requires.
  2. The maximum and minimum values that it can represent.
  3. The members (methods, fields, events, and so on) that it contains.
  4. The base type it inherits from.
  5. The location where the memory for variables will be allocated at run time.
  6. The kinds of operations that are permitted.
EEClass

EEClass is the data structure used by CLR to store all information about a Type.

MethodTable

A MethodTable contains an array of structures that describes each interface implemented by the class (directly declared or indirectly declared).

Generic type instantiations (in C# syntax: C<ty_1,…,ty_n>) are represented by MethodTables, i.e. a new MethodTable gets allocated for each such instantiation. The entries in these tables (i.e. the code) are, however, often shared.

MethodDesc

Method descriptor is a data structure used to store important information for a single method.

Debugging Commands: !DumpMT !DumpMD

Older Posts »

©2009 NetInverse. All rights reserved. Powered by WordPress