Skip to content

Unable to run !ClrStack -a because of duplicite stack frames #67

Description

@stej

I'm running !ClrStack -a and I get this error message for some threads

Exception during command execution -- InvalidOperationException: 'Sequence contains more than one matching element'
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at msos.ClrThreadExtensions.FrameArgumentsAndLocalsRetriever.ProcessFrame(IXCLRDataStackWalk stackWalk) in C:\dev\github\msos\msos\ClrThreadExtensions.cs:line 288
   at msos.ClrThreadExtensions.FrameArgumentsAndLocalsRetriever.ProcessStackWalk(UInt32 osThreadId) in C:\dev\github\msos\msos\ClrThreadExtensions.cs:line 216
   at msos.ClrThreadExtensions.FrameArgumentsAndLocalsRetriever..ctor(ClrThread thread, IList`1 stackTrace, CommandExecutionContext context) in C:\dev\github\msos\msos\ClrThreadExtensions.cs:line 200
   at msos.ClrThreadExtensions.WriteStackTraceToContext(ClrThread thread, IList`1 stackTrace, CommandExecutionContext context, Boolean displayArgumentsAndLocals) in C:\dev\github\msos\msos\ClrThreadExtensions.cs:line 64
   at msos.ClrThreadExtensions.WriteCurrentStackTraceToContext(ClrThread thread, CommandExecutionContext context, Boolean displayArgumentsAndLocals) in C:\dev\github\msos\msos\ClrThreadExtensions.cs:line 54
   at msos.CLRStack.Execute(CommandExecutionContext context) in C:\dev\github\msos\msos\CLRStack.cs:line 31
   at msos.CommandExecutionContext.ExecuteOneCommand(String command) in C:\dev\github\msos\msos\CommandExecutionContext.cs:line 122
Proceed at your own risk, or restart the debugging session.

The callstack I'm analyzing looks like this:

 -> HelperMethodFrame_1OBJ
 -> System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle, Int64, Boolean, Boolean)
 -> System.Threading.WaitHandle.WaitOne(System.TimeSpan, Boolean)
 -> System.Threading.WaitHandle.WaitOne(System.TimeSpan)
 -> XY.Z.FollowerEventListener.<StartHeartBeatMonitor>b__17_0()
 -> System.Threading.Tasks.Task.Execute()
 -> System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
 -> System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
 -> System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
 -> System.Threading.Tasks.Task.ExecuteEntry(Boolean)
 -> System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
 -> System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
 -> System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
 -> System.Threading.ThreadHelper.ThreadStart(System.Object)
 -> GCFrame

The code crashes on inspeciting the frame System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
on this line var matchingFrame = _stackTrace.SingleOrDefault(f => f.DisplayString == frameArgsLocals.MethodName); (see ClrThreadExtensions, method ProcessFrame, my line numbers are a little bit different from the ones on github).

Possible solutions

  • replace the SingleOrDefault with Where and ignore cases where count is != 1
  • pass frame index into ProcessFrame and use this index like this var matchingFrame = _stackTrace[index] - this looks obvious, so there was probably a catch, right?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions