-
Notifications
You must be signed in to change notification settings - Fork 385
Add gchandles and objsize commands to lldb debugger extension #3192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2981036
e126005
54ab7ba
58638a6
f021059
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,18 +39,18 @@ importance. Shortcut names for popular functions are listed in parenthesis. Type | |
| DumpHeap (dumpheap) DumpStack (dumpstack) | ||
| DumpVC EEStack (eestack) | ||
| GCRoot (gcroot) CLRStack (clrstack) | ||
| PrintException (pe) GCInfo | ||
| EHInfo | ||
| ObjSize GCInfo | ||
| PrintException (pe) EHInfo | ||
| bpmd (bpmd) | ||
|
|
||
| Examining CLR data structures Diagnostic Utilities | ||
| ----------------------------- ----------------------------- | ||
| DumpDomain (dumpdomain) VerifyHeap | ||
| EEHeap (eeheap) FindAppDomain | ||
| Name2EE (name2ee) DumpLog (dumplog) | ||
| DumpMT (dumpmt) | ||
| DumpClass (dumpclass) | ||
| DumpMD (dumpmd) | ||
| EEHeap (eeheap) FindAppDomain | ||
| Name2EE (name2ee) GCHandles | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add |
||
| DumpMT (dumpmt) DumpLog (dumplog) | ||
| DumpClass (dumpclass) SuppressJitOptimization | ||
| DumpMD (dumpmd) ThreadPool (threadpool) | ||
| Token2EE | ||
| DumpModule (dumpmodule) | ||
| DumpAssembly | ||
|
|
@@ -98,6 +98,7 @@ importance. Shortcut names for popular functions are listed in parenthesis. Type | |
| |**EHInfo** [\<*MethodDesc address*>] [\<*Code address*>]|Displays the exception handling blocks in a specified method. This command displays the code addresses and offsets for the clause block (the `try` block) and the handler block (the `catch` block).| | ||
| |**FAQ**|Displays frequently asked questions.| | ||
| |**FindAppDomain** \<*Object address*>|Determines the application domain of an object at the specified address.| | ||
| |**GCHandles** [**-perdomain**]|Displays statistics about garbage collector handles in the process.<br /><br /> The **-perdomain** option arranges the statistics by application domain.<br /><br /> Use the **GCHandles** command to find memory leaks caused by garbage collector handle leaks. For example, a memory leak occurs when code retains a large array because a strong garbage collector handle still points to it, and the handle is discarded without freeing it.| | ||
| |**GCInfo** \<*MethodDesc address*>\<*Code address*>|Displays data that indicates when registers or stack locations contain managed objects. If a garbage collection occurs, the collector must know the locations of references to objects so it can update them with new object pointer values.| | ||
| |**GCRoot** [**-nostacks**] [**-all**] \<*Object address*>|Displays information about references (or roots) to an object at the specified address.<br /><br /> The **GCRoot** command examines the entire managed heap and the handle table for handles within other objects and handles on the stack. Each stack is then searched for pointers to objects, and the finalizer queue is also searched.<br /><br /> This command does not determine whether a stack root is valid or is discarded. Use the **clrstack** and **U** commands to disassemble the frame that the local or argument value belongs to in order to determine if the stack root is still in use.<br /><br /> The **-nostacks** option restricts the search to garbage collector handles and reachable objects.<br /><br /> The **-all** option forces all roots to be displayed instead of just the unique roots.| | ||
| |**GCWhere** *\<object address>*|Displays the location and size in the garbage collection heap of the argument passed in. When the argument lies in the managed heap but is not a valid object address, the size is displayed as 0 (zero).| | ||
|
|
@@ -109,6 +110,7 @@ importance. Shortcut names for popular functions are listed in parenthesis. Type | |
| |**HistRoot** *\<root>*|Displays information related to both promotions and relocations of the specified root.<br /><br /> The root value can be used to track the movement of an object through the garbage collections.| | ||
| |**IP2MD** (**ip2md**) \<*Code address*>|Displays the `MethodDesc` structure at the specified address in code that has been JIT-compiled.| | ||
| |**Name2EE** (**name2ee**) \<*module name*> \<*type or method name*><br /><br /> -or-<br /><br /> **Name2EE** \<*module name*>**!**\<*type or method name*>|Displays the `MethodTable` structure and `EEClass` structure for the specified type or method in the specified module.<br /><br /> The specified module must be loaded in the process.<br /><br /> To get the proper type name you can browse the module by using the an IL reflection tool like Ildasm or ILSpy. You can also pass `*` as the module name parameter to search all loaded managed modules. The *module name* parameter can also be the debugger's name for a module, such as `mscorlib` or `image00400000`.<br /><br /> This command supports the Windows debugger syntax of <`module`>`!`<`type`>. The type must be fully qualified.| | ||
| |**ObjSize** [\<*Object address*>] | [**-aggregate**] [**-stat**]|Displays the size of the specified object. If you do not specify any parameters, the **ObjSize** command displays the size of all objects found on managed threads, displays all garbage collector handles in the process, and totals the size of any objects pointed to by those handles. The **ObjSize** command includes the size of all child objects in addition to the parent.<br /><br /> The **-aggregate** option can be used in conjunction with the **-stat** argument to get a detailed view of the types that are still rooted. By using **!dumpheap -stat** and **!objsize -aggregate -stat**, you can determine which objects are no longer rooted and diagnose various memory issues.| | ||
| |**PrintException** [**-nested**] [**-lines**] [\<*Exception object address*>]<br /><br /> -or-<br /><br /> **PE** [**-nested**] [\<*Exception object address*>]|Displays and formats fields of any object derived from the <xref:System.Exception> class at the specified address. If you do not specify an address, the **PrintException** command displays the last exception thrown on the current thread.<br /><br /> The **-nested** option displays details about nested exception objects.<br /><br /> The **-lines** option displays source information, if available.<br /><br /> You can use this command to format and view the `_stackTrace` field, which is a binary array.| | ||
| |**SyncBlk** [**-all** | \<*syncblk number*>]|Displays the specified `SyncBlock` structure or all `SyncBlock` structures. If you do not pass any arguments, the **SyncBlk** command displays the `SyncBlock` structure corresponding to objects that are owned by a thread.<br /><br /> A `SyncBlock` structure is a container for extra information that does not need to be created for every object. It can hold COM interop data, hash codes, and locking information for thread-safe operations.| | ||
| |**SOSFlush**|Flushes an internal SOS cache.| | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,16 +32,17 @@ DumpHeap (dumpheap) EEStack (eestack) | |
| DumpVC ClrStack (clrstack) | ||
| FinalizeQueue (finalizequeue) GCInfo | ||
| GCRoot (gcroot) EHInfo | ||
| PrintException (pe) bpmd (bpmd) | ||
| ObjSize bpmd (bpmd) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you put |
||
| PrintException (pe) | ||
|
|
||
| Examining CLR data structures Diagnostic Utilities | ||
| ----------------------------- ----------------------------- | ||
| DumpDomain (dumpdomain) VerifyHeap | ||
| EEHeap (eeheap) FindAppDomain | ||
| Name2EE (name2ee) DumpLog (dumplog) | ||
| SyncBlk (syncblk) SuppressJitOptimization | ||
| DumpMT (dumpmt) ThreadPool (threadpool) | ||
| DumpClass (dumpclass) | ||
| Name2EE (name2ee) GCHandles | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add |
||
| SyncBlk (syncblk) DumpLog (dumplog) | ||
| DumpMT (dumpmt) SuppressJitOptimization | ||
| DumpClass (dumpclass) ThreadPool (threadpool) | ||
| DumpMD (dumpmd) | ||
| Token2EE | ||
| DumpModule (dumpmodule) | ||
|
|
@@ -487,6 +488,44 @@ objects, there is a -nostacks option. | |
| The -all option forces all roots to be displayed instead of just the unique roots. | ||
| \\ | ||
|
|
||
| COMMAND: objsize. | ||
| ObjSize [<Object address>] | ||
|
|
||
| With no parameters, ObjSize lists the size of all objects found on managed | ||
| threads. It also enumerates all GCHandles in the process, and totals the size | ||
| of any objects pointed to by those handles. In calculating object size, | ||
| ObjSize includes the size of all child objects in addition to the parent. | ||
|
|
||
| For example, DumpObj lists a size of 20 bytes for this Customer object: | ||
|
|
||
| (lldb) dumpobj a79d40 | ||
| Name: Customer | ||
| MethodTable: 009038ec | ||
| EEClass: 03ee1b84 | ||
| Size: 20(0x14) bytes | ||
| (C:\pub\unittest.exe) | ||
| Fields: | ||
| MT Field Offset Type Attr Value Name | ||
| 009038ec 4000008 4 CLASS instance 00a79ce4 name | ||
| 009038ec 4000009 8 CLASS instance 00a79d2c bank | ||
| 009038ec 400000a c System.Boolean instance 1 valid | ||
|
|
||
| but ObjSize lists 152 bytes: | ||
|
|
||
| (lldb) ObjSize a79d40 | ||
| sizeof(00a79d40) = 152 ( 0x98) bytes (Customer) | ||
|
|
||
| This is because a Customer points to a Bank, has a name, and the Bank points to | ||
| an Address string. You can use ObjSize to identify any particularly large | ||
| objects, such as a managed cache in a web server. | ||
|
|
||
| While running ObjSize with no arguments may point to specific roots that hold | ||
| onto large amounts of memory it does not provide information regarding the | ||
| amount of managed memory that is still alive. This is due to the fact that a | ||
| number of roots can share a common subgraph, and that part will be reported in | ||
| the size of all the roots that reference the subgraph. | ||
| \\ | ||
|
|
||
| COMMAND: pe. | ||
| COMMAND: printexception. | ||
| PrintException [-nested] [-lines] [-ccw] [<Exception object address>] [<CCW pointer>] | ||
|
|
@@ -1763,6 +1802,84 @@ Objects with Finalizers are the easiest case, as the CLR needs to be able to | |
| call those when an AppDomain shuts down. | ||
| \\ | ||
|
|
||
| COMMAND: gchandles. | ||
| GCHandles [-type handletype] [-stat] [-perdomain] | ||
|
|
||
| GCHandles provides statistics about GCHandles in the process. | ||
|
|
||
| Paremeters: | ||
| stat - Only display the statistics and not the list of handles and | ||
| what they point to. | ||
| perdomain - Break down the statistics by the app domain in which | ||
| the handles reside. | ||
| type - A type of handle to filter it by. The handle types are: | ||
| Pinned | ||
| RefCounted | ||
| WeakShort | ||
| WeakLong | ||
| Strong | ||
| Variable | ||
| AsyncPinned | ||
| SizedRef | ||
|
|
||
| Sometimes the source of a memory leak is a GCHandle leak. For example, code | ||
| might keep a 50 Megabyte array alive because a strong GCHandle points to it, | ||
| and the handle was discarded without freeing it. | ||
|
|
||
| The most common handles are "Strong Handles," which keep the object they point | ||
| to alive until the handle is explicitly freed. "Pinned Handles" are used to | ||
| prevent the garbage collector from moving an object during collection. These | ||
| should be used sparingly, and for short periods of time. If you don't follow | ||
| that precept, the gc heap can become very fragmented. | ||
|
|
||
| Here is sample output from a very simple program. Note that the "RefCount" | ||
| field only applies to RefCount Handles, and this field will contain the | ||
| reference count: | ||
|
|
||
| 0:000> !GCHandles | ||
| Handle Type Object Size RefCount Type | ||
| 001611c0 Strong 01d00b58 84 System.IndexOutOfRangeException | ||
| 001611c4 Strong 01d00b58 84 System.IndexOutOfRangeException | ||
| 001611c8 Strong 01d1b48c 40 System.Diagnostics.LogSwitch | ||
| 001611d0 Strong 01cfd2c0 36 System.Security.PermissionSet | ||
| 001611d4 Strong 01cf7484 56 System.Object[] | ||
| 001611d8 Strong 01cf1238 32 System.SharedStatics | ||
| 001611dc Strong 01cf11c8 84 System.Threading.ThreadAbortException | ||
| 001611e0 Strong 01cf1174 84 System.Threading.ThreadAbortException | ||
| 001611e4 Strong 01cf1120 84 System.ExecutionEngineException | ||
| 001611e8 Strong 01cf10cc 84 System.StackOverflowException | ||
| 001611ec Strong 01cf1078 84 System.OutOfMemoryException | ||
| 001611f0 Strong 01cf1024 84 System.Exception | ||
| 001611f8 Strong 01cf2068 48 System.Threading.Thread | ||
| 001611fc Strong 01cf1328 112 System.AppDomain | ||
| 001613ec Pinned 02cf3268 8176 System.Object[] | ||
| 001613f0 Pinned 02cf2258 4096 System.Object[] | ||
| 001613f4 Pinned 02cf2038 528 System.Object[] | ||
| 001613f8 Pinned 01cf121c 12 System.Object | ||
| 001613fc Pinned 02cf1010 4116 System.Object[] | ||
|
|
||
| Statistics: | ||
| MT Count TotalSize Class Name | ||
| 563266dc 1 12 System.Object | ||
| 56329708 1 32 System.SharedStatics | ||
| 5632bc38 1 36 System.Security.PermissionSet | ||
| 5635f934 1 40 System.Diagnostics.LogSwitch | ||
| 5632759c 1 48 System.Threading.Thread | ||
| 5632735c 1 84 System.ExecutionEngineException | ||
| 56327304 1 84 System.StackOverflowException | ||
| 563272ac 1 84 System.OutOfMemoryException | ||
| 563270c4 1 84 System.Exception | ||
| 56328914 1 112 System.AppDomain | ||
| 56335f78 2 168 System.IndexOutOfRangeException | ||
| 563273b4 2 168 System.Threading.ThreadAbortException | ||
| 563208d0 5 16972 System.Object[] | ||
| Total 19 objects | ||
|
|
||
| Handles: | ||
| Strong Handles: 14 | ||
| Pinned Handles: 5 | ||
| \\ | ||
|
|
||
| COMMAND: histinit. | ||
| HistInit | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add
(objsize)after ObjSize.