Make code in `getTargetMethodDesc` more reliable. (dotnet/coreclr#21101)
authorSergey Andreenko <seandree@microsoft.com>
Tue, 20 Nov 2018 05:53:14 +0000 (21:53 -0800)
committerGitHub <noreply@github.com>
Tue, 20 Nov 2018 05:53:14 +0000 (21:53 -0800)
* Make code in `getTargetMethodDesc` more reliable.

Fixes DevDiv_723667.

* change the condition to make sure that we do not have false true cases.

Commit migrated from https://github.com/dotnet/coreclr/commit/417fea5c5b358a79c6d096a887a89c12ec3ece2e

src/coreclr/src/vm/gccover.cpp

index 2ba76d3..48dcf8b 100644 (file)
@@ -43,25 +43,33 @@ static void replaceSafePointInstructionWithGcStressInstr(UINT32 safePointOffset,
 static bool replaceInterruptibleRangesWithGcStressInstr (UINT32 startOffset, UINT32 stopOffset, LPVOID codeStart);
 #endif
 
+// There is a call target instruction, try to find the MethodDesc for where target points to.
+// Returns nullptr if it can't find it.
 static MethodDesc* getTargetMethodDesc(PCODE target)
 {
     MethodDesc* targetMD = ExecutionManager::GetCodeMethodDesc(target);
-    if (targetMD == 0) 
+    if (targetMD != nullptr)
     {
-        VirtualCallStubManager::StubKind vsdStubKind = VirtualCallStubManager::SK_UNKNOWN;
-        VirtualCallStubManager *pVSDStubManager = VirtualCallStubManager::FindStubManager(target, &vsdStubKind);
-        if (vsdStubKind != VirtualCallStubManager::SK_BREAKPOINT && vsdStubKind != VirtualCallStubManager::SK_UNKNOWN)
-        {
-            DispatchToken token = VirtualCallStubManager::GetTokenFromStubQuick(pVSDStubManager, target, vsdStubKind);
-            _ASSERTE(token.IsValid());
-            targetMD = VirtualCallStubManager::GetInterfaceMethodDescFromToken(token);
-        }
-        else
-        {
-            targetMD = AsMethodDesc(size_t(MethodDesc::GetMethodDescFromStubAddr(target, TRUE)));
-        }
+        // It is JIT/NGened call.
+        return targetMD;
     }
-    return targetMD;
+
+    VirtualCallStubManager::StubKind vsdStubKind = VirtualCallStubManager::SK_UNKNOWN;
+    VirtualCallStubManager *pVSDStubManager = VirtualCallStubManager::FindStubManager(target, &vsdStubKind);
+    if (vsdStubKind != VirtualCallStubManager::SK_BREAKPOINT && vsdStubKind != VirtualCallStubManager::SK_UNKNOWN)
+    {
+        // It is a VSD stub manager.
+        DispatchToken token = VirtualCallStubManager::GetTokenFromStubQuick(pVSDStubManager, target, vsdStubKind);
+        _ASSERTE(token.IsValid());
+        return VirtualCallStubManager::GetInterfaceMethodDescFromToken(token);
+    }
+    if (RangeSectionStubManager::GetStubKind(target) == STUB_CODE_BLOCK_PRECODE)
+    {
+        // The address looks like a value stub, try to get the method descriptor.
+        return MethodDesc::GetMethodDescFromStubAddr(target, TRUE);
+    }
+
+    return nullptr;
 }