1 -------------------------------------------------------------------------------
2 NOTE: THIS FILE CONTAINS SOS DOCUMENTATION. THE FORMAT OF THE FILE IS:
5 COMMAND: <cmd name, all lower case>
6 <descriptive text of the command>
7 \\ <these are two backslashes, immediately followed by a newline>
9 <repeat the sequence above>
11 The first command is "contents" which is the general help screen. The rest
12 correspond to SOS command names. This file is embedded as a resource in the SOS
13 binary. Be sure to list any new commands here.
14 -------------------------------------------------------------------------------
19 SOS is a debugger extension DLL designed to aid in the debugging of managed
20 programs. Functions are listed by category, then roughly in order of
21 importance. Shortcut names for popular functions are listed in parenthesis.
22 Type "soshelp <functionname>" for detailed info on that function.
24 Object Inspection Examining code and stacks
25 ----------------------------- -----------------------------
26 DumpObj (dumpobj) Threads (clrthreads)
28 DumpStackObjects (dso) IP2MD (ip2md)
29 DumpHeap (dumpheap) u (clru)
30 DumpVC DumpStack (dumpstack)
31 GCRoot (gcroot) EEStack (eestack)
32 PrintException (pe) ClrStack (clrstack)
37 Examining CLR data structures Diagnostic Utilities
38 ----------------------------- -----------------------------
40 EEHeap (eeheap) FindAppDomain
41 Name2EE (name2ee) DumpLog (dumplog)
46 DumpModule (dumpmodule)
53 Examining the GC history Other
54 ----------------------------- -----------------------------
55 HistInit (histinit) FAQ
56 HistRoot (histroot) CreateDump (createdump)
57 HistObj (histobj) Help (soshelp)
58 HistObjFind (histobjfind)
63 >> Where can I get the right version of SOS for my build?
65 If you are running a xplat version of coreclr, the sos module (exact name
66 is platform dependent) is installed in the same directory as the main coreclr
67 module. There is also an lldb sos plugin command that allows the path where
68 the sos, dac and dbi modules are loaded:
70 "setsospath /home/user/coreclr/bin/Product/Linux.x64.Debug""
72 If you are using a dump file created on another machine, it is a little bit
73 more complex. You need to make sure the dac module that came with that install
74 is in the directory set with the above command.
76 >> I have a chicken and egg problem. I want to use SOS commands, but the CLR
77 isn't loaded yet. What can I do?
81 >> I got the following error message. Now what?
84 (lldb) sos DumpStackObjects
85 The coreclr module is not loaded yet in the target process
88 This means that the clr is not loaded yet, or has been unloaded. You need to
89 wait until your managed program is running in order to use these commands. If
90 you have just started the program a good way to do this is to type
92 breakpoint set coreclr`EEStartup
94 in the debugger, and let it run. After the function EEStartup is finished,
95 there will be a minimal managed environment for executing SOS commands.
100 DumpObj [-nofields] <object address>
102 This command allows you to examine the fields of an object, as well as learn
103 important properties of the object such as the EEClass, the MethodTable, and
106 You might find an object pointer by running DumpStackObjects and choosing
107 from the resultant list. Here is a simple object:
109 (lldb) dumpobj a79d40
111 MethodTable: 009038ec
114 (/home/user/pub/unittest)
116 MT Field Offset Type VT Attr Value Name
117 009038ec 4000008 4 Customer 0 instance 00a79ce4 name
118 009038ec 4000009 8 Bank 0 instance 00a79d2c bank
120 Note that fields of type Customer and Bank are themselves objects, and you can
121 run DumpObj on them too. You could look at the field directly in memory using
122 the offset given. "dd a79d40+8 l1" would allow you to look at the bank field
123 directly. Be careful about using this to set memory breakpoints, since objects
124 can move around in the garbage collected heap.
126 What else can you do with an object? You might run GCRoot, to determine what
127 roots are keeping it alive. Or you can find all objects of that type with
128 "dumpheap -type Customer".
130 The column VT contains the value 1 if the field is a valuetype structure, and
131 0 if the field contains a pointer to another object. For valuetypes, you can
132 take the MethodTable pointer in the MT column, and the Value and pass them to
135 The arguments in detail:
136 -nofields: do not print fields of the object, useful for objects like String
141 [-start <startIndex>]
145 <array object address>
147 This command allows you to examine elements of an array object.
148 The arguments in detail:
149 -start <startIndex>: optional, only supported for single dimension array.
150 Specify from which index the command shows the elements.
151 -length <length>: optional, only supported for single dimension array.
152 Specify how many elements to show.
153 -details: optional. Ask the command to print out details
154 of the element using DumpObj and DumpVC format.
155 -nofields: optional, only takes effect when -details is used. Do
156 not print fields of the elements. Useful for arrays of
161 (lldb) sos DumpArray -start 2 -length 3 -details 00ad28d0
163 MethodTable: 03e41044
165 Size: 132(0x84) bytes
166 Array: Rank 1, Number of elements 10, Type VALUETYPE
173 (/home/user/bugs/225271/arraytest)
175 MT Field Offset Type Attr Value Name
176 5b9a628c 4000001 0 System.Int32 instance 2 x
177 5b9a628c 4000002 4 System.Int32 instance 4 y
178 5b9a628c 4000003 8 System.Int32 instance 6 z
184 (/home/user/bugs/225271/arraytest)
186 MT Field Offset Type Attr Value Name
187 5b9a628c 4000001 0 System.Int32 instance 3 x
188 5b9a628c 4000002 4 System.Int32 instance 6 y
189 5b9a628c 4000003 8 System.Int32 instance 9 z
195 (/home/user/bugs/225271/arraytest.exe)
197 MT Field Offset Type Attr Value Name
198 5b9a628c 4000001 0 System.Int32 instance 4 x
199 5b9a628c 4000002 4 System.Int32 instance 8 y
200 5b9a628c 4000003 8 System.Int32 instance 12 z
205 COMMAND: dumpstackobjects.
206 DumpStackObjects [-verify] [top stack [bottom stack]]
208 This command will display any managed objects it finds within the bounds of
209 the current stack. Combined with the stack tracing commands like K and
210 CLRStack, it is a good aid to determining the values of locals and
213 If you use the -verify option, each non-static CLASS field of an object
214 candidate is validated. This helps to eliminate false positives. It is not
215 on by default because very often in a debugging scenario, you are
216 interested in objects with invalid fields.
218 The abbreviation dso can be used for brevity.
231 [-mt <MethodTable address>]
232 [-type <partial type name>]
235 DumpHeap is a powerful command that traverses the garbage collected heap,
236 collection statistics about objects. With it's various options, it can look for
237 particular types, restrict to a range, or look for ThinLocks (see SyncBlk
238 documentation). Finally, it will provide a warning if it detects excessive
239 fragmentation in the GC heap.
241 When called without options, the output is first a list of objects in the heap,
242 followed by a report listing all the types found, their size and number:
246 00a71000 0015cde8 12 Free
247 00a7100c 0015cde8 12 Free
248 00a71018 0015cde8 12 Free
256 MT Count TotalSize Class Name
257 5ba7607c 1 12 System.Security.Permissions.HostProtectionResource
258 5ba75d54 1 12 System.Security.Permissions.SecurityPermissionFlag
259 5ba61f18 1 12 System.Collections.CaseInsensitiveComparer
261 0015cde8 6 10260 Free
262 5ba57bf8 318 18136 System.String
265 "Free" objects are simply regions of space the garbage collector can use later.
266 If 30% or more of the heap contains "Free" objects, the process may suffer from
267 heap fragmentation. This is usually caused by pinning objects for a long time
268 combined with a high rate of allocation. Here is example output where DumpHeap
269 provides a warning about fragmentation:
271 <After the Statistics section>
272 Fragmented blocks larger than 1MB:
273 Addr Size Followed by
274 00a780c0 1.5MB 00bec800 System.Byte[]
275 00da4e38 1.2MB 00ed2c00 System.Byte[]
276 00f16df0 1.2MB 01044338 System.Byte[]
278 The arguments in detail:
280 -stat Restrict the output to the statistical type summary
281 -strings Restrict the output to a statistical string value summary
282 -short Limits output to just the address of each object. This allows you
283 to easily pipe output from the command to another debugger
284 command for automation.
285 -min Ignore objects less than the size given in bytes
286 -max Ignore objects larger than the size given in bytes
287 -live Only print live objects
288 -dead Only print dead objects (objects which will be collected in the
290 -thinlock Report on any ThinLocks (an efficient locking scheme, see SyncBlk
291 documentation for more info)
293 Force heap walk to begin at lower bound of a supplied address range.
294 (During plan phase, the heap is often not walkable because objects
295 are being moved. In this case, DumpHeap may report spurious errors,
296 in particular bad objects. It may be possible to traverse more of
297 the heap after the reported bad object. Even if you specify an
298 address range, DumpHeap will start its walk from the beginning of
299 the heap by default. If it finds a bad object before the specified
300 range, it will stop before displaying the part of the heap in which
301 you are interested. This switch will force DumpHeap to begin its
302 walk at the specified lower bound. You must supply the address of a
303 good object as the lower bound for this to work. Display memory at
304 the address of the bad object to manually find the next method
305 table (use DumpMT to verify). If the GC is currently in a call to
306 memcopy, You may also be able to find the next object's address by
307 adding the size to the start address given as parameters.)
308 -mt List only those objects with the MethodTable given
309 -type List only those objects whose type name is a substring match of the
311 start Begin listing from this address
312 end Stop listing at this address
314 A special note about -type: Often, you'd like to find not only Strings, but
315 System.Object arrays that are constrained to contain Strings. ("new
316 String[100]" actually creates a System.Object array, but it can only hold
317 System.String object pointers). You can use -type in a special way to find
318 these arrays. Just pass "-type System.String[]" and those Object arrays will
319 be returned. More generally, "-type <Substring of interesting type>[]".
321 The start/end parameters can be obtained from the output of eeheap -gc. For
322 example, if you only want to list objects in the large heap segment:
325 Number of GC Heaps: 1
326 generation 0 starts at 0x00c32754
327 generation 1 starts at 0x00c32748
328 generation 2 starts at 0x00a71000
329 segment begin allocated size
330 00a70000 00a71000 010443a8 005d33a8(6108072)
331 Large object heap starts at 0x01a71000
332 segment begin allocated size
333 01a70000 01a71000 01a75000 0x00004000(16384)
334 Total Size 0x5d73a8(6124456)
335 ------------------------------
336 GC Heap Size 0x5d73a8(6124456)
338 (lldb) dumpheap 1a71000 1a75000
340 01a71000 5ba88bd8 2064
341 01a71810 0019fe48 2032 Free
342 01a72000 5ba88bd8 4096
343 01a73000 0019fe48 4096 Free
344 01a74000 5ba88bd8 4096
347 MT Count TotalSize Class Name
349 5ba88bd8 3 10256 System.Object[]
352 Finally, if GC heap corruption is present, you may see an error like this:
354 (lldb) dumpheap -stat
355 object 00a73d24: does not have valid MT
356 curr_object : 00a73d24
357 Last good object: 00a73d14
360 That indicates a serious problem. See the help for VerifyHeap for more
361 information on diagnosing the cause.
365 DumpVC <MethodTable address> <Address>
367 DumpVC allows you to examine the fields of a value class. In C#, this is a
368 struct, and lives on the stack or within an Object on the GC heap. You need
369 to know the MethodTable address to tell SOS how to interpret the fields, as
370 a value class is not a first-class object with it's own MethodTable as the
371 first field. For example:
373 (lldb) sos DumpObj a79d98
375 MethodTable: 009032d8
378 (/home/user/pub/unittest)
380 MT Field Offset Type Attr Value Name
381 0090320c 4000010 4 VALUETYPE instance 00a79d9c m_valuetype
382 009032d8 400000f 4 CLASS static 00a79d54 m_sExcep
384 m_valuetype is a value type. The value in the MT column (0090320c) is the
385 MethodTable for it, and the Value column provides the start address:
387 (lldb) sos DumpVC 0090320c 00a79d9c
392 (/home/user/pub/unittest)
394 MT Field Offset Type Attr Value Name
395 0090320c 4000001 0 CLASS instance 00a743d8 signature
396 0090320c 4000002 8 System.Int32 instance 2345 m1
397 0090320c 4000003 10 System.Boolean instance 1 b1
398 0090320c 4000004 c System.Int32 instance 1234 m2
399 0090320c 4000005 4 CLASS instance 00a79d98 backpointer
401 DumpVC is quite a specialized function. Some managed programs make heavy use
402 of value classes, while others do not.
406 GCRoot [-nostacks] <Object address>
408 GCRoot looks for references (or roots) to an object. These can exist in four
412 2. Within a GC Handle
413 3. In an object ready for finalization
414 4. As a member of an object found in 1, 2 or 3 above.
416 First, all stacks will be searched for roots, then handle tables, and finally
417 the freachable queue of the finalizer. Some caution about the stack roots:
418 GCRoot doesn't attempt to determine if a stack root it encountered is valid
419 or is old (discarded) data. You would have to use CLRStack and U to
420 disassemble the frame that the local or argument value belongs to in order to
421 determine if it is still in use.
423 Because people often want to restrict the search to gc handles and freachable
424 objects, there is a -nostacks option.
428 COMMAND: printexception.
429 PrintException [-nested] [-lines] [-ccw] [<Exception object address>] [<CCW pointer>]
431 This will format fields of any object derived from System.Exception. One of the
432 more useful aspects is that it will format the _stackTrace field, which is a
433 binary array. If _stackTraceString field is not filled in, that can be helpful
434 for debugging. You can of course use DumpObj on the same exception object to
437 If called with no parameters, PrintException will look for the last outstanding
438 exception on the current thread and print it. This will be the same exception
439 that shows up in a run of clrthreads.
441 PrintException will notify you if there are any nested exceptions on the
442 current managed thread. (A nested exception occurs when you throw another
443 exception within a catch handler already being called for another exception).
444 If there are nested exceptions, you can re-run PrintException with the
445 "-nested" option to get full details on the nested exception objects. The
446 clrthreads command will also tell you which threads have nested exceptions.
448 PrintException can display source information if available, by specifying the
449 -lines command line argument.
451 PrintException prints the exception object corresponding to a given CCW pointer,
452 which can be specified using the -ccw option.
454 The abbreviation 'pe' can be used for brevity.
457 COMMAND: threadstate.
460 The clrthreads command outputs, among other things, the state of the thread.
461 This is a bit field which corresponds to various states the thread is in.
462 To check the state of the thread, simply pass that bit field from the
463 output of clrthreads into ThreadState.
473 PreEmptive GC Alloc Lock
474 ID OSID ThreadOBJ State GC Context Domain Count APT Exception
475 0 1 250 0019b068 a020 Disabled 02349668:02349fe8 0015def0 0 MTA
476 2 2 944 001a6020 b220 Enabled 00000000:00000000 0015def0 0 MTA (Finalizer)
477 0:003> sos ThreadState b220
482 In Multi Threaded Apartment
484 Possible thread states:
485 Thread Abort Requested
488 Debug Suspend Pending
493 Blocking GC for Stack Overflow
499 In Single Threaded Apartment
500 In Multi Threaded Apartment
509 Thread Pool Worker Thread
512 Completion Port Thread
520 Threads [-live] [-special]
522 Threads (clrthreads) lists all the mananaged threads in the process.
524 -live: optional. Only print threads associated with a live thread.
525 -special: optional. With this switch, the command will display all the special
526 threads created by CLR. Those threads might not be managed threads
527 so they might not be shown in the first part of the command's
528 output. Example of special threads include: GC threads (in
529 concurrent GC and server GC), Debugger helper threads, Finalizer
530 threads, AppDomain Unload threads, and Threadpool timer threads.
532 Each thread has many attributes, many of which can be ignored. The important
533 ones are discussed below:
535 There are three ID columns:
537 1) The debugger shorthand ID (When the runtime is hosted this column might
538 display the special string "<<<<" when this internal thread object is not
539 associated with any physical thread - this may happen when the host reuses
540 the runtime internal thread object)
544 If PreEmptiveGC is enabled for a thread, then a garbage collection
545 can occur while that thread is running. For example, if you break in while
546 a managed thread is making a PInvoke call to a Win32 function, that thread
547 will be in PreEmptive GC mode.
549 The Domain column indicates what AppDomain the thread is currently executing
550 in. You can pass this value to DumpDomain to find out more.
552 The APT column gives the COM apartment mode.
554 Exception will list the last thrown exception (if any) for the thread. More
555 details can be obtained by passing the pointer value to PrintException. If
556 you get the notation "(nested exceptions)", you can get details on those
557 exceptions by switching to the thread in question, and running
558 "PrintException -nested".
562 CLRStack [-a] [-l] [-p] [-n] [-f]
563 CLRStack [-a] [-l] [-p] [-i] [variable name] [frame]
565 CLRStack attempts to provide a true stack trace for managed code only. It is
566 handy for clean, simple traces when debugging straightforward managed
567 programs. The -p parameter will show arguments to the managed function. The
568 -l parameter can be used to show information on local variables in a frame.
569 SOS can't retrieve local names at this time, so the output for locals is in
570 the format <local address> = <value>. The -a (all) parameter is a short-cut
571 for -l and -p combined.
573 The -f option (full mode) displays the native frames intermixing them with
574 the managed frames and the assembly name and function offset for the managed
577 If the debugger has the option SYMOPT_LOAD_LINES specified (either by the
578 .lines or .symopt commands), SOS will look up the symbols for every managed
579 frame and if successful will display the corresponding source file name and
580 line number. The -n (No line numbers) parameter can be specified to disable
583 When you see methods with the name "[Frame:...", that indicates a transition
584 between managed and unmanaged code. You could run IP2MD on the return
585 addresses in the call stack to get more information on each managed method.
587 On x64 platforms, Transition Frames are not displayed at this time. To avoid
588 heavy optimization of parameters and locals one can request the JIT compiler
589 to not optimize functions in the managed app by creating a file myapp.ini
590 (if your program is myapp.exe) in the same directory. Put the following lines
591 in myapp.ini and re-run:
593 [.NET Framework Debugging Control]
594 GenerateTrackingInfo=1
597 The -i option is a new EXPERIMENTAL addition to CLRStack and will use the ICorDebug
598 interfaces to display the managed stack and variables. With this option you can also
599 view and expand arrays and fields for managed variables. If a stack frame number is
600 specified in the command line, CLRStack will show you the parameters and/or locals
601 only for that frame (provided you specify -l or -p or -a of course). If a variable
602 name and a stack frame number are specified in the command line, CLRStack will show
603 you the parameters and/or locals for that frame, and will also show you the fields
604 for that variable name you specified. Here are some examples:
605 clrstack -i -a : This will show you all parameters and locals for all frames
606 clrstack -i -a 3 : This will show you all parameters and locals, for frame 3
607 clrstack -i var1 0 : This will show you the fields of 'var1' for frame 0
608 clrstack -i var1.abc 2 : This will show you the fields of 'var1', and expand
609 'var1.abc' to show you the fields of the 'abc' field,
611 clrstack -i var1.[basetype] 0 : This will show you the fields of 'var1', and
612 expand the base type of 'var1' to show you its
614 clrstack -i var1.[6] 0 : If 'var1' is an array, this will show you the element
615 at index 6 in the array, along with its fields
616 The -i options uses DML output for a better debugging experience, so typically you
617 should only need to execute "clrstack -i", and from there, click on the DML
618 hyperlinks to inspect the different managed stack frames and managed variables.
622 createdump [options] [dumpFileName]
623 -n - create minidump.
624 -h - create minidump with heap (default).
625 -t - create triage minidump.
626 -f - create full core dump (everything).
627 -d - enable diagnostic messages.
629 Creates a platform (ELF core on Linux, etc.) minidump. The pid can be placed in the dump
630 file name with %d. The default is '/tmp/coredump.%d'.
636 Given an address in managed JITTED code, IP2MD attempts to find the MethodDesc
637 associated with it. For example, this output from K:
641 frame #9: 0x00007fffffffbf60 0x00007ffff61c6d89 libcoreclr.so`MethodDesc::DoPrestub(this=0x00007ffff041f870, pDispatchingMT=0x0000000000000000) + 3001 at prestub.cpp:1490
642 frame #10: 0x00007fffffffc140 0x00007ffff61c5f17 libcoreclr.so`::PreStubWorker(pTransitionBlock=0x00007fffffffc9a8, pMD=0x00007ffff041f870) + 1399 at prestub.cpp:1037
643 frame #11: 0x00007fffffffc920 0x00007ffff5f5238c libcoreclr.so`ThePreStub + 92 at theprestubamd64.S:800
644 frame #12: 0x00007fffffffca10 0x00007ffff04981cc
645 frame #13: 0x00007fffffffca30 0x00007ffff049773c
646 frame #14: 0x00007fffffffca80 0x00007ffff04975ad
648 frame #22: 0x00007fffffffcc90 0x00007ffff5f51a0f libcoreclr.so`CallDescrWorkerInternal + 124 at calldescrworkeramd64.S:863
649 frame #23: 0x00007fffffffccb0 0x00007ffff5d6d6dc libcoreclr.so`CallDescrWorkerWithHandler(pCallDescrData=0x00007fffffffce80, fCriticalCall=0) + 476 at callhelpers.cpp:88
650 frame #24: 0x00007fffffffcd00 0x00007ffff5d6eb38 libcoreclr.so`MethodDescCallSite::CallTargetWorker(this=0x00007fffffffd0c8, pArguments=0x00007fffffffd048) + 2504 at callhelpers.cpp:633
652 (lldb) ip2md 0x00007ffff049773c
653 MethodDesc: 00007ffff7f71920
654 Method Name: Microsoft.Win32.SafeHandles.SafeFileHandle.Open(System.Func`1<Int32>)
655 Class: 00007ffff0494bf8
656 MethodTable: 00007ffff7f71a58
657 mdToken: 0000000006000008
658 Module: 00007ffff7f6b938
660 CodeAddr: 00007ffff04976c0
662 We have taken a return address into Mainy.Main, and discovered information
663 about that method. You could run U, DumpMT, DumpClass, DumpMD, or
664 DumpModule on the fields listed to learn more.
666 The "Source line" output will only be present if the debugger can find the
667 symbols for the managed module containing the given <code address>, and if the
668 debugger is configured to load line number information.
673 U [-gcinfo] [-ehinfo] [-n] [-o] <MethodDesc address> | <Code address>
675 Presents an annotated disassembly of a managed method when given a MethodDesc
676 pointer for the method, or a code address within the method body. Unlike the
677 debugger "U" function, the entire method from start to finish is printed,
678 with annotations that convert metadata tokens to names.
682 03ef015d b901000000 mov ecx,0x1
683 03ef0162 ff156477a25b call dword ptr [mscorlib_dll+0x3c7764 (5ba27764)] (System.Console.InitializeStdOutError(Boolean), mdToken: 06000713)
684 03ef0168 a17c20a701 mov eax,[01a7207c] (Object: SyncTextWriter)
685 03ef016d 89442414 mov [esp+0x14],eax
687 If you pass the -gcinfo flag, you'll get inline display of the GCInfo for
688 the method. You can also obtain this information with the GCInfo command.
690 If you pass the -ehinfo flag, you'll get inline display of exception info
691 for the method. (Beginning and end of try/finally/catch handlers, etc.).
692 You can also obtain this information with the EHInfo command.
694 If you pass the -o flag, the byte offset of each instruction from the
695 beginning of the method will be printed in addition to the absolute address of
698 If the debugger has the option SYMOPT_LOAD_LINES specified (either by the
699 .lines or .symopt commands), and if symbols are available for the managed
700 module containing the method being examined, the output of the command will
701 include the source file name and line number corresponding to the
702 disassembly. The -n (No line numbers) flag can be specified to disable this
707 c:\Code\prj.mini\exc.cs @ 38:
708 001b00b0 8b0d3020ab03 mov ecx,dword ptr ds:[3AB2030h] ("Break in debugger. When done type <Enter> to continue: ")
709 001b00b6 e8d5355951 call mscorlib_ni+0x8b3690 (51743690) (System.Console.Write(System.String), mdToken: 0600091b)
712 c:\Code\prj.mini\exc.cs @ 39:
713 001b00bc e863cdc651 call mscorlib_ni+0xf8ce24 (51e1ce24) (System.Console.ReadLine(), mdToken: 060008f6)
719 DumpStack [-EE] [-n] [top stack [bottom stack]]
721 [x86 and x64 documentation]
723 This command provides a verbose stack trace obtained by "scraping." Therefore
724 the output is very noisy and potentially confusing. The command is good for
725 viewing the complete call stack when "kb" gets confused. For best results,
726 make sure you have valid symbols.
728 -EE will only show managed functions.
730 If the debugger has the option SYMOPT_LOAD_LINES specified (either by the
731 .lines or .symopt commands), SOS will look up the symbols for every managed
732 frame and if successful will display the corresponding source file name and
733 line number. The -n (No line numbers) parameter can be specified to disable
736 You can also pass a stack range to limit the output.
740 EEStack [-short] [-EE]
742 This command runs DumpStack on all threads in the process. The -EE option is
743 passed directly to DumpStack. The -short option tries to narrow down the
744 output to "interesting" threads only, which is defined by
746 1) The thread has taken a lock.
747 2) The thread has been "hijacked" in order to allow a garbage collection.
748 3) The thread is currently in managed code.
750 See the documentation for DumpStack for more info.
754 EHInfo (<MethodDesc address> | <Code address>)
756 EHInfo shows the exception handling blocks in a jitted method. For each
757 handler, it shows the type, including code addresses and offsets for the clause
758 block and the handler block. For a TYPED handler, this would be the "try" and
759 "catch" blocks respectively.
763 (lldb) sos EHInfo 33bbd3a
765 Method Name: MainClass.Main()
767 MethodTable: 0331121c
773 EHHandler 0: TYPED catch(System.IO.FileNotFoundException)
774 Clause: [033bbd2b, 033bbd3c] [8b, 9c]
775 Handler: [033bbd3c, 033bbd50] [9c, b0]
778 Clause: [033bbd83, 033bbda3] [e3, 103]
779 Handler: [033bbda3, 033bbdc5] [103, 125]
781 EHHandler 2: TYPED catch(System.Exception)
782 Clause: [033bbd7a, 033bbdc5] [da, 125]
783 Handler: [033bbdc5, 033bbdd6] [125, 136]
788 GCInfo (<MethodDesc address> | <Code address>)
790 GCInfo is especially useful for CLR Devs who are trying to determine if there
791 is a bug in the JIT Compiler. It parses the GCEncoding for a method, which is a
792 compressed stream of data indicating when registers or stack locations contain
793 managed objects. It is important to keep track of this information, because if
794 a garbage collection occurs, the collector needs to know where roots are so it
795 can update them with new object pointer values.
797 Here is sample output where you can see the change in register state. Normally
798 you would print this output out and read it alongside a disassembly of the
799 method. For example, the notation "reg EDI becoming live" at offset 0x11 of the
800 method might correspond to a "mov edi,ecx" statement.
802 (lldb) sos GCInfo 5b68dbb8 (5b68dbb8 is the start of a JITTED method)
804 preJIT generated code
812 saved reg. mask = 000B
814 fully interruptible=yes
817 exception handlers = no
824 var ptr tab count = 0
830 14 | [EBP+14H] an untracked local
831 10 | [EBP+10H] an untracked local
832 0C | [EBP+0CH] an untracked local
833 08 | [EBP+08H] an untracked local
834 44 | [EBP-04H] an untracked local
835 F1 79 | 0011 reg EDI becoming live
836 72 | 0013 reg ESI becoming live
841 56 | 0025 reg EDX becoming live
842 4A | 0027 reg ECX becoming live
843 0E | 002D reg ECX becoming dead
844 10 | 002D reg EDX becoming dead
846 F0 31 | 0036 reg ESI becoming dead
847 38 | 0036 reg EDI becoming dead
850 This function is important for CLR Devs, but very difficult for anyone else to
851 make sense of it. You would usually come to use it if you suspect a gc heap
852 corruption bug caused by invalid GCEncoding for a particular method.
856 bpmd [-nofuturemodule] <module name> <method name> [<il offset>]
857 bpmd <source file name>:<line number>
858 bpmd -md <MethodDesc>
860 bpmd -clear <pending breakpoint number>
863 bpmd provides managed breakpoint support. If it can resolve the method name
864 to a loaded, jitted or ngen'd function it will create a breakpoint with "bp".
865 If not then either the module that contains the method hasn't been loaded yet
866 or the module is loaded, but the function is not jitted yet. In these cases,
867 bpmd asks the Windows Debugger to receive CLR Notifications, and waits to
868 receive news of module loads and JITs, at which time it will try to resolve
869 the function to a breakpoint. -nofuturemodule can be used to suppress
870 creating a breakpoint against a module that has not yet been loaded.
872 Management of the list of pending breakpoints can be done via bpmd -list,
873 bpmd -clear, and bpmd -clearall commands. bpmd -list generates a list of
874 all of the pending breakpoints. If the pending breakpoint has a non-zero
875 module id, then that pending breakpoint is specific to function in that
876 particular loaded module. If the pending breakpoint has a zero module id, then
877 the breakpoint applies to modules that have not yet been loaded. Use
878 bpmd -clear or bpmd -clearall to remove pending breakpoints from the list.
880 This brings up a good question: "I want to set a breakpoint on the main
881 method of my application. How can I do this?"
883 1) Stop after coreclr is loaded - TBD
885 2) Add the breakpoint with command such as:
886 bpmd myapp.exe MyApp.Main
888 4) You will stop at the start of MyApp.Main. If you type "bl" you will
889 see the breakpoint listed.
891 To correctly specify explicitly implemented methods make sure to retrieve the
892 method name from the metadata, or from the output of the "dumpmt -md" command.
899 public class ExplicitItfImpl : I1
902 void I1.M1() // this method's name is 'I1.M1'
906 bpmd myapp.exe ExplicitItfImpl.I1.M1
909 bpmd works equally well with generic types. Adding a breakpoint on a generic
910 type sets breakpoints on all already JIT-ted generic methods and sets a pending
911 breakpoint for any instantiation that will be JIT-ted in the future.
913 Example for generics:
914 Given the following two classes:
919 public void F(T1 p1, T2 p2, T3 p3)
925 static public void G<W>(W w)
929 One would issue the following commands to set breapoints on G3.F() and
932 bpmd myapp.exe G3`3.F
933 bpmd myapp.exe G1`1.G
935 And for explicitly implemented methods on generic interfaces:
936 public interface IT1<T>
941 public class ExplicitItfImpl<U> : IT1<U>
944 void IT1<U>.M1(U u) // this method's name is 'IT1<U>.M1'
948 bpmd bpmd.exe ExplicitItfImpl`1.IT1<U>.M1
951 If IT1 and ExplicitItfImpl are types declared inside another class,
952 Outer, the bpmd command would become:
954 bpmd bpmd.exe Outer+ExplicitItfImpl`1.Outer.IT1<U>.M1
956 (note that the fully qualified type name for ExplicitItfImpl became
957 Outer+ExplicitItfImpl, using the '+' separator, while the method name
958 is Outer.IT1<U>.M1, using a '.' as the separator)
960 Furthermore, if the Outer class resides in a namespace, NS, the bpmd
961 command to use becomes:
963 bpmd bpmd.exe NS.Outer+ExplicitItfImpl`1.NS.Outer.IT1<U>.M1
965 bpmd does not accept offsets nor parameters in the method name. You can add
966 an IL offset as an optional parameter seperate from the name. If there are overloaded
967 methods, bpmd will set a breakpoint for all of them.
969 In the case of hosted environments such as SQL, the module name may be
970 complex, like 'price, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
971 For this case, just be sure to surround the module name with single quotes,
974 bpmd 'price, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' Price.M2
979 DumpDomain [<Domain address>]
981 When called with no parameters, DumpDomain will list all the AppDomains in the
982 process. It enumerates each Assembly loaded into those AppDomains as well.
983 In addition to your application domain, and any domains it might create, there
984 are two special domains: the Shared Domain and the System Domain.
986 Any Assembly pointer in the output can be passed to DumpAssembly. Any Module
987 pointer in the output can be passed to DumpModule. Any AppDomain pointer can
988 be passed to DumpDomain to limit output only to that AppDomain. Other
989 functions provide an AppDomain pointer as well, such as clrthreads where it lists
990 the current AppDomain for each thread.
994 EEHeap [-gc] [-loader]
996 EEHeap enumerates process memory consumed by internal CLR data structures. You
997 can limit the output by passing "-gc" or "-loader". All information will be
1000 The information for the Garbage Collector lists the ranges of each Segment in
1001 the managed heap. This can be useful if you believe you have an object pointer.
1002 If the pointer falls within a segment range given by "eeheap -gc", then you do
1003 have an object pointer, and can attempt to run "dumpobj" on it.
1005 Here is output for a simple program:
1008 Number of GC Heaps: 1
1009 generation 0 starts at 0x00a71018
1010 generation 1 starts at 0x00a7100c
1011 generation 2 starts at 0x00a71000
1012 segment begin allocated size
1013 00a70000 00a71000 00a7e01c 0000d01c(53276)
1014 Large object heap starts at 0x01a71000
1015 segment begin allocated size
1016 01a70000 01a71000 01a76000 0x00005000(20480)
1017 Total Size 0x1201c(73756)
1018 ------------------------------
1019 GC Heap Size 0x1201c(73756)
1021 So the total size of the GC Heap is only 72K. On a large web server, with
1022 multiple processors, you can expect to see a GC Heap of 400MB or more. The
1023 Garbage Collector attempts to collect and reclaim memory only when required to
1024 by memory pressure for better performance. You can also see the notion of
1025 "generations," wherein the youngest objects live in generation 0, and
1026 long-lived objects eventually get "promoted" to generation 2.
1028 The loader output lists various private heaps associated with AppDomains. It
1029 also lists heaps associated with the JIT compiler, and heaps associated with
1030 Modules. For example:
1032 (lldb) eeheap -loader
1034 --------------------------------------
1035 System Domain: 5e0662a0
1036 LowFrequencyHeap:008f0000(00002000:00001000) Size: 0x00001000 bytes.
1037 HighFrequencyHeap:008f2000(00008000:00001000) Size: 0x00001000 bytes.
1038 StubHeap:008fa000(00002000:00001000) Size: 0x00001000 bytes.
1039 Total size: 0x3000(12288)bytes
1040 --------------------------------------
1041 Shared Domain: 5e066970
1042 LowFrequencyHeap:00920000(00002000:00001000) 03e30000(00010000:00003000) Size: 0x00004000 bytes.
1043 Wasted: 0x00001000 bytes.
1044 HighFrequencyHeap:00922000(00008000:00001000) Size: 0x00001000 bytes.
1045 StubHeap:0092a000(00002000:00001000) Size: 0x00001000 bytes.
1046 Total size: 0x6000(24576)bytes
1047 --------------------------------------
1049 LowFrequencyHeap:00900000(00002000:00001000) 03ee0000(00010000:00003000) Size: 0x00004000 bytes.
1050 Wasted: 0x00001000 bytes.
1051 HighFrequencyHeap:00902000(00008000:00003000) Size: 0x00003000 bytes.
1052 StubHeap:0090a000(00002000:00001000) Size: 0x00001000 bytes.
1053 Total size: 0x8000(32768)bytes
1054 --------------------------------------
1056 Normal JIT:03ef0000(00010000:00002000) Size: 0x00002000 bytes.
1057 Total size: 0x2000(8192)bytes
1058 --------------------------------------
1060 Module 5ba22410: Size: 0x00000000 bytes.
1061 Module 001c1320: Size: 0x00000000 bytes.
1062 Module 001c03f0: Size: 0x00000000 bytes.
1063 Module 001caa38: Size: 0x00000000 bytes.
1064 Total size: 0x0(0)bytes
1065 --------------------------------------
1066 Module Lookup Table heaps:
1067 Module 5ba22410:Size: 0x00000000 bytes.
1068 Module 001c1320:Size: 0x00000000 bytes.
1069 Module 001c03f0:Size: 0x00000000 bytes.
1070 Module 001caa38:03ec0000(00010000:00002000) Size: 0x00002000 bytes.
1071 Total size: 0x2000(8192)bytes
1072 --------------------------------------
1073 Total LoaderHeap size: 0x15000(86016)bytes
1074 =======================================
1076 By using eeheap to keep track of the growth of these private heaps, we are
1077 able to rule out or include them as a source of a memory leak.
1081 Name2EE <module name> <type or method name>
1082 Name2EE <module name>!<type or method name>
1084 This function allows you to turn a class name into a MethodTable and EEClass.
1085 It turns a method name into a MethodDesc. Here is an example for a method:
1087 (lldb) name2ee unittest.exe MainClass.Main
1090 MethodDesc: 00902f40
1091 Name: MainClass.Main()
1092 JITTED Code Address: 03ef00b8
1096 (lldb) name2ee unittest!MainClass
1099 MethodTable: 009032d8
1103 The module you are "browsing" with Name2EE needs to be loaded in the process.
1104 To get a type name exactly right, first browse the module with ILDASM. You
1105 can also pass * as the <module name> to search all loaded managed modules.
1106 <module name> can also be the debugger's name for a module, such as
1107 mscorlib or image00400000.
1109 The <module>!<type> syntax is also supported. You can use an asterisk on the
1110 left of the !, but the type on the right side needs to be fully qualified.
1112 If you are looking for a way to display a static field of a class (and you
1113 don't have an instance of the class, so dumpobj won't help you), note that
1114 once you have the EEClass, you can run DumpClass, which will display the
1115 value of all static fields.
1117 There is yet one more way to specify a module name. In the case of modules
1118 loaded from an assembly store (such as a SQL db) rather than disk, the
1119 module name will look like this:
1121 price, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
1123 For this kind of module, simply use price as the module name:
1125 0:044> name2ee price Price
1126 Module: 10f028b0 (price, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null)
1128 MethodTable: 11a47ae0
1132 Where are we getting these module names from? Run DumpDomain to see a list of
1133 all loaded modules in all domains. And remember that you can browse all the
1134 types in a module with DumpModule -mt <module pointer>.
1138 DumpMT [-MD] <MethodTable address>
1140 Examine a MethodTable. Each managed object has a MethodTable pointer at the
1141 start. If you pass the "-MD" flag, you'll also see a list of all the methods
1142 defined on the object.
1146 DumpClass <EEClass address>
1148 The EEClass is a data structure associated with an object type. DumpClass
1149 will show attributes, as well as list the fields of the type. The output is
1150 similar to DumpObj. Although static field values will be displayed,
1151 non-static values won't because you need an instance of an object for that.
1153 You can get an EEClass to look at from DumpMT, DumpObj, Name2EE, and
1154 Token2EE among others.
1158 DumpMD <MethodDesc address>
1160 This command lists information about a MethodDesc. You can use ip2md to turn
1161 a code address in a managed function into a MethodDesc:
1163 (lldb) dumpmd 902f40
1164 Method Name: Mainy.Main()
1166 MethodTable: 009032d8
1172 If IsJitted is "yes," you can run U on the CodeAddr pointer to see a
1173 disassembly of the JITTED code. You can call also DumpClass, DumpMT,
1174 DumpModule on the Class, MethodTable and Module fields above.
1178 Token2EE <module name> <token>
1180 This function allows you to turn a metadata token into a MethodTable or
1181 MethodDesc. Here is an example showing class tokens being resolved:
1183 (lldb) sos Token2EE unittest.exe 02000003
1186 MethodTable: 0090375c
1189 (lldb) sos Token2EE image00400000 02000004
1192 MethodTable: 009038ec
1196 The module you are "browsing" with Token2EE needs to be loaded in the process.
1197 This function doesn't see much use, especially since a tool like ILDASM can
1198 show the mapping between metadata tokens and types/methods in a friendlier way.
1199 But it could be handy sometimes.
1201 You can pass "*" for <module name> to find what that token maps to in every
1202 loaded managed module. <module name> can also be the debugger's name for a
1203 module, such as mscorlib or image00400000.
1206 COMMAND: dumpmodule.
1207 DumpModule [-mt] <Module address>
1209 You can get a Module address from DumpDomain, DumpAssembly and other
1210 functions. Here is sample output:
1212 (lldb) sos DumpModule 1caa50
1213 Name: /home/user/pub/unittest
1216 LoaderHeap: 001cab3c
1217 TypeDefToMethodTableMap: 03ec0010
1218 TypeRefToMethodTableMap: 03ec0024
1219 MethodDefToDescMap: 03ec0064
1220 FieldDefToDescMap: 03ec00a4
1221 MemberRefToDescMap: 03ec00e8
1222 FileReferencesMap: 03ec0128
1223 AssemblyReferencesMap: 03ec012c
1224 MetaData start address: 00402230 (1888 bytes)
1226 The Maps listed map metadata tokens to CLR data structures. Without going into
1227 too much detail, you can examine memory at those addresses to find the
1228 appropriate structures. For example, the TypeDefToMethodTableMap above can be
1232 03ec0010 00000000 00000000 0090320c 0090375c
1233 03ec0020 009038ec ...
1235 This means TypeDef token 2 maps to a MethodTable with the value 0090320c. You
1236 can run DumpMT to verify that. The MethodDefToDescMap takes a MethodDef token
1237 and maps it to a MethodDesc, which can be passed to dumpmd.
1239 There is a new option "-mt", which will display the types defined in a module,
1240 and the types referenced by the module. For example:
1242 (lldb) sos DumpModule -mt 1aa580
1243 Name: /home/user/pub/unittest
1245 MetaData start address: 0040220c (1696 bytes)
1247 Types defined in this module
1250 --------------------------------------------------------------------------
1251 030d115c 0x02000002 Funny
1252 030d1228 0x02000003 Mainy
1254 Types referenced in this module
1257 --------------------------------------------------------------------------
1258 030b6420 0x01000001 System.ValueType
1259 030b5cb0 0x01000002 System.Object
1260 030fceb4 0x01000003 System.Exception
1261 0334e374 0x0100000c System.Console
1262 03167a50 0x0100000e System.Runtime.InteropServices.GCHandle
1263 0336a048 0x0100000f System.GC
1267 COMMAND: dumpassembly.
1268 DumpAssembly <Assembly address>
1272 (lldb) sos DumpAssembly 1ca248
1273 Parent Domain: 0014f000
1274 Name: /home/user/pub/unittest
1275 ClassLoader: 001ca060
1277 001caa50 /home/user/pub/unittest
1279 An assembly can consist of multiple modules, and those will be listed. You can
1280 get an Assembly address from the output of DumpDomain.
1283 COMMAND: dumpruntimetypes.
1286 DumpRuntimeTypes finds all System.RuntimeType objects in the gc heap and
1287 prints the type name and MethodTable they refer too. Sample output:
1289 Address Domain MT Type Name
1290 ------------------------------------------------------------------------------
1291 a515f4 14a740 5baf8d28 System.TypedReference
1292 a51608 14a740 5bb05764 System.Globalization.BaseInfoTable
1293 a51958 14a740 5bb05b24 System.Globalization.CultureInfo
1294 a51a44 14a740 5bb06298 System.Globalization.GlobalizationAssembly
1295 a51de0 14a740 5bb069c8 System.Globalization.TextInfo
1296 a56b98 14a740 5bb12d28 System.Security.Permissions.HostProtectionResource
1297 a56bbc 14a740 5baf7248 System.Int32
1298 a56bd0 14a740 5baf3fdc System.String
1299 a56cfc 14a740 5baf36a4 System.ValueType
1302 This command will print a "?" in the domain column if the type is loaded into multiple
1303 AppDomains. For example:
1305 (lldb) sos DumpRuntimeTypes
1306 Address Domain MT Type Name
1307 ------------------------------------------------------------------------------
1308 28435a0 ? 3f6a8c System.TypedReference
1309 28435b4 ? 214d6c System.ValueType
1310 28435c8 ? 216314 System.Enum
1311 28435dc ? 2147cc System.Object
1312 284365c ? 3cd57c System.IntPtr
1313 2843670 ? 3feaac System.Byte
1314 2843684 ? 23a544c System.IEquatable`1[[System.IntPtr, mscorlib]]
1315 2843784 ? 3c999c System.Int32
1316 2843798 ? 3caa04 System.IEquatable`1[[System.Int32, mscorlib]]
1320 DumpSig <sigaddr> <moduleaddr>
1322 This command dumps the signature of a method or field given by <sigaddr>. This is
1323 useful when you are debugging parts of the runtime which returns a raw PCCOR_SIGNATURE
1324 structure and need to know what its contents are.
1326 Sample output for a method:
1327 0:000> sos DumpSig 0x000007fe`ec20879d 0x000007fe`eabd1000
1328 [DEFAULT] [hasThis] Void (Boolean,String,String)
1330 The first section of the output is the calling convention. This includes, but is not
1331 limited to, "[DEFAULT]", "[C]", "[STDCALL]", "[THISCALL]", and so on. The second
1332 portion of the output is either "[hasThis]" or "[explicit]" for whether the method
1333 is an instance method or a static method respectively. The third portion of the
1334 output is the return value (in this case a "void"). Finally, the method's arguments
1335 are printed as the final portion of the output.
1337 Sample output for a field:
1338 0:000> sos DumpSig 0x000007fe`eb7fd8cd 0x000007fe`eabd1000
1339 [FIELD] ValueClass System.RuntimeTypeHandle
1341 DumpSig will also work with generics. Here is the output for the following
1343 public A Test(IEnumerable<B> n)
1345 0:000> sos DumpSig 00000000`00bc2437 000007ff00043178
1346 [DEFAULT] [hasThis] __Canon (Class System.Collections.Generic.IEnumerable`1<__Canon>)
1349 COMMAND: dumpsigelem.
1350 DumpSigElem <sigaddr> <moduleaddr>
1352 This command dumps a single element of a signature object. For most circumstances,
1353 you should use DumpSig to look at individual signature objects, but if you find a
1354 signature that has been corrupted in some manner you can use DumpSigElem to read out
1355 the valid portions of it.
1357 If we look at a valid signature object for a method we see the following:
1358 0:000> dumpsig 0x000007fe`ec20879d 0x000007fe`eabd1000
1359 [DEFAULT] [hasThis] Void (Boolean,String,String)
1361 We can look at the individual elements of this object by adding the offsets into the
1362 object which correspond to the return value and parameters:
1363 0:000> sos DumpSigElem 0x000007fe`ec20879d+2 0x000007fe`eabd1000
1365 0:000> sos DumpSigElem 0x000007fe`ec20879d+3 0x000007fe`eabd1000
1367 0:000> sos DumpSigElem 0x000007fe`ec20879d+4 0x000007fe`eabd1000
1369 0:000> sos DumpSigElem 0x000007fe`ec20879d+5 0x000007fe`eabd1000
1372 We can do something similar for fields. Here is the full signature of a field:
1373 0:000> dumpsig 0x000007fe`eb7fd8cd 0x000007fe`eabd1000
1374 [FIELD] ValueClass System.RuntimeTypeHandle
1376 Using DumpSigElem we can find the type of the field by adding the offset of it (1) to
1377 the address of the signature:
1378 0:000> sos DumpSigElem 0x000007fe`eb7fd8cd+1 0x000007fe`eabd1000
1379 ValueClass System.RuntimeTypeHandle
1381 DumpSigElem will also work with generics. Let a function be defined as follows:
1382 public A Test(IEnumerable<B> n)
1384 The elements of this signature can be obtained by adding offsets into the signature
1385 when calling DumpSigElem:
1387 0:000> sos DumpSigElem 00000000`00bc2437+2 000007ff00043178
1389 0:000> sos DumpSigElem 00000000`00bc2437+4 000007ff00043178
1390 Class System.Collections.Generic.IEnumerable`1<__Canon>
1392 The actual offsets that you should add are determined by the contents of the
1393 signature itself. By trial and error you should be able to find various elements
1398 DumpIL <Managed DynamicMethod object> |
1399 <DynamicMethodDesc pointer> |
1400 <MethodDesc pointer> |
1403 DumpIL prints the IL code associated with a managed method. We added this
1404 function specifically to debug DynamicMethod code which was constructed on
1405 the fly. Happily it works for non-dynamic code as well.
1407 You can use it in four ways:
1409 1) If you have a System.Reflection.Emit.DynamicMethod object, just pass
1410 the pointer as the first argument.
1411 2) If you have a DynamicMethodDesc pointer you can use that to print the
1412 IL associated with the dynamic method.
1413 3) If you have an ordinary MethodDesc, you can see the IL for that as well,
1414 just pass it as the first argument.
1415 4) If you have a pointer directly to the IL, specify /i followed by the
1416 the IL address. This is useful for writers of profilers that instrument
1420 Note that dynamic IL is constructed a bit differently. Rather than referring
1421 to metadata tokens, the IL points to objects in a managed object array. Here
1422 is a simple example of the output for a dynamic method:
1424 0:000> sos DumpIL b741dc
1425 This is dynamic IL. Exception info is not reported at this time.
1426 If a token is unresolved, run "sos DumpObj <addr>" on the addr given
1427 in parenthesis. You can also look at the token table yourself, by
1428 running "DumpArray 00b77388".
1430 IL_0000: ldstr 70000002 "Inside invoked method "
1431 IL_0005: call 6000003 System.Console.WriteLine(System.String)
1433 IL_000b: newarr 2000004 "System.Int32"
1439 COMMAND: verifyheap.
1442 VerifyHeap is a diagnostic tool that checks the garbage collected heap for
1443 signs of corruption. It walks objects one by one in a pattern like this:
1446 while(o != endobject)
1448 o.ValidateAllFields();
1449 o = (Object *) o + o.Size();
1452 If an error is found, VerifyHeap will report it. I'll take a perfectly good
1453 object and corrupt it:
1455 (lldb) dumpobj a79d40
1457 MethodTable: 009038ec
1459 Size: 20(0x14) bytes
1460 (/home/user/pub/unittest)
1462 MT Field Offset Type Attr Value Name
1463 009038ec 4000008 4 CLASS instance 00a79ce4 name
1464 009038ec 4000009 8 CLASS instance 00a79d2c bank
1465 009038ec 400000a c System.Boolean instance 1 valid
1467 (lldb) ed a79d40+4 01 (change the name field to the bogus pointer value 1)
1468 (lldb) sos VerifyHeap
1469 object 01ee60dc: bad member 00000003 at 01EE6168
1470 Last good object: 01EE60C4.
1472 If this gc heap corruption exists, there is a serious bug in your own code or
1473 in the CLR. In user code, an error in constructing PInvoke calls can cause
1474 this problem, and running with Managed Debugging Assistants is advised. If that
1475 possibility is eliminated, consider contacting Microsoft Product Support for
1480 DumpLog [-addr <addressOfStressLog>] [<Filename>]
1482 To aid in diagnosing hard-to-reproduce stress failures, the CLR team added an
1483 in-memory log capability. The idea was to avoid using locks or I/O which could
1484 disturb a fragile repro environment. The DumpLog function allows you to write
1485 that log out to a file. If no Filename is specified, the file "Stresslog.txt"
1486 in the current directory is created.
1488 The optional argument addr allows one to specify a stress log other then the
1492 Attempting to dump Stress log to file 'StressLog.txt'
1494 SUCCESS: Stress log dumped
1496 To turn on the stress log, set the following registry keys under
1497 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework:
1500 (DWORD) StressLog = 1
1501 (DWORD) LogFacility = 0xffffffbf (this is a bit mask, almost all logging is on.
1502 This is also the default value if the key
1504 (DWORD) StressLogSize = 65536 (this is the default value if the key isn't
1506 (DWORD) LogLevel = 6 (this is the default value if the key isn't
1507 specified. The higher the number the more
1508 detailed logs are generated. The maximum
1509 value is decimal 10)
1511 StressLogSize is the size in bytes of the in-memory log allocated for each
1512 thread in the process. In the case above, each thread gets a 64K log. You
1513 could increase this to get more logging, but more memory will be required for
1514 this log in the process. For example, 20 threads with 524288 bytes per thread
1515 has a memory demand of 10 Megabytes. The stress log is circular so new entries
1516 will replace older ones on threads which have reached their buffer limit.
1518 The log facilities are defined as follows:
1529 CLASSLOADER 0x00000400
1537 THREADPOOL 0x00040000
1540 MARSHALER 0x00200000
1544 APPDOMAIN 0x02000000
1545 CODESHARING 0x04000000
1551 Here is some sample output:
1553 3560 9.981137099 : `SYNC` RareEnablePremptiveGC: entering.
1556 3560 9.981135033 : `GC`GCALLOC`GCROOTS` ========== ENDGC 4194 (gen = 2,
1557 collect_classes = 0) ==========={
1559 3560 9.981125826 : `GC` Segment mem 00C61000 alloc
1560 = 00D071F0 used 00D09254 committed 00D17000
1562 3560 9.981125726 : `GC` Generation 0 [00CED07C, 00000000
1565 3560 9.981125529 : `GC` Generation 1 [00CED070, 00000000
1568 3560 9.981125103 : `GC` Generation 2 [00C61000, 00000000
1571 3560 9.981124963 : `GC` GC Heap 00000000
1573 3560 9.980618994 : `GC`GCROOTS` GcScanHandles (Promotion Phase = 0)
1575 The first column is the OS thread ID for the thread appending to the log,
1576 the second column is the timestamp, the third is the facility category for the
1577 log entry, and the fourth contains the log message. The facility field is
1578 expressed as `facility1`facility2`facility3`. This facilitates the creation of
1579 filters for displaying only specific message categories. To make sense of this
1580 log, you would probably want the Shared Source CLI to find out exactly where
1584 COMMAND: findappdomain.
1585 FindAppDomain <Object address>
1587 FindAppDomain will attempt to resolve the AppDomain of an object. For example,
1588 using an Object Pointer from the output of DumpStackObjects:
1590 (lldb) sos FindAppDomain 00a79d98
1595 You can find out more about the AppDomain with the DumpDomain command. Not
1596 every object has enough clues about it's origin to determine the AppDomain.
1597 Objects with Finalizers are the easiest case, as the CLR needs to be able to
1598 call those when an AppDomain shuts down.
1604 Before running any of the Hist - family commands you need to initialize the SOS
1605 structures from the stress log saved in the debuggee. This is achieved by the
1611 Attempting to read Stress log
1613 facilitiesToLog = 0xffffffff
1615 MaxLogSizePerThread = 0x10000 (65536)
1616 MaxTotalLogSize = 0x1000000 (16777216)
1617 CurrentTotalLogChunk = 9
1619 Clock frequency = 3.392 GHz
1621 Last message time 15:26:56
1622 Total elapsed time 25.077 sec
1623 .....................................
1624 ---------------------------- 2407 total entries -----------------------------
1627 SUCCESS: GCHist structures initialized
1631 COMMAND: histobjfind.
1632 HistObjFind <obj_address>
1634 To examine log entries related to an object whose present address is known one
1635 would use this command. The output of this command contains all entries that
1636 reference the object:
1638 (lldb) histobjfind 028970d4
1639 GCCount Object Message
1640 ---------------------------------------------------------
1641 2296 028970d4 Promotion for root 01e411b8 (MT = 5b6c5cd8)
1642 2296 028970d4 Relocation NEWVALUE for root 00223fc4
1643 2296 028970d4 Relocation NEWVALUE for root 01e411b8
1645 2295 028970d4 Promotion for root 01e411b8 (MT = 5b6c5cd8)
1646 2295 028970d4 Relocation NEWVALUE for root 00223fc4
1647 2295 028970d4 Relocation NEWVALUE for root 01e411b8
1655 The root value obtained from !HistObjFind can be used to track the movement of
1656 an object through the GCs.
1658 HistRoot provides information related to both promotions and relocations of the
1659 root specified as the argument.
1661 (lldb) histroot 01e411b8
1662 GCCount Value MT Promoted? Notes
1663 ---------------------------------------------------------
1664 2296 028970d4 5b6c5cd8 yes
1665 2295 028970d4 5b6c5cd8 yes
1666 2294 028970d4 5b6c5cd8 yes
1667 2293 028970d4 5b6c5cd8 yes
1668 2292 028970d4 5b6c5cd8 yes
1669 2291 028970d4 5b6c5cd8 yes
1670 2290 028970d4 5b6c5cd8 yes
1671 2289 028970d4 5b6c5cd8 yes
1672 2288 028970d4 5b6c5cd8 yes
1673 2287 028970d4 5b6c5cd8 yes
1674 2286 028970d4 5b6c5cd8 yes
1675 2285 028970d4 5b6c5cd8 yes
1676 322 028970e8 5b6c5cd8 yes Duplicate promote/relocs
1682 HistObj <obj_address>
1684 This command examines all stress log relocation records and displays the chain
1685 of GC relocations that may have led to the address passed in as an argument.
1686 Conceptually the output is:
1688 GenN obj_address root1, root2, root3,
1689 GenN-1 prev_obj_addr root1, root2,
1690 GenN-2 prev_prev_oa root1, root4,
1694 (lldb) histobj 028970d4
1695 GCCount Object Roots
1696 ---------------------------------------------------------
1697 2296 028970d4 00223fc4, 01e411b8,
1698 2295 028970d4 00223fc4, 01e411b8,
1699 2294 028970d4 00223fc4, 01e411b8,
1700 2293 028970d4 00223fc4, 01e411b8,
1701 2292 028970d4 00223fc4, 01e411b8,
1702 2291 028970d4 00223fc4, 01e411b8,
1703 2290 028970d4 00223fc4, 01e411b8,
1704 2289 028970d4 00223fc4, 01e411b8,
1705 2288 028970d4 00223fc4, 01e411b8,
1706 2287 028970d4 00223fc4, 01e411b8,
1707 2286 028970d4 00223fc4, 01e411b8,
1708 2285 028970d4 00223fc4, 01e411b8,
1709 322 028970d4 01e411b8,
1717 This command releases any resources used by the Hist-family of commands.
1718 Generally there's no need to call this explicitly, as each HistInit will first
1719 cleanup the previous resources.
1722 Completed successfully.