-
Notifications
You must be signed in to change notification settings - Fork 357
/
sosdocsunix.txt
2007 lines (1641 loc) · 78.1 KB
/
sosdocsunix.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
-------------------------------------------------------------------------------
NOTE: THIS FILE CONTAINS SOS DOCUMENTATION. THE FORMAT OF THE FILE IS:
<optional comments>
COMMAND: <cmd name, all lower case>
<descriptive text of the command>
\\ <these are two backslashes, immediately followed by a newline>
<repeat the sequence above>
The first command is "contents" which is the general help screen. The rest
correspond to SOS command names. This file is embedded as a resource in the SOS
binary. Be sure to list any new commands here.
-------------------------------------------------------------------------------
COMMAND: contents.
SOS is a debugger extension DLL designed to aid in the debugging of managed
programs. Functions are listed by category, then roughly in order of
importance. Shortcut names for popular functions are listed in parenthesis.
Type "soshelp <functionname>" for detailed info on that function.
Object Inspection Examining code and stacks
----------------------------- -----------------------------
DumpObj (dumpobj) Threads (clrthreads)
DumpALC (dumpalc) ThreadState
DumpArray IP2MD (ip2md)
DumpAsync (dumpasync) u (clru)
DumpDelegate (dumpdelegate) DumpStack (dumpstack)
DumpStackObjects (dso) EEStack (eestack)
DumpHeap (dumpheap) ClrStack (clrstack)
DumpVC GCInfo
FinalizeQueue (finalizequeue) EHInfo
GCRoot (gcroot) bpmd (bpmd)
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)
DumpMD (dumpmd)
Token2EE
DumpModule (dumpmodule)
DumpAssembly (dumpassembly)
DumpRuntimeTypes
DumpIL (dumpil)
DumpSig
DumpSigElem
Examining the GC history Other
----------------------------- -----------------------------
HistInit (histinit) SetHostRuntime (sethostruntime)
HistRoot (histroot) SetSymbolServer (setsymbolserver, loadsymbols)
HistObj (histobj) SetClrPath (setclrpath)
HistObjFind (histobjfind) SOSFlush (sosflush)
HistClear (histclear) SOSStatus (sosstatus)
FAQ
Help (soshelp)
\\
COMMAND: faq.
>> I have a chicken and egg problem. I want to use SOS commands, but the CLR
isn't loaded yet. What can I do?
There currently isn't any way to get lldb to stop on libcoreclr.so module load, but
you can now set a breakpoint on Main with "bpmd".
(lldb) bpmd Foo.dll Program.Main
>> I got the following error message. Now what?
(lldb) sos DumpStackObjects
The coreclr module is not loaded yet in the target process
(lldb)
This means that the clr is not loaded yet, or has been unloaded. You need to
wait until your managed program is running in order to use these commands. If
you have just started the program a good way to do this is to type
breakpoint set coreclr`EEStartup
in the debugger, and let it run. After the function EEStartup is finished,
there will be a minimal managed environment for executing SOS commands.
\\
COMMAND: dumpobj.
DumpObj [-nofields] <object address>
This command allows you to examine the fields of an object, as well as learn
important properties of the object such as the EEClass, the MethodTable, and
the size.
You might find an object pointer by running DumpStackObjects and choosing
from the resultant list. Here is a simple object:
(lldb) dumpobj a79d40
Name: Customer
MethodTable: 009038ec
EEClass: 03ee1b84
Size: 20(0x14) bytes
(/home/user/pub/unittest)
Fields:
MT Field Offset Type VT Attr Value Name
009038ec 4000008 4 Customer 0 instance 00a79ce4 name
009038ec 4000009 8 Bank 0 instance 00a79d2c bank
Note that fields of type Customer and Bank are themselves objects, and you can
run DumpObj on them too. You could look at the field directly in memory using
the offset given. "dd a79d40+8 l1" would allow you to look at the bank field
directly. Be careful about using this to set memory breakpoints, since objects
can move around in the garbage collected heap.
What else can you do with an object? You might run GCRoot, to determine what
roots are keeping it alive. Or you can find all objects of that type with
"dumpheap -type Customer".
The column VT contains the value 1 if the field is a valuetype structure, and
0 if the field contains a pointer to another object. For valuetypes, you can
take the MethodTable pointer in the MT column, and the Value and pass them to
the command DumpVC.
The arguments in detail:
-nofields: do not print fields of the object, useful for objects like String
\\
COMMAND: dumparray.
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 -details is used. Do
not print fields of the elements. Useful for arrays of
objects like String
Example output:
(lldb) sos DumpArray -start 2 -length 3 -details 00ad28d0
Name: Value[]
MethodTable: 03e41044
EEClass: 03e40fc0
Size: 132(0x84) bytes
Array: Rank 1, Number of elements 10, Type VALUETYPE
Element Type: Value
[2] 00ad28f0
Name: Value
MethodTable 03e40f4c
EEClass: 03ef1698
Size: 20(0x14) bytes
(/home/user/bugs/225271/arraytest)
Fields:
MT Field Offset Type Attr Value Name
5b9a628c 4000001 0 System.Int32 instance 2 x
5b9a628c 4000002 4 System.Int32 instance 4 y
5b9a628c 4000003 8 System.Int32 instance 6 z
[3] 00ad28fc
Name: Value
MethodTable 03e40f4c
EEClass: 03ef1698
Size: 20(0x14) bytes
(/home/user/bugs/225271/arraytest)
Fields:
MT Field Offset Type Attr Value Name
5b9a628c 4000001 0 System.Int32 instance 3 x
5b9a628c 4000002 4 System.Int32 instance 6 y
5b9a628c 4000003 8 System.Int32 instance 9 z
[4] 00ad2908
Name: Value
MethodTable 03e40f4c
EEClass: 03ef1698
Size: 20(0x14) bytes
(/home/user/bugs/225271/arraytest.exe)
Fields:
MT Field Offset Type Attr Value Name
5b9a628c 4000001 0 System.Int32 instance 4 x
5b9a628c 4000002 4 System.Int32 instance 8 y
5b9a628c 4000003 8 System.Int32 instance 12 z
\\
COMMAND: dumpalc.
DumpALC
<object address>
This command allows you to dump the AssemblyLoadContext into which the type of the
specified object was loaded.
Example output:
(lldb) dumpalc 000001c2800101a0
Name: Host.HostAssemblyLoadContext
MethodTable: 00007ff7c9cb1428
EEClass: 00007ff7c9ca4b40
Size: 88(0x58) bytes
File: /home/user/test/host.dll
Fields:
MT Field Offset Type VT Attr Value Name
00007ff7c9920eb8 4000ea3 8 System.Object 0 instance 000001c28000cff0 _unloadLock
0000000000000000 4000ea4 10 0 instance 0000000000000000 _resolvingUnmanagedDll
0000000000000000 4000ea5 18 0 instance 0000000000000000 _resolving
00007ff7c9d36850 4000ea6 20 ...Private.CoreLib]] 0 instance 000001c2800101b8 _unloading
00007ff7c9a74748 4000ea7 28 System.String 0 instance 0000000000000000 _name
00007ff7c9a427f0 4000ea8 30 System.IntPtr 1 instance 000001C2FA21DD50 _nativeAssemblyLoadContext
00007ff7c9a1c7e0 4000ea9 38 System.Int64 1 instance 0 _id
00007ff7c9ac57b8 4000eaa 40 System.Int32 1 instance 0 _state
00007ff7c9a107b8 4000eab 44 System.Boolean 1 instance 1 _isCollectible
00007ff7c9cb4070 4000ea1 b08 ...Private.CoreLib]] 0 static 000001c28000d090 s_allContexts
00007ff7c9a1c7e0 4000ea2 970 System.Int64 1 static 1 s_nextId
0000000000000000 4000eac b10 ...yLoadEventHandler 0 static 0000000000000000 AssemblyLoad
0000000000000000 4000ead b18 ...solveEventHandler 0 static 0000000000000000 TypeResolve
0000000000000000 4000eae b20 ...solveEventHandler 0 static 0000000000000000 ResourceResolve
0000000000000000 4000eaf b28 ...solveEventHandler 0 static 0000000000000000 AssemblyResolve
0000000000000000 4000eb0 b30 0 static 0000000000000000 s_asyncLocalCurrent
00007ff7c9cb26d0 4000001 48 ...ependencyResolver 0 instance 000001c28000d1c0 _resolver
\\
COMMAND: dumpasync.
DumpAsync [-addr <Object Address>]
[-mt <MethodTable address>]
[-type <partial type name>]
[-tasks]
[-completed]
[-fields]
[-stacks]
[-roots]
DumpAsync traverses the garbage collected heap, looking for objects representing
async state machines as created when an async method's state is transferred to the
heap. This command recognizes async state machines defined as "async void", "async Task",
"async Task<T>", "async ValueTask", and "async ValueTask<T>". It also optionally supports
any other tasks.
\\
COMMAND: dso.
COMMAND: dumpstackobjects.
DumpStackObjects [-verify] [top stack [bottom stack]]
This command will display any managed objects it finds within the bounds of
the current stack. Combined with the stack tracing commands like K and
ClrStack, it is a good aid to determining the values of locals and
parameters.
If you use the -verify option, each non-static CLASS field of an object
candidate is validated. This helps to eliminate false positives. It is not
on by default because very often in a debugging scenario, you are
interested in objects with invalid fields.
The abbreviation dso can be used for brevity.
\\
COMMAND: dumpdelegate.
DumpDelegate <delegate address>
DumpDelegate finds and outputs the one or more method descriptors associated with a delegate object.
For example:
(lldb) dumpdelegate
Target Method Name
000001461bacb0d8 00007ffc5c894b80 ConsoleApp16.Program.InstanceMethod()
000001461bacb098 00007ffc5c894b68 ConsoleApp16.Program.StaticMethod()
\\
COMMAND: dumpheap.
DumpHeap [-stat]
[-strings]
[-short]
[-min <size>]
[-max <size>]
[-live]
[-dead]
[-thinlock]
[-startAtLowerBound]
[-mt <MethodTable address>]
[-type <partial type name>]
[start [end]]
DumpHeap is a powerful command that traverses the garbage collected heap,
collection statistics about objects. With it's various options, it can look for
particular types, restrict to a range, or look for ThinLocks (see syncblk
documentation). Finally, it will provide a warning if it detects excessive
fragmentation in the GC heap.
When called without options, the output is first a list of objects in the heap,
followed by a report listing all the types found, their size and number:
(lldb) dumpheap
Address MT Size
00a71000 0015cde8 12 Free
00a7100c 0015cde8 12 Free
00a71018 0015cde8 12 Free
00a71024 5ba58328 68
00a71068 5ba58380 68
00a710ac 5ba58430 68
00a710f0 5ba5dba4 68
...
total 619 objects
Statistics:
MT Count TotalSize Class Name
5ba7607c 1 12 System.Security.Permissions.HostProtectionResource
5ba75d54 1 12 System.Security.Permissions.SecurityPermissionFlag
5ba61f18 1 12 System.Collections.CaseInsensitiveComparer
...
0015cde8 6 10260 Free
5ba57bf8 318 18136 System.String
...
"Free" objects are simply regions of space the garbage collector can use later.
If 30% or more of the heap contains "Free" objects, the process may suffer from
heap fragmentation. This is usually caused by pinning objects for a long time
combined with a high rate of allocation. Here is example output where DumpHeap
provides a warning about fragmentation:
<After the Statistics section>
Fragmented blocks larger than 1MB:
Addr Size Followed by
00a780c0 1.5MB 00bec800 System.Byte[]
00da4e38 1.2MB 00ed2c00 System.Byte[]
00f16df0 1.2MB 01044338 System.Byte[]
The arguments in detail:
-stat Restrict the output to the statistical type summary
-strings Restrict the output to a statistical string value summary
-short Limits output to just the address of each object. This allows you
to easily pipe output from the command to another debugger
command for automation.
-min Ignore objects less than the size given in bytes
-max Ignore objects larger than the size given in bytes
-live Only print live objects
-dead Only print dead objects (objects which will be collected in the
next full GC)
-thinlock Report on any ThinLocks (an efficient locking scheme, see syncblk
documentation for more info)
-startAtLowerBound
Force heap walk to begin at lower bound of a supplied address range.
(During plan phase, the heap is often not walkable because objects
are being moved. In this case, DumpHeap may report spurious errors,
in particular bad objects. It may be possible to traverse more of
the heap after the reported bad object. Even if you specify an
address range, DumpHeap will start its walk from the beginning of
the heap by default. If it finds a bad object before the specified
range, it will stop before displaying the part of the heap in which
you are interested. This switch will force DumpHeap to begin its
walk at the specified lower bound. You must supply the address of a
good object as the lower bound for this to work. Display memory at
the address of the bad object to manually find the next method
table (use DumpMT to verify). If the GC is currently in a call to
memcopy, You may also be able to find the next object's address by
adding the size to the start address given as parameters.)
-mt List only those objects with the MethodTable given
-type List only those objects whose type name is a substring match of the
string provided.
start Begin listing from this address
end Stop listing at this address
A special note about -type: Often, you'd like to find not only Strings, but
System.Object arrays that are constrained to contain Strings. ("new
String[100]" actually creates a System.Object array, but it can only hold
System.String object pointers). You can use -type in a special way to find
these arrays. Just pass "-type System.String[]" and those Object arrays will
be returned. More generally, "-type <Substring of interesting type>[]".
The start/end parameters can be obtained from the output of eeheap -gc. For
example, if you only want to list objects in the large heap segment:
(lldb) eeheap -gc
Number of GC Heaps: 1
generation 0 starts at 0x00c32754
generation 1 starts at 0x00c32748
generation 2 starts at 0x00a71000
segment begin allocated size
00a70000 00a71000 010443a8 005d33a8(6108072)
Large object heap starts at 0x01a71000
segment begin allocated size
01a70000 01a71000 01a75000 0x00004000(16384)
Total Size 0x5d73a8(6124456)
------------------------------
GC Heap Size 0x5d73a8(6124456)
(lldb) dumpheap 1a71000 1a75000
Address MT Size
01a71000 5ba88bd8 2064
01a71810 0019fe48 2032 Free
01a72000 5ba88bd8 4096
01a73000 0019fe48 4096 Free
01a74000 5ba88bd8 4096
total 5 objects
Statistics:
MT Count TotalSize Class Name
0019fe48 2 6128 Free
5ba88bd8 3 10256 System.Object[]
Total 5 objects
Finally, if GC heap corruption is present, you may see an error like this:
(lldb) dumpheap -stat
object 00a73d24: does not have valid MT
curr_object : 00a73d24
Last good object: 00a73d14
----------------
That indicates a serious problem. See the help for VerifyHeap for more
information on diagnosing the cause.
\\
COMMAND: dumpvc.
DumpVC <MethodTable address> <Address>
DumpVC allows you to examine the fields of a value class. In C#, this is a
struct, and lives on the stack or within an Object on the GC heap. You need
to know the MethodTable address to tell SOS how to interpret the fields, as
a value class is not a first-class object with it's own MethodTable as the
first field. For example:
(lldb) sos DumpObj a79d98
Name: Mainy
MethodTable: 009032d8
EEClass: 03ee1424
Size: 28(0x1c) bytes
(/home/user/pub/unittest)
Fields:
MT Field Offset Type Attr Value Name
0090320c 4000010 4 VALUETYPE instance 00a79d9c m_valuetype
009032d8 400000f 4 CLASS static 00a79d54 m_sExcep
m_valuetype is a value type. The value in the MT column (0090320c) is the
MethodTable for it, and the Value column provides the start address:
(lldb) sos DumpVC 0090320c 00a79d9c
Name: Funny
MethodTable 0090320c
EEClass: 03ee14b8
Size: 28(0x1c) bytes
(/home/user/pub/unittest)
Fields:
MT Field Offset Type Attr Value Name
0090320c 4000001 0 CLASS instance 00a743d8 signature
0090320c 4000002 8 System.Int32 instance 2345 m1
0090320c 4000003 10 System.Boolean instance 1 b1
0090320c 4000004 c System.Int32 instance 1234 m2
0090320c 4000005 4 CLASS instance 00a79d98 backpointer
DumpVC is quite a specialized function. Some managed programs make heavy use
of value classes, while others do not.
\\
COMMAND: finalizequeue
FinalizeQueue [-detail] | [-allReady] [-short]
Displays all objects registered for finalization.
The "-detail" option displays extra information about any SyncBlocks that need
to be cleaned up. This data structure is cached and cleaned up by the
finalizer thread when it runs.
The "-allReady" option displays all objects that are ready for finalization,
regardless of whether they are already marked by the garbage collection
as such, or will be marked by the next garbage collection. The objects that
are in the "ready for finalization" list are finalizable objects that are
no longer rooted. This option can be very expensive, because it verifies
whether all the objects in the finalizable queues are still rooted.
The "-short" option limits the output to the address of each object. If it is
used in conjunction with -allReady, it enumerates all objects that have
a finalizer that are no longer rooted. If it is used independently, it lists
all objects in the finalizable and "ready for finalization" queues.
\\
COMMAND: gcroot.
GCRoot [-nostacks] [-all] <Object address>
GCRoot looks for references (or roots) to an object. These can exist in four
places:
1. On the stack
2. Within a GC Handle
3. In an object ready for finalization
4. As a member of an object found in 1, 2 or 3 above.
First, all stacks will be searched for roots, then handle tables, and finally
the reachable queue of the finalizer. Some caution about the stack roots:
GCRoot doesn't attempt to determine if a stack root it encountered is valid
or is old (discarded) data. You would have to use ClrStack and U to
disassemble the frame that the local or argument value belongs to in order to
determine if it is still in use.
Because people often want to restrict the search to gc handles and reachable
objects, there is a -nostacks option.
The -all option forces all roots to be displayed instead of just the unique roots.
\\
COMMAND: pe.
COMMAND: printexception.
PrintException [-nested] [-lines] [-ccw] [<Exception object address>] [<CCW pointer>]
This will format fields of any object derived from System.Exception. One of the
more useful aspects is that it will format the _stackTrace field, which is a
binary array. If _stackTraceString field is not filled in, that can be helpful
for debugging. You can of course use DumpObj on the same exception object to
explore more fields.
If called with no parameters, PrintException will look for the last outstanding
exception on the current thread and print it. This will be the same exception
that shows up in a run of clrthreads.
PrintException will notify you if there are any nested exceptions on the
current managed thread. (A nested exception occurs when you throw another
exception within a catch handler already being called for another exception).
If there are nested exceptions, you can re-run PrintException with the
"-nested" option to get full details on the nested exception objects. The
clrthreads command will also tell you which threads have nested exceptions.
PrintException can display source information if available, by specifying the
-lines command line argument.
PrintException prints the exception object corresponding to a given CCW pointer,
which can be specified using the -ccw option.
The abbreviation 'pe' can be used for brevity.
\\
COMMAND: threadstate.
ThreadState value
The clrthreads command outputs, among other things, the state of the thread.
This is a bit field which corresponds to various states the thread is in.
To check the state of the thread, simply pass that bit field from the
output of clrthreads into ThreadState.
Example:
(lldb) clrthreads
ThreadCount: 2
UnstartedThread: 0
BackgroundThread: 1
PendingThread: 0
DeadThread: 0
Hosted Runtime: no
PreEmptive GC Alloc Lock
ID OSID ThreadOBJ State GC Context Domain Count APT Exception
0 1 250 0019b068 a020 Disabled 02349668:02349fe8 0015def0 0 MTA
2 2 944 001a6020 b220 Enabled 00000000:00000000 0015def0 0 MTA (Finalizer)
0:003> sos ThreadState b220
Legal to Join
Background
CLR Owns
CoInitialized
In Multi Threaded Apartment
Possible thread states:
Thread Abort Requested
GC Suspend Pending
User Suspend Pending
Debug Suspend Pending
GC On Transitions
Legal to Join
Yield Requested
Hijacked by the GC
Blocking GC for Stack Overflow
Background
Unstarted
Dead
CLR Owns
CoInitialized
In Single Threaded Apartment
In Multi Threaded Apartment
Reported Dead
Fully initialized
Task Reset
Sync Suspended
Debug Will Sync
Stack Crawl Needed
Suspend Unstarted
Aborted
Thread Pool Worker Thread
Interruptible
Interrupted
Completion Port Thread
Abort Initiated
Finalized
Failed to Start
Detached
\\
COMMAND: threads.
COMMAND: clrthreads.
Threads [-live] [-special]
Threads (clrthreads) lists all the mananaged threads in the process.
-live: optional. Only print threads associated with a live thread.
-special: optional. With this switch, the command will display all the special
threads created by CLR. Those threads might not be managed threads
so they might not be shown in the first part of the command's
output. Example of special threads include: GC threads (in
concurrent GC and server GC), Debugger helper threads, Finalizer
threads, AppDomain Unload threads, and Threadpool timer threads.
-managedexception: optional. Sets the current thread to first thread with
an managed exception for the "printexception" command.
Each thread has many attributes, many of which can be ignored. The important
ones are discussed below:
There are three ID columns:
1) The debugger shorthand ID (When the runtime is hosted this column might
display the special string "<<<<" when this internal thread object is not
associated with any physical thread - this may happen when the host reuses
the runtime internal thread object)
2) The CLR Thread ID
3) The OS thread ID.
If PreEmptiveGC is enabled for a thread, then a garbage collection
can occur while that thread is running. For example, if you break in while
a managed thread is making a PInvoke call to a Win32 function, that thread
will be in PreEmptive GC mode.
The Domain column indicates what AppDomain the thread is currently executing
in. You can pass this value to DumpDomain to find out more.
The APT column gives the COM apartment mode.
Exception will list the last thrown exception (if any) for the thread. More
details can be obtained by passing the pointer value to PrintException. If
you get the notation "(nested exceptions)", you can get details on those
exceptions by switching to the thread in question, and running
"PrintException -nested".
\\
COMMAND: clrstack.
ClrStack [-a] [-l] [-p] [-n] [-f] [-r] [-all]
ClrStack [-a] [-l] [-p] [-i] [variable name] [frame]
ClrStack attempts to provide a true stack trace for managed code only. It is
handy for clean, simple traces when debugging straightforward managed
programs. The -p parameter will show arguments to the managed function. The
-l parameter can be used to show information on local variables in a frame.
SOS can't retrieve local names at this time, so the output for locals is in
the format <local address> = <value>. The -a (all) parameter is a short-cut
for -l and -p combined.
The -f option (full mode) displays the native frames intermixing them with
the managed frames and the assembly name and function offset for the managed
frames.
The -r option dumps the registers for each stack frame.
The -all option dumps all the managed threads' stacks.
If the debugger has the option SYMOPT_LOAD_LINES specified (either by the
.lines or .symopt commands), SOS will look up the symbols for every managed
frame and if successful will display the corresponding source file name and
line number. The -n (No line numbers) parameter can be specified to disable
this behavior.
When you see methods with the name "[Frame:...", that indicates a transition
between managed and unmanaged code. You could run IP2MD on the return
addresses in the call stack to get more information on each managed method.
On x64 platforms, Transition Frames are not displayed at this time. To avoid
heavy optimization of parameters and locals one can request the JIT compiler
to not optimize functions in the managed app by creating a file myapp.ini
(if your program is myapp.exe) in the same directory. Put the following lines
in myapp.ini and re-run:
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
The -i option is a new EXPERIMENTAL addition to ClrStack and will use the ICorDebug
interfaces to display the managed stack and variables. With this option you can also
view and expand arrays and fields for managed variables. If a stack frame number is
specified in the command line, ClrStack will show you the parameters and/or locals
only for that frame (provided you specify -l or -p or -a of course). If a variable
name and a stack frame number are specified in the command line, ClrStack will show
you the parameters and/or locals for that frame, and will also show you the fields
for that variable name you specified. Here are some examples:
clrstack -i -a : This will show you all parameters and locals for all frames
clrstack -i -a 3 : This will show you all parameters and locals, for frame 3
clrstack -i var1 0 : This will show you the fields of 'var1' for frame 0
clrstack -i var1.abc 2 : This will show you the fields of 'var1', and expand
'var1.abc' to show you the fields of the 'abc' field,
for frame 2.
clrstack -i var1.[basetype] 0 : This will show you the fields of 'var1', and
expand the base type of 'var1' to show you its
fields.
clrstack -i var1.[6] 0 : If 'var1' is an array, this will show you the element
at index 6 in the array, along with its fields
The -i options uses DML output for a better debugging experience, so typically you
should only need to execute "clrstack -i", and from there, click on the DML
hyperlinks to inspect the different managed stack frames and managed variables.
\\
COMMAND: createdump.
Currently not implemented.
\\
COMMAND: ip2md.
IP2MD <Code address>
Given an address in managed JITTED code, IP2MD attempts to find the MethodDesc
associated with it. For example, this output from K:
(lldb) bt
...
frame #9: 0x00007fffffffbf60 0x00007ffff61c6d89 libcoreclr.so`MethodDesc::DoPrestub(this=0x00007ffff041f870, pDispatchingMT=0x0000000000000000) + 3001 at prestub.cpp:1490
frame #10: 0x00007fffffffc140 0x00007ffff61c5f17 libcoreclr.so`::PreStubWorker(pTransitionBlock=0x00007fffffffc9a8, pMD=0x00007ffff041f870) + 1399 at prestub.cpp:1037
frame #11: 0x00007fffffffc920 0x00007ffff5f5238c libcoreclr.so`ThePreStub + 92 at theprestubamd64.S:800
frame #12: 0x00007fffffffca10 0x00007ffff04981cc
frame #13: 0x00007fffffffca30 0x00007ffff049773c
frame #14: 0x00007fffffffca80 0x00007ffff04975ad
...
frame #22: 0x00007fffffffcc90 0x00007ffff5f51a0f libcoreclr.so`CallDescrWorkerInternal + 124 at calldescrworkeramd64.S:863
frame #23: 0x00007fffffffccb0 0x00007ffff5d6d6dc libcoreclr.so`CallDescrWorkerWithHandler(pCallDescrData=0x00007fffffffce80, fCriticalCall=0) + 476 at callhelpers.cpp:88
frame #24: 0x00007fffffffcd00 0x00007ffff5d6eb38 libcoreclr.so`MethodDescCallSite::CallTargetWorker(this=0x00007fffffffd0c8, pArguments=0x00007fffffffd048) + 2504 at callhelpers.cpp:633
(lldb) ip2md 0x00007ffff049773c
MethodDesc: 00007ffff7f71920
Method Name: Microsoft.Win32.SafeHandles.SafeFileHandle.Open(System.Func`1<Int32>)
Class: 00007ffff0494bf8
MethodTable: 00007ffff7f71a58
mdToken: 0000000006000008
Module: 00007ffff7f6b938
IsJitted: yes
CodeAddr: 00007ffff04976c0
We have taken a return address into Mainy.Main, and discovered information
about that method. You could run U, DumpMT, DumpClass, DumpMD, or
DumpModule on the fields listed to learn more.
The "Source line" output will only be present if the debugger can find the
symbols for the managed module containing the given <code address>, and if the
debugger is configured to load line number information.
\\
COMMAND: clru.
COMMAND: u.
U [-gcinfo] [-ehinfo] [-n] [-o] <MethodDesc address> | <Code address>
Presents an annotated disassembly of a managed method when given a MethodDesc
pointer for the method, or a code address within the method body. Unlike the
debugger "U" function, the entire method from start to finish is printed,
with annotations that convert metadata tokens to names.
<example output>
...
03ef015d b901000000 mov ecx,0x1
03ef0162 ff156477a25b call dword ptr [mscorlib_dll+0x3c7764 (5ba27764)] (System.Console.InitializeStdOutError(Boolean), mdToken: 06000713)
03ef0168 a17c20a701 mov eax,[01a7207c] (Object: SyncTextWriter)
03ef016d 89442414 mov [esp+0x14],eax
If you pass the -gcinfo flag, you'll get inline display of the GCInfo for
the method. You can also obtain this information with the GCInfo command.
If you pass the -ehinfo flag, you'll get inline display of exception info
for the method. (Beginning and end of try/finally/catch handlers, etc.).
You can also obtain this information with the EHInfo command.
If you pass the -o flag, the byte offset of each instruction from the
beginning of the method will be printed in addition to the absolute address of
the instruction.
If the debugger has the option SYMOPT_LOAD_LINES specified (either by the
.lines or .symopt commands), and if symbols are available for the managed
module containing the method being examined, the output of the command will
include the source file name and line number corresponding to the
disassembly. The -n (No line numbers) flag can be specified to disable this
behavior.
<example output>
...
c:\Code\prj.mini\exc.cs @ 38:
001b00b0 8b0d3020ab03 mov ecx,dword ptr ds:[3AB2030h] ("Break in debugger. When done type <Enter> to continue: ")
001b00b6 e8d5355951 call mscorlib_ni+0x8b3690 (51743690) (System.Console.Write(System.String), mdToken: 0600091b)
001b00bb 90 nop
c:\Code\prj.mini\exc.cs @ 39:
001b00bc e863cdc651 call mscorlib_ni+0xf8ce24 (51e1ce24) (System.Console.ReadLine(), mdToken: 060008f6)
>>> 001b00c1 90 nop
...
\\
COMMAND: dumpstack.
DumpStack [-EE] [-n] [top stack [bottom stack]]
[x86 and x64 documentation]
This command provides a verbose stack trace obtained by "scraping." Therefore
the output is very noisy and potentially confusing. The command is good for
viewing the complete call stack when "kb" gets confused. For best results,
make sure you have valid symbols.
-EE will only show managed functions.
If the debugger has the option SYMOPT_LOAD_LINES specified (either by the
.lines or .symopt commands), SOS will look up the symbols for every managed
frame and if successful will display the corresponding source file name and
line number. The -n (No line numbers) parameter can be specified to disable
this behavior.
You can also pass a stack range to limit the output.
\\
COMMAND: eestack.
EEStack [-short] [-EE]
This command runs DumpStack on all threads in the process. The -EE option is
passed directly to DumpStack. The -short option tries to narrow down the
output to "interesting" threads only, which is defined by
1) The thread has taken a lock.
2) The thread has been "hijacked" in order to allow a garbage collection.
3) The thread is currently in managed code.
See the documentation for DumpStack for more info.
\\
COMMAND: ehinfo.
EHInfo (<MethodDesc address> | <Code address>)
EHInfo shows the exception handling blocks in a jitted method. For each
handler, it shows the type, including code addresses and offsets for the clause
block and the handler block. For a TYPED handler, this would be the "try" and
"catch" blocks respectively.
Sample output:
(lldb) sos EHInfo 33bbd3a
MethodDesc: 03310f68
Method Name: MainClass.Main()
Class: 03571358
MethodTable: 0331121c
mdToken: 0600000b
Module: 001e2fd8
IsJitted: yes
CodeAddr: 033bbca0
EHHandler 0: TYPED catch(System.IO.FileNotFoundException)
Clause: [033bbd2b, 033bbd3c] [8b, 9c]
Handler: [033bbd3c, 033bbd50] [9c, b0]
EHHandler 1: FINALLY
Clause: [033bbd83, 033bbda3] [e3, 103]
Handler: [033bbda3, 033bbdc5] [103, 125]
EHHandler 2: TYPED catch(System.Exception)
Clause: [033bbd7a, 033bbdc5] [da, 125]
Handler: [033bbdc5, 033bbdd6] [125, 136]
\\
COMMAND: gcinfo.
GCInfo (<MethodDesc address> | <Code address>)
GCInfo is especially useful for CLR Devs who are trying to determine if there
is a bug in the JIT Compiler. It parses the GCEncoding for a method, which is a
compressed stream of data indicating when registers or stack locations contain
managed objects. It is important to keep track of this information, because if
a garbage collection occurs, the collector needs to know where roots are so it
can update them with new object pointer values.
Here is sample output where you can see the change in register state. Normally
you would print this output out and read it alongside a disassembly of the
method. For example, the notation "reg EDI becoming live" at offset 0x11 of the
method might correspond to a "mov edi,ecx" statement.
(lldb) sos GCInfo 5b68dbb8 (5b68dbb8 is the start of a JITTED method)
entry point 5b68dbb8
preJIT generated code
GC info 5b9f2f09
Method info block:
method size = 0036
prolog size = 19
epilog size = 8
epilog count = 1
epilog end = yes
saved reg. mask = 000B
ebp frame = yes
fully interruptible=yes
double align = no
security check = no
exception handlers = no
local alloc = no
edit & continue = no
varargs = no
argument count = 4
stack frame size = 1
untracked count = 5
var ptr tab count = 0
epilog at 002E
36 D4 8C C7 AA |
93 F3 40 05 |
Pointer table:
14 | [EBP+14H] an untracked local
10 | [EBP+10H] an untracked local
0C | [EBP+0CH] an untracked local
08 | [EBP+08H] an untracked local
44 | [EBP-04H] an untracked local
F1 79 | 0011 reg EDI becoming live
72 | 0013 reg ESI becoming live
83 | 0016 push ptr 0
8B | 0019 push ptr 1
93 | 001C push ptr 2
9B | 001F push ptr 3
56 | 0025 reg EDX becoming live
4A | 0027 reg ECX becoming live
0E | 002D reg ECX becoming dead
10 | 002D reg EDX becoming dead
E0 | 002D pop 4 ptrs
F0 31 | 0036 reg ESI becoming dead
38 | 0036 reg EDI becoming dead
FF |
This function is important for CLR Devs, but very difficult for anyone else to
make sense of it. You would usually come to use it if you suspect a gc heap
corruption bug caused by invalid GCEncoding for a particular method.
\\
COMMAND: bpmd.
bpmd [-nofuturemodule] <module name> <method name> [<il offset>]
bpmd <source file name>:<line number>
bpmd -md <MethodDesc>
bpmd -list
bpmd -clear <pending breakpoint number>
bpmd -clearall
bpmd provides managed breakpoint support. If it can resolve the method name
to a loaded, jitted or ngen'd function it will create a breakpoint with "bp".
If not then either the module that contains the method hasn't been loaded yet
or the module is loaded, but the function is not jitted yet. In these cases,
bpmd asks the Debugger to receive CLR Notifications, and waits to receive news
of module loads and JITs, at which time it will try to resolve the function to
a breakpoint. -nofuturemodule can be used to suppress creating a breakpoint
against a module that has not yet been loaded.
Management of the list of pending breakpoints can be done via bpmd -list,
bpmd -clear, and bpmd -clearall commands. bpmd -list generates a list of
all of the pending breakpoints. If the pending breakpoint has a non-zero
module id, then that pending breakpoint is specific to function in that
particular loaded module. If the pending breakpoint has a zero module id, then
the breakpoint applies to modules that have not yet been loaded. Use
bpmd -clear or bpmd -clearall to remove pending breakpoints from the list.
The bpmd command can now be used before the runtime is loaded. You can execute
bpmd right after the SOS plug-in is loaded. Always add the module extension for
the module name parameter.
This brings up a good question: "I want to set a breakpoint on the main
method of my application. How can I do this?"
1) Add the breakpoint with command such as:
bpmd myapp.dll MyApp.Main
2) g
3) You will stop at the start of MyApp.Main. If you type "bl" you will
see the breakpoint listed.
To correctly specify explicitly implemented methods make sure to retrieve the
method name from the metadata, or from the output of the "dumpmt -md" command.
For example:
public interface I1
{
void M1();
}
public class ExplicitItfImpl : I1
{
...
void I1.M1() // this method's name is 'I1.M1'
{ ... }
}
bpmd myapp.dll ExplicitItfImpl.I1.M1
bpmd works equally well with generic types. Adding a breakpoint on a generic
type sets breakpoints on all already JIT-ted generic methods and sets a pending
breakpoint for any instantiation that will be JIT-ted in the future.
Example for generics:
Given the following two classes:
class G3<T1, T2, T3>
{
...