Skip to content

Commit a76400c

Browse files
[release/8.0-staging] For transition profiler callbacks, always load the thread (#105200)
Co-authored-by: Jeremy Koritzinsky <[email protected]> Co-authored-by: Jeremy Koritzinsky <[email protected]>
1 parent 8912b21 commit a76400c

File tree

5 files changed

+51
-14
lines changed

5 files changed

+51
-14
lines changed

src/coreclr/vm/dllimport.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,15 +2268,7 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
22682268
EmitLoadStubContext(pcsEmit, dwStubFlags);
22692269
}
22702270

2271-
if (SF_IsForwardStub(dwStubFlags))
2272-
{
2273-
pcsEmit->EmitLDLOC(GetThreadLocalNum());
2274-
}
2275-
else
2276-
{
2277-
// we use a null pThread to indicate reverse interop
2278-
pcsEmit->EmitLoadNullPtr();
2279-
}
2271+
pcsEmit->EmitLDLOC(GetThreadLocalNum());
22802272

22812273
// In the unmanaged delegate case, we need the "this" object to retrieve the MD
22822274
// in StubHelpers::ProfilerEnterCallback().

src/coreclr/vm/stubhelpers.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ FCIMPL3(SIZE_T, StubHelpers::ProfilerBeginTransitionCallback, SIZE_T pSecretPara
552552
}
553553

554554
{
555+
_ASSERTE(pThread != nullptr);
555556
GCX_PREEMP_THREAD_EXISTS(pThread);
556557

557558
ProfilerManagedToUnmanagedTransitionMD(pRealMD, COR_PRF_TRANSITION_CALL);
@@ -582,6 +583,7 @@ FCIMPL2(void, StubHelpers::ProfilerEndTransitionCallback, MethodDesc* pRealMD, T
582583
// and the transition requires us to set up a HMF.
583584
HELPER_METHOD_FRAME_BEGIN_0();
584585
{
586+
_ASSERTE(pThread != nullptr);
585587
GCX_PREEMP_THREAD_EXISTS(pThread);
586588

587589
ProfilerUnmanagedToManagedTransitionMD(pRealMD, COR_PRF_TRANSITION_RETURN);

src/tests/profiler/native/profiler.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ EXPORTS
55
DllCanUnloadNow PRIVATE
66
PassCallbackToProfiler PRIVATE
77
DoPInvoke PRIVATE
8+
DoPInvokeWithCallbackOnOtherThread PRIVATE
89

src/tests/profiler/native/transitions/transitions.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ extern "C" EXPORT void STDMETHODCALLTYPE DoPInvoke(int(*callback)(int), int i)
6969
printf("PInvoke received i=%d\n", callback(i));
7070
}
7171

72+
extern "C" EXPORT void STDMETHODCALLTYPE DoPInvokeWithCallbackOnOtherThread(int(*callback)(int), int i)
73+
{
74+
int j = 0;
75+
std::thread t([&j, callback, i] { j = callback(i); });
76+
t.join();
77+
printf("PInvoke with callback on other thread received i=%d\n", j);
78+
}
79+
7280

7381
HRESULT Transitions::UnmanagedToManagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason)
7482
{
@@ -124,4 +132,4 @@ bool Transitions::FunctionIsTargetFunction(FunctionID functionID, TransitionInst
124132
}
125133

126134
return true;
127-
}
135+
}

src/tests/profiler/transitions/transitions.cs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ private static int DoDelegateReversePInvokeNonBlittable(bool b)
3232
public static int BlittablePInvokeToBlittableInteropDelegate()
3333
{
3434
InteropDelegate del = DoDelegateReversePInvoke;
35-
35+
3636
DoPInvoke((delegate* unmanaged<int,int>)Marshal.GetFunctionPointerForDelegate(del), 13);
3737
GC.KeepAlive(del);
3838

@@ -42,13 +42,23 @@ public static int BlittablePInvokeToBlittableInteropDelegate()
4242
public static int NonBlittablePInvokeToNonBlittableInteropDelegate()
4343
{
4444
InteropDelegateNonBlittable del = DoDelegateReversePInvokeNonBlittable;
45-
45+
4646
DoPInvokeNonBlitable((delegate* unmanaged<int,int>)Marshal.GetFunctionPointerForDelegate(del), true);
4747
GC.KeepAlive(del);
4848

4949
return 100;
5050
}
5151

52+
public static int BlittablePInvokeToBlittableInteropDelegateOnOtherThread()
53+
{
54+
InteropDelegate del = DoDelegateReversePInvoke;
55+
56+
DoPInvokeWithCallbackOnOtherThread((delegate* unmanaged<int,int>)Marshal.GetFunctionPointerForDelegate(del), 13);
57+
GC.KeepAlive(del);
58+
59+
return 100;
60+
}
61+
5262
[UnmanagedCallersOnly]
5363
private static int DoReversePInvoke(int i)
5464
{
@@ -61,6 +71,9 @@ private static int DoReversePInvoke(int i)
6171
[DllImport("Profiler", EntryPoint = nameof(DoPInvoke))]
6272
public static extern void DoPInvokeNonBlitable(delegate* unmanaged<int,int> callback, bool i);
6373

74+
[DllImport("Profiler")]
75+
public static extern void DoPInvokeWithCallbackOnOtherThread(delegate* unmanaged<int,int> callback, int i);
76+
6477
public static int BlittablePInvokeToUnmanagedCallersOnly()
6578
{
6679
DoPInvoke(&DoReversePInvoke, 13);
@@ -75,6 +88,13 @@ public static int NonBlittablePInvokeToUnmanagedCallersOnly()
7588
return 100;
7689
}
7790

91+
public static int BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread()
92+
{
93+
DoPInvokeWithCallbackOnOtherThread(&DoReversePInvoke, 13);
94+
95+
return 100;
96+
}
97+
7898
public static int Main(string[] args)
7999
{
80100
if (args.Length > 1 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase))
@@ -89,6 +109,10 @@ public static int Main(string[] args)
89109
return NonBlittablePInvokeToUnmanagedCallersOnly();
90110
case nameof(NonBlittablePInvokeToNonBlittableInteropDelegate):
91111
return NonBlittablePInvokeToNonBlittableInteropDelegate();
112+
case nameof(BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread):
113+
return BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread();
114+
case nameof(BlittablePInvokeToBlittableInteropDelegateOnOtherThread):
115+
return BlittablePInvokeToBlittableInteropDelegateOnOtherThread();
92116
}
93117
}
94118

@@ -104,12 +128,22 @@ public static int Main(string[] args)
104128

105129
if (!RunProfilerTest(nameof(NonBlittablePInvokeToUnmanagedCallersOnly), nameof(DoPInvokeNonBlitable), nameof(DoReversePInvoke)))
106130
{
107-
return 101;
131+
return 103;
108132
}
109133

110134
if (!RunProfilerTest(nameof(NonBlittablePInvokeToNonBlittableInteropDelegate), nameof(DoPInvokeNonBlitable), "Invoke"))
111135
{
112-
return 102;
136+
return 104;
137+
}
138+
139+
if (!RunProfilerTest(nameof(BlittablePInvokeToUnmanagedCallersOnlyOnOtherThread), nameof(DoPInvokeWithCallbackOnOtherThread), nameof(DoReversePInvoke)))
140+
{
141+
return 105;
142+
}
143+
144+
if (!RunProfilerTest(nameof(BlittablePInvokeToBlittableInteropDelegateOnOtherThread), nameof(DoPInvokeWithCallbackOnOtherThread), "Invoke"))
145+
{
146+
return 106;
113147
}
114148

115149
return 100;

0 commit comments

Comments
 (0)