diff options
author | Stephen Toub <stoub@microsoft.com> | 2019-02-28 16:44:26 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-28 16:44:26 -0500 |
commit | 3a0367c75a9b5cebbcc2f2c9609aa05536ed921b (patch) | |
tree | bc6aaf7433ae62929982b3e510f7f1941ce9d7cb /src/ToolBox | |
parent | 0a93b5136621040b93b9f805e26e7d27d11dc955 (diff) | |
download | coreclr-3a0367c75a9b5cebbcc2f2c9609aa05536ed921b.tar.gz coreclr-3a0367c75a9b5cebbcc2f2c9609aa05536ed921b.tar.bz2 coreclr-3a0367c75a9b5cebbcc2f2c9609aa05536ed921b.zip |
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".
Diffstat (limited to 'src/ToolBox')
-rw-r--r-- | src/ToolBox/SOS/Strike/strike.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
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); + } + } + } + } } } } |