From 3a0367c75a9b5cebbcc2f2c9609aa05536ed921b Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 28 Feb 2019 16:44:26 -0500 Subject: Fix DumpAsync to understand ContinuationWrapper (#22913) Continuations created while the debugger is attached or certain EventSource events are enabled end up getting wrapped in an extra ContinuationWrapper object that carries some additional information. DumpAsync currently isn't unwrapping these but should. This just teaches it to look for a known field name so that it can "see through" these wrappers while following async "stacks". --- src/ToolBox/SOS/Strike/strike.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/ToolBox') diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp index 82af32ede7..7d74458d46 100644 --- a/src/ToolBox/SOS/Strike/strike.cpp +++ b/src/ToolBox/SOS/Strike/strike.cpp @@ -4273,13 +4273,32 @@ void ResolveContinuation(CLRDATA_ADDRESS* contAddr) } } - // If it was, or if it's storing an action, try to follow through to the action's target. + // If we now have an Action, try to follow through to the delegate's target. if ((offset = GetObjFieldOffset(contObj.GetAddress(), contObj.GetMT(), W("_target"))) != 0) { MOVE(*contAddr, contObj.GetAddress() + offset); if (sos::IsObject(*contAddr, false)) { contObj = TO_TADDR(*contAddr); + + // In some cases, the delegate's target might be a ContinuationWrapper, in which case we want to unwrap that as well. + if (_wcsncmp(contObj.GetTypeName(), W("System.Runtime.CompilerServices.AsyncMethodBuilderCore+ContinuationWrapper"), 74) == 0 && + (offset = GetObjFieldOffset(contObj.GetAddress(), contObj.GetMT(), W("_continuation"))) != 0) + { + MOVE(*contAddr, contObj.GetAddress() + offset); + if (sos::IsObject(*contAddr, false)) + { + contObj = TO_TADDR(*contAddr); + if ((offset = GetObjFieldOffset(contObj.GetAddress(), contObj.GetMT(), W("_target"))) != 0) + { + MOVE(*contAddr, contObj.GetAddress() + offset); + if (sos::IsObject(*contAddr, false)) + { + contObj = TO_TADDR(*contAddr); + } + } + } + } } } } -- cgit v1.2.3