Skip to content

Commit 2f0920c

Browse files
authored
For transition profiler callbacks, always load the thread (#105104)
1 parent 67bb10f commit 2f0920c

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
@@ -2272,15 +2272,7 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
22722272
EmitLoadStubContext(pcsEmit, dwStubFlags);
22732273
}
22742274

2275-
if (SF_IsForwardStub(dwStubFlags))
2276-
{
2277-
pcsEmit->EmitLDLOC(GetThreadLocalNum());
2278-
}
2279-
else
2280-
{
2281-
// we use a null pThread to indicate reverse interop
2282-
pcsEmit->EmitLoadNullPtr();
2283-
}
2275+
pcsEmit->EmitLDLOC(GetThreadLocalNum());
22842276

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

src/coreclr/vm/stubhelpers.cpp

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

549549
{
550+
_ASSERTE(pThread != nullptr);
550551
GCX_PREEMP_THREAD_EXISTS(pThread);
551552

552553
ProfilerManagedToUnmanagedTransitionMD(pRealMD, COR_PRF_TRANSITION_CALL);
@@ -577,6 +578,7 @@ FCIMPL2(void, StubHelpers::ProfilerEndTransitionCallback, MethodDesc* pRealMD, T
577578
// and the transition requires us to set up a HMF.
578579
HELPER_METHOD_FRAME_BEGIN_0();
579580
{
581+
_ASSERTE(pThread != nullptr);
580582
GCX_PREEMP_THREAD_EXISTS(pThread);
581583

582584
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)