Skip to content

Commit fde9281

Browse files
authored
fix invalid IL in profiler stub helper (#45453)
1 parent f7530ff commit fde9281

File tree

8 files changed

+170
-4
lines changed

8 files changed

+170
-4
lines changed

src/coreclr/src/vm/dllimport.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,7 +2247,7 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
22472247
else
22482248
{
22492249
// we use a null pThread to indicate reverse interop
2250-
pcsEmit->EmitLDC(NULL);
2250+
pcsEmit->EmitLoadNullPtr();
22512251
}
22522252

22532253
// In the unmanaged delegate case, we need the "this" object to retrieve the MD
@@ -2269,8 +2269,9 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
22692269
}
22702270
else
22712271
{
2272-
pcsEmit->EmitLDC(NULL);
2272+
pcsEmit->EmitLDNULL();
22732273
}
2274+
22742275
pcsEmit->EmitCALL(METHOD__STUBHELPERS__PROFILER_BEGIN_TRANSITION_CALLBACK, 3, 1);
22752276

22762277
// Store the MD for StubHelpers::ProfilerLeaveCallback().
@@ -2287,7 +2288,7 @@ void NDirectStubLinker::EmitProfilerEndTransitionCallback(ILCodeStream* pcsEmit,
22872288
if (SF_IsReverseStub(dwStubFlags))
22882289
{
22892290
// we use a null pThread to indicate reverse interop
2290-
pcsEmit->EmitLDC(NULL);
2291+
pcsEmit->EmitLoadNullPtr();
22912292
}
22922293
else
22932294
{

src/tests/profiler/native/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ set(SOURCES
1515
getappdomainstaticaddress/getappdomainstaticaddress.cpp
1616
eltprofiler/slowpatheltprofiler.cpp
1717
releaseondetach/releaseondetach.cpp
18+
transitions/transitions.cpp
1819
profiler.def
1920
profiler.cpp
2021
classfactory.cpp

src/tests/profiler/native/classfactory.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "eltprofiler/slowpatheltprofiler.h"
1212
#include "gcprofiler/gcprofiler.h"
1313
#include "releaseondetach/releaseondetach.h"
14+
#include "transitions/transitions.h"
1415

1516
ClassFactory::ClassFactory(REFCLSID clsid) : refCount(0), clsid(clsid)
1617
{
@@ -67,7 +68,8 @@ HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFI
6768
new GetAppDomainStaticAddress(),
6869
new SlowPathELTProfiler(),
6970
new GCProfiler(),
70-
new ReleaseOnDetach()
71+
new ReleaseOnDetach(),
72+
new Transitions()
7173
// add new profilers here
7274
};
7375

src/tests/profiler/native/profiler.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ EXPORTS
44
DllGetClassObject PRIVATE
55
DllCanUnloadNow PRIVATE
66
PassBoolToProfiler PRIVATE
7+
DoPInvoke PRIVATE
78

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
2+
// Licensed to the .NET Foundation under one or more agreements.
3+
// The .NET Foundation licenses this file to you under the MIT license.
4+
5+
#include "transitions.h"
6+
7+
Transitions::Transitions() :
8+
_failures(0),
9+
_sawEnter(false),
10+
_sawLeave(false)
11+
{
12+
13+
}
14+
15+
GUID Transitions::GetClsid()
16+
{
17+
// {027AD7BB-578E-4921-B29F-B540363D83EC}
18+
GUID clsid = { 0x027AD7BB, 0x578E, 0x4921, { 0xB2, 0x9F, 0xB5, 0x40, 0x36, 0x3D, 0x83, 0xEC } };
19+
return clsid;
20+
}
21+
22+
HRESULT Transitions::Initialize(IUnknown* pICorProfilerInfoUnk)
23+
{
24+
Profiler::Initialize(pICorProfilerInfoUnk);
25+
26+
HRESULT hr = S_OK;
27+
if (FAILED(hr = pCorProfilerInfo->SetEventMask2(COR_PRF_MONITOR_CODE_TRANSITIONS | COR_PRF_DISABLE_INLINING, 0)))
28+
{
29+
_failures++;
30+
printf("FAIL: ICorProfilerInfo::SetEventMask2() failed hr=0x%x", hr);
31+
return hr;
32+
}
33+
34+
return S_OK;
35+
}
36+
37+
HRESULT Transitions::Shutdown()
38+
{
39+
Profiler::Shutdown();
40+
41+
if (_failures == 0 && _sawEnter && _sawLeave)
42+
{
43+
// If we're here, that means we were Released enough to trigger the destructor
44+
printf("PROFILER TEST PASSES\n");
45+
}
46+
else
47+
{
48+
auto boolFmt = [](bool b) { return b ? "true" : "false"; };
49+
printf("Test failed _failures=%d _sawEnter=%s _sawLeave=%s\n",
50+
_failures.load(), boolFmt(_sawEnter), boolFmt(_sawLeave));
51+
}
52+
53+
return S_OK;
54+
}
55+
56+
extern "C" EXPORT void STDMETHODCALLTYPE DoPInvoke(int i)
57+
{
58+
printf("PInvoke received i=%d\n", i);
59+
}
60+
61+
HRESULT Transitions::UnmanagedToManagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason)
62+
{
63+
if (FunctionIsTargetFunction(functionID))
64+
{
65+
_sawEnter = true;
66+
}
67+
68+
return S_OK;
69+
}
70+
71+
HRESULT Transitions::ManagedToUnmanagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason)
72+
{
73+
if (FunctionIsTargetFunction(functionID))
74+
{
75+
_sawLeave = true;
76+
}
77+
78+
return S_OK;
79+
}
80+
81+
bool Transitions::FunctionIsTargetFunction(FunctionID functionID)
82+
{
83+
String name = GetFunctionIDName(functionID);
84+
return name == WCHAR("DoPInvoke");
85+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
#pragma once
5+
6+
#include "../profiler.h"
7+
8+
class Transitions : public Profiler
9+
{
10+
public:
11+
Transitions();
12+
virtual ~Transitions() = default;
13+
14+
virtual GUID GetClsid();
15+
virtual HRESULT STDMETHODCALLTYPE Initialize(IUnknown* pICorProfilerInfoUnk);
16+
virtual HRESULT STDMETHODCALLTYPE Shutdown();
17+
virtual HRESULT STDMETHODCALLTYPE UnmanagedToManagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason);
18+
virtual HRESULT STDMETHODCALLTYPE ManagedToUnmanagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason);
19+
20+
private:
21+
std::atomic<int> _failures;
22+
std::atomic<bool> _sawEnter;
23+
std::atomic<bool> _sawLeave;
24+
25+
bool FunctionIsTargetFunction(FunctionID functionID);
26+
};
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Runtime.InteropServices;
6+
7+
namespace Profiler.Tests
8+
{
9+
class GCTests
10+
{
11+
static readonly Guid TransitionsGuid = new Guid("027AD7BB-578E-4921-B29F-B540363D83EC");
12+
13+
[DllImport("Profiler")]
14+
public static extern void DoPInvoke(int i);
15+
16+
public static int RunTest(String[] args)
17+
{
18+
DoPInvoke(13);
19+
20+
return 100;
21+
}
22+
23+
public static int Main(string[] args)
24+
{
25+
if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase))
26+
{
27+
return RunTest(args);
28+
}
29+
30+
return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location,
31+
testName: "Transitions",
32+
profilerClsid: TransitionsGuid);
33+
}
34+
}
35+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
4+
<OutputType>exe</OutputType>
5+
<CLRTestKind>BuildAndRun</CLRTestKind>
6+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
7+
<CLRTestPriority>0</CLRTestPriority>
8+
</PropertyGroup>
9+
<ItemGroup>
10+
<Compile Include="$(MSBuildProjectName).cs" />
11+
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
12+
<ProjectReference Include="../common/profiler_common.csproj" />
13+
<ProjectReference Include="$(MSBuildThisFileDirectory)/../native/CMakeLists.txt" />
14+
</ItemGroup>
15+
</Project>

0 commit comments

Comments
 (0)