Skip to content

Commit

Permalink
[release/6.0-preview1] For Reverse P/Invokes, call TraceCall with the…
Browse files Browse the repository at this point in the history
… entrypoint to the target method. (#47650)

* For Reverse P/Invokes, call TraceCall with the entrypoint to the target method.

Since we're in an IL stub, we don't need to support breakpoints in the stub itself. The debugger will try to resolve the target method and move the breakpoint there. In actuality, that's the part that's failing. Somewhere in the ReversePInvoke helper call chain, we're touching the secret arg register. As a result, when the debugger tries to move the breakpoint, it crashes. By doing the same work ourselves, the debugger doesn't need to resolve the stub secret arg since it never sees a breakpoint in the stub itself.

* Use IsILStub instead of JIT flag.

* Use UMEntryThunk::GetManagedTarget like what the old system used.

* Calculate the trace call managed target once we're always in COOP GC mode and have a thread.

* Fix rename.

* Dont ask if the target method is an IL stub.

Co-authored-by: Jeremy Koritzinsky <[email protected]>
  • Loading branch information
github-actions[bot] and jkoritzinsky authored Feb 1, 2021
1 parent 2b89781 commit a0f85dd
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
16 changes: 10 additions & 6 deletions src/coreclr/vm/jithelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5360,7 +5360,7 @@ EXCEPTION_HANDLER_DECL(FastNExportExceptHandler);
#endif

// This is a slower version of the reverse PInvoke enter function.
NOINLINE static void JIT_ReversePInvokeEnterRare(ReversePInvokeFrame* frame, void* traceAddr)
NOINLINE static void JIT_ReversePInvokeEnterRare(ReversePInvokeFrame* frame, void* returnAddr, UMEntryThunk* pThunk = NULL)
{
_ASSERTE(frame != NULL);

Expand Down Expand Up @@ -5389,11 +5389,11 @@ NOINLINE static void JIT_ReversePInvokeEnterRare(ReversePInvokeFrame* frame, voi
// Increment/DecrementTraceCallCount() will bump
// g_TrapReturningThreads for us.
if (CORDebuggerTraceCall())
g_pDebugInterface->TraceCall((const BYTE*)traceAddr);
g_pDebugInterface->TraceCall(pThunk ? (const BYTE*)pThunk->GetManagedTarget() : (const BYTE*)returnAddr);
#endif // DEBUGGING_SUPPORTED
}

NOINLINE static void JIT_ReversePInvokeEnterRare2(ReversePInvokeFrame* frame, void* traceAddr)
NOINLINE static void JIT_ReversePInvokeEnterRare2(ReversePInvokeFrame* frame, void* returnAddr, UMEntryThunk* pThunk = NULL)
{
frame->currentThread->RareDisablePreemptiveGC();
#ifdef DEBUGGING_SUPPORTED
Expand All @@ -5403,7 +5403,7 @@ NOINLINE static void JIT_ReversePInvokeEnterRare2(ReversePInvokeFrame* frame, vo
// Increment/DecrementTraceCallCount() will bump
// g_TrapReturningThreads for us.
if (CORDebuggerTraceCall())
g_pDebugInterface->TraceCall((const BYTE*)traceAddr);
g_pDebugInterface->TraceCall(pThunk ? (const BYTE*)pThunk->GetManagedTarget() : (const BYTE*)returnAddr);
#endif // DEBUGGING_SUPPORTED
}

Expand Down Expand Up @@ -5445,12 +5445,16 @@ void F_CALL_CONV HCCALL3(JIT_ReversePInvokeEnterTrackTransitions, ReversePInvoke
thread->m_fPreemptiveGCDisabled.StoreWithoutBarrier(1);
if (g_TrapReturningThreads.LoadWithoutBarrier() != 0)
{
JIT_ReversePInvokeEnterRare2(frame, _ReturnAddress());
// If we're in an IL stub, we want to trace the address of the target method,
// not the next instruction in the stub.
JIT_ReversePInvokeEnterRare2(frame, _ReturnAddress(), GetMethod(handle)->IsILStub() ? (UMEntryThunk*)secretArg : (UMEntryThunk*)NULL);
}
}
else
{
JIT_ReversePInvokeEnterRare(frame, _ReturnAddress());
// If we're in an IL stub, we want to trace the address of the target method,
// not the next instruction in the stub.
JIT_ReversePInvokeEnterRare(frame, _ReturnAddress(), GetMethod(handle)->IsILStub() ? (UMEntryThunk*)secretArg : (UMEntryThunk*)NULL);
}

#ifndef FEATURE_EH_FUNCLETS
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12677,7 +12677,10 @@ CorJitResult CallCompileMethodWithSEHWrapper(EEJitManager *jitMgr,
COMDelegate::ThrowIfInvalidUnmanagedCallersOnlyUsage(ftn);

flags.Set(CORJIT_FLAGS::CORJIT_FLAG_REVERSE_PINVOKE);
if (CORProfilerTrackTransitions())

// If we're a reverse IL stub, we need to use the TrackTransitions variant
// so we have the target MethodDesc entrypoint to tell the debugger about.
if (CORProfilerTrackTransitions() || ftn->IsILStub())
{
flags.Set(CORJIT_FLAGS::CORJIT_FLAG_TRACK_TRANSITIONS);
}
Expand Down

0 comments on commit a0f85dd

Please sign in to comment.