summaryrefslogtreecommitdiff
path: root/src/ToolBox
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-02-28 16:44:26 -0500
committerGitHub <noreply@github.com>2019-02-28 16:44:26 -0500
commit3a0367c75a9b5cebbcc2f2c9609aa05536ed921b (patch)
treebc6aaf7433ae62929982b3e510f7f1941ce9d7cb /src/ToolBox
parent0a93b5136621040b93b9f805e26e7d27d11dc955 (diff)
downloadcoreclr-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.cpp21
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);
+ }
+ }
+ }
+ }
}
}
}