Exemple #1
0
        protected CausalityNode(CausalityContext context, ClrInstance clrInstance, NodeKind kind)
        {
            Context     = context;
            ClrInstance = clrInstance;

            Id   = Contract.AssertNotNull(clrInstance.ValueOrDefault?.ToString(), "ValueOrDefault should not be null");
            Kind = kind;
        }
Exemple #2
0
 public static CausalityNode Create(CausalityContext context, ClrInstance clrInstance, NodeKind kind)
 {
     return(kind switch
     {
         NodeKind.Task => new TaskNode(context, clrInstance),
         NodeKind.TaskCompletionSource => new TaskCompletionSourceNode(context, clrInstance),
         NodeKind.AsyncStateMachine => new AsyncStateMachineNode(context, clrInstance),
         NodeKind.AwaitTaskContinuation => new AwaitTaskContinuationNode(context, clrInstance),
         NodeKind.Thread => new ThreadNode(context, clrInstance),
         NodeKind.ManualResetEventSlim => new ManualResetEventSlimNode(context, clrInstance),
         NodeKind.SemaphoreSlim => new SemaphoreSlimNode(context, clrInstance),
         NodeKind.SynchronizationContext => new SynchronizationContextNode(context, clrInstance),
         _ => Return(() => new CausalityNode(context, clrInstance, kind)),
     });
Exemple #3
0
        public static CausalityContext LoadCausalityContextFromDump(string dumpPath)
        {
            var heapContext = new HeapContext(() =>
            {
                var target      = DataTarget.LoadCrashDump(dumpPath);
                var dacLocation = target.ClrVersions[0];
                var runtime     = dacLocation.CreateRuntime();
                var heap        = runtime.Heap;
                return(heap);
            });

            var context = new CausalityContext(heapContext);

            Console.WriteLine("Linking the nodes together.");
            context.LinkNodes();
            return(context);
        }
Exemple #4
0
        public AsyncStateMachineNode(CausalityContext context, ClrInstance clrInstance)
            : base(context, clrInstance, NodeKind.AsyncStateMachine)
        {
            _status = StateMachineState switch
            {
                InitialState => StateMachineStatus.Created,
                CompletedState => StateMachineStatus.Completed,
                _ => StateMachineStatus.Awaiting,
            };

            if (_status == StateMachineStatus.Awaiting)
            {
                _awaitedTask = GetAwaitedTask();
                Contract.AssertNotNull(_awaitedTask, $"For state machine state '{StateMachineState}' an awaited task should be available");
            }

            _resultingTask = GetResultingTask(clrInstance, Context.Registry);
        }
Exemple #5
0
 public TaskNode(CausalityContext context, ClrInstance clrInstance)
     : base(context, clrInstance, NodeKind.Task)
 {
     _taskInstance = new TaskInstance(clrInstance);
 }
        public static ClrInstance?TryResolveContinuationForAction(ClrInstance instance, CausalityContext context)
        {
            Contract.Requires(instance.IsOfType(typeof(Action), context), $"A given instance should be of type System.Action, but was '{instance.Type.TypeToString(context.Registry)}'");

            var continuation = instance;
            var actionTarget = continuation["_target"].Instance;

            if (actionTarget.IsOfType(context.Registry.ContinuationWrapperType))
            {
                // Do we need to look at the m_innerTask field as well here?
                return(actionTarget["m_continuation"].Instance);
            }

            // If the action points to a closure, it is possible that the closure
            // is responsible for setting the result of a task completion source.
            // There is no simple way to detect whether this is the case or not, so we will add the "edge" unconditionally.
            if (actionTarget.Type.IsClosure())
            {
                foreach (var field in actionTarget.Fields)
                {
                    if (field.Instance.IsTaskCompletionSource(context))
                    {
                        return(field.Instance);
                    }
                }
            }

            // m_stateMachine field is defined in AsyncMethodBuilderCore and in MoveNextRunner.
            var stateMachine = actionTarget.TryGetFieldValue("m_stateMachine")?.Instance;

            if (stateMachine.IsNull())
            {
                return(null);
            }

            return(stateMachine);
        }
        public static ClrInstance?TryResolveContinuationInstance(ClrInstance continuation, CausalityContext context)
        {
            if (continuation.IsOfType(context.Registry.StandardTaskContinuationType))
            {
                return(continuation["m_task"].Instance);
            }

            if (continuation.IsTaskCompletionSource(context))
            {
                return(continuation["m_task"].Instance);
            }

            if (continuation.IsCompletedTaskContinuation(context))
            {
                // Continuation is a special sentinel instance that indicates that the task is completed.
                return(null);
            }

            if (continuation.IsOfType(typeof(Action), context))
            {
                return(TryResolveContinuationForAction(continuation, context));
            }

            if (continuation.IsOfType(context.Registry.AwaitTaskContinuationIndex) || continuation.IsOfType(context.Registry.TaskIndex))
            {
                return(TryResolveContinuationForAction(continuation["m_action"].Instance, context));
            }

            // Need to compare by name since GetTypeByName does not work for the generic type during initialization
            if (continuation.IsListOfObjects())
            {
                Contract.Assert(false, "Please call 'TryResolveContinuations' for a list of continuations.");
            }

            return(null);
        }
        public static ClrInstance[] TryResolveContinuations(ClrInstance continuation, CausalityContext context)
        {
            if (continuation.IsListOfObjects())
            {
                var result = new List <ClrInstance>();
                int size   = (int)continuation["_size"].Instance.ValueOrDefault !;
                var items  = continuation["_items"].Instance.Items;

                for (int i = 0; i < size; i++)
                {
                    var continuationItem = TryResolveContinuationInstance(items[i], context);
                    if (continuationItem != null)
                    {
                        result.Add(continuationItem);
                    }

                    return(result.ToArray());
                }
            }

            var resolvedContinuation = TryResolveContinuationInstance(continuation, context);

            if (resolvedContinuation != null)
            {
                return(new[] { resolvedContinuation });
            }

            return(Array.Empty <ClrInstance>());
        }
Exemple #9
0
 public SemaphoreSlimNode(CausalityContext context, ClrInstance clrInstance) : base(context, clrInstance, NodeKind.SemaphoreSlim)
 {
     _asyncWaiters = GetAsynchronousWaiters().ToList();
 }
Exemple #10
0
 public SynchronizationContextNode(CausalityContext context, ClrInstance clrInstance)
     : base(context, clrInstance, NodeKind.SynchronizationContext)
 {
 }
 public AwaitTaskContinuationNode(CausalityContext context, ClrInstance clrInstance)
     : base(context, clrInstance, NodeKind.AwaitTaskContinuation)
 {
 }
Exemple #12
0
 public ManualResetEventSlimNode(CausalityContext context, ClrInstance clrInstance)
     : base(context, clrInstance, NodeKind.ManualResetEventSlim)
 {
 }
 public TaskCompletionSourceNode(CausalityContext context, ClrInstance clrInstance)
     : base(context, clrInstance, NodeKind.TaskCompletionSource)
 {
 }