@@ -459,7 +459,7 @@ bool ShouldIncludeStack(AsyncObject obj)
459459 // <summary>Outputs a line of information for each instance field on the object.</summary>
460460 void RenderFields ( IAddressableTypedEntity ? obj , int depth )
461461 {
462- if ( obj is not null )
462+ if ( obj ? . Type is not null )
463463 {
464464 string depthTab = new string ( ' ' , depth * TabWidth ) ;
465465
@@ -489,33 +489,36 @@ void RenderFields(IAddressableTypedEntity? obj, int depth)
489489 // <summary>Gets a printable description for the specified object.</summary>
490490 string Describe ( ClrObject obj )
491491 {
492- // Default the description to the type name.
493- string description = obj . Type . Name ;
494-
495- if ( IsStateMachineBox ( obj . Type ) )
492+ string description = string . Empty ;
493+ if ( obj . Type ? . Name is not null )
496494 {
497- // Remove the boilerplate box type from the name.
498- int pos = description . IndexOf ( "StateMachineBox<" , StringComparison . Ordinal ) ;
499- if ( pos >= 0 )
495+ // Default the description to the type name.
496+ description = obj . Type . Name ;
497+
498+ if ( IsStateMachineBox ( obj . Type ) )
500499 {
501- ReadOnlySpan < char > slice = description . AsSpan ( pos + "StateMachineBox<" . Length ) ;
502- slice = slice . Slice ( 0 , slice . Length - 1 ) ; // remove trailing >
503- description = slice . ToString ( ) ;
500+ // Remove the boilerplate box type from the name.
501+ int pos = description . IndexOf ( "StateMachineBox<" , StringComparison . Ordinal ) ;
502+ if ( pos >= 0 )
503+ {
504+ ReadOnlySpan < char > slice = description . AsSpan ( pos + "StateMachineBox<" . Length ) ;
505+ slice = slice . Slice ( 0 , slice . Length - 1 ) ; // remove trailing >
506+ description = slice . ToString ( ) ;
507+ }
504508 }
505- }
506- else if ( TryGetValidObjectField ( obj , "m_action" , out ClrObject taskDelegate ) )
507- {
508- // If we can figure out what the task's delegate points to, append the method signature.
509- if ( TryGetMethodFromDelegate ( runtime , taskDelegate , out ClrMethod ? method ) )
509+ else if ( TryGetValidObjectField ( obj , "m_action" , out ClrObject taskDelegate ) )
510+ {
511+ // If we can figure out what the task's delegate points to, append the method signature.
512+ if ( TryGetMethodFromDelegate ( runtime , taskDelegate , out ClrMethod ? method ) )
513+ {
514+ description = $ "{ description } {{{method!.Signature}}}";
515+ }
516+ }
517+ else if ( obj . Address != 0 && taskCompletionSentinel . Address == obj . Address )
510518 {
511- description = $ " { description } {{{method!.Signature}}} ";
519+ description = "TaskCompletionSentinel ";
512520 }
513521 }
514- else if ( obj . Address != 0 && taskCompletionSentinel . Address == obj . Address )
515- {
516- description = "TaskCompletionSentinel" ;
517- }
518-
519522 return description ;
520523 }
521524
@@ -527,14 +530,17 @@ bool IncludeInOutput(ClrObject obj)
527530 return false ;
528531 }
529532
530- if ( MethodTableAddress is ulong mt && obj . Type . MethodTable != mt )
533+ if ( obj . Type is not null )
531534 {
532- return false ;
533- }
535+ if ( MethodTableAddress is ulong mt && obj . Type . MethodTable != mt )
536+ {
537+ return false ;
538+ }
534539
535- if ( NameSubstring is not null && ! obj . Type . Name . Contains ( NameSubstring ) )
536- {
537- return false ;
540+ if ( NameSubstring is not null && obj . Type . Name is not null && ! obj . Type . Name . Contains ( NameSubstring ) )
541+ {
542+ return false ;
543+ }
538544 }
539545
540546 return true ;
@@ -655,37 +661,42 @@ Dictionary<ClrObject, AsyncObject> CollectObjects()
655661 // </remarks>
656662 void AddContinuation ( ClrObject continuation , List < ClrObject > continuations )
657663 {
658- if ( continuation . Type . Name . StartsWith ( "System.Collections.Generic.List<" , StringComparison . Ordinal ) )
664+ if ( continuation . Type is not null )
659665 {
660- if ( continuation . Type . GetFieldByName ( "_items" ) is ClrInstanceField itemsField )
666+ if ( continuation . Type . Name is not null &&
667+ continuation . Type . Name . StartsWith ( "System.Collections.Generic.List<" , StringComparison . Ordinal ) )
661668 {
662- ClrObject itemsObj = itemsField . ReadObject ( continuation . Address , interior : false ) ;
663- if ( ! itemsObj . IsNull )
669+ if ( continuation . Type . GetFieldByName ( "_items" ) is ClrInstanceField itemsField )
664670 {
665- ClrArray items = itemsObj . AsArray ( ) ;
666- if ( items . Rank == 1 )
671+ ClrObject itemsObj = itemsField . ReadObject ( continuation . Address , interior : false ) ;
672+ if ( ! itemsObj . IsNull )
667673 {
668- for ( int i = 0 ; i < items . Length ; i ++ )
674+ ClrArray items = itemsObj . AsArray ( ) ;
675+ if ( items . Rank == 1 )
669676 {
670- if ( items . GetObjectValue ( i ) is ClrObject { IsValid : true } c )
677+ for ( int i = 0 ; i < items . Length ; i ++ )
671678 {
672- continuations . Add ( ResolveContinuation ( c ) ) ;
679+ if ( items . GetObjectValue ( i ) is ClrObject { IsValid : true } c )
680+ {
681+ continuations . Add ( ResolveContinuation ( c ) ) ;
682+ }
673683 }
674684 }
675685 }
676686 }
677687 }
678- }
679- else
680- {
681- continuations . Add ( continuation ) ;
688+ else
689+ {
690+ continuations . Add ( continuation ) ;
691+ }
682692 }
683693 }
684694
685695 // <summary>Tries to get the object contents of a Task's continuations field</summary>
686696 bool TryGetContinuation ( ClrObject obj , out ClrObject continuation )
687697 {
688- if ( obj . Type . GetFieldByName ( "m_continuationObject" ) is ClrInstanceField continuationObjectField &&
698+ if ( obj . Type is not null &&
699+ obj . Type . GetFieldByName ( "m_continuationObject" ) is ClrInstanceField continuationObjectField &&
689700 continuationObjectField . ReadObject ( obj . Address , interior : false ) is ClrObject { IsValid : true } continuationObject )
690701 {
691702 continuation = ResolveContinuation ( continuationObject ) ;
@@ -888,7 +899,7 @@ private void WriteCodeLink(ulong address)
888899 }
889900
890901 /// <summary>Gets whether the specified type is an AsyncStateMachineBox{T}.</summary>
891- private static bool IsStateMachineBox ( ClrType type )
902+ private static bool IsStateMachineBox ( ClrType ? type )
892903 {
893904 // Ideally we would compare the metadata token and module for the generic template for the type,
894905 // but that information isn't fully available via ClrMd, nor can it currently find DebugFinalizableAsyncStateMachineBox
0 commit comments