Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix invalid IL in profiler stub helper #45453

Merged
merged 2 commits into from
Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/coreclr/src/vm/dllimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2247,7 +2247,7 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
else
{
// we use a null pThread to indicate reverse interop
pcsEmit->EmitLDC(NULL);
pcsEmit->EmitLoadNullPtr();
}

// In the unmanaged delegate case, we need the "this" object to retrieve the MD
Expand All @@ -2269,8 +2269,9 @@ DWORD NDirectStubLinker::EmitProfilerBeginTransitionCallback(ILCodeStream* pcsEm
}
else
{
pcsEmit->EmitLDC(NULL);
pcsEmit->EmitLDNULL();
}

pcsEmit->EmitCALL(METHOD__STUBHELPERS__PROFILER_BEGIN_TRANSITION_CALLBACK, 3, 1);

// Store the MD for StubHelpers::ProfilerLeaveCallback().
Expand All @@ -2287,7 +2288,7 @@ void NDirectStubLinker::EmitProfilerEndTransitionCallback(ILCodeStream* pcsEmit,
if (SF_IsReverseStub(dwStubFlags))
{
// we use a null pThread to indicate reverse interop
pcsEmit->EmitLDC(NULL);
pcsEmit->EmitLoadNullPtr();
}
else
{
Expand Down
1 change: 1 addition & 0 deletions src/tests/profiler/native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(SOURCES
getappdomainstaticaddress/getappdomainstaticaddress.cpp
eltprofiler/slowpatheltprofiler.cpp
releaseondetach/releaseondetach.cpp
transitions/transitions.cpp
profiler.def
profiler.cpp
classfactory.cpp
Expand Down
4 changes: 3 additions & 1 deletion src/tests/profiler/native/classfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "eltprofiler/slowpatheltprofiler.h"
#include "gcprofiler/gcprofiler.h"
#include "releaseondetach/releaseondetach.h"
#include "transitions/transitions.h"

ClassFactory::ClassFactory(REFCLSID clsid) : refCount(0), clsid(clsid)
{
Expand Down Expand Up @@ -67,7 +68,8 @@ HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFI
new GetAppDomainStaticAddress(),
new SlowPathELTProfiler(),
new GCProfiler(),
new ReleaseOnDetach()
new ReleaseOnDetach(),
new Transitions()
// add new profilers here
};

Expand Down
1 change: 1 addition & 0 deletions src/tests/profiler/native/profiler.def
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
PassBoolToProfiler PRIVATE
DoPInvoke PRIVATE

85 changes: 85 additions & 0 deletions src/tests/profiler/native/transitions/transitions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "transitions.h"

Transitions::Transitions() :
_failures(0),
_sawEnter(false),
_sawLeave(false)
{

}

GUID Transitions::GetClsid()
{
// {027AD7BB-578E-4921-B29F-B540363D83EC}
GUID clsid = { 0x027AD7BB, 0x578E, 0x4921, { 0xB2, 0x9F, 0xB5, 0x40, 0x36, 0x3D, 0x83, 0xEC } };
return clsid;
}

HRESULT Transitions::Initialize(IUnknown* pICorProfilerInfoUnk)
{
Profiler::Initialize(pICorProfilerInfoUnk);

HRESULT hr = S_OK;
if (FAILED(hr = pCorProfilerInfo->SetEventMask2(COR_PRF_MONITOR_CODE_TRANSITIONS | COR_PRF_DISABLE_INLINING, 0)))
{
_failures++;
printf("FAIL: ICorProfilerInfo::SetEventMask2() failed hr=0x%x", hr);
return hr;
}

return S_OK;
}

HRESULT Transitions::Shutdown()
{
Profiler::Shutdown();

if (_failures == 0 && _sawEnter && _sawLeave)
{
// If we're here, that means we were Released enough to trigger the destructor
printf("PROFILER TEST PASSES\n");
}
else
{
auto boolFmt = [](bool b) { return b ? "true" : "false"; };
printf("Test failed _failures=%d _sawEnter=%s _sawLeave=%s\n",
_failures.load(), boolFmt(_sawEnter), boolFmt(_sawLeave));
}

return S_OK;
}

extern "C" EXPORT void STDMETHODCALLTYPE DoPInvoke(int i)
{
printf("PInvoke received i=%d\n", i);
}

HRESULT Transitions::UnmanagedToManagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason)
{
if (FunctionIsTargetFunction(functionID))
{
_sawEnter = true;
}

return S_OK;
}

HRESULT Transitions::ManagedToUnmanagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason)
{
if (FunctionIsTargetFunction(functionID))
{
_sawLeave = true;
}

return S_OK;
}

bool Transitions::FunctionIsTargetFunction(FunctionID functionID)
{
String name = GetFunctionIDName(functionID);
return name == WCHAR("DoPInvoke");
}
26 changes: 26 additions & 0 deletions src/tests/profiler/native/transitions/transitions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#pragma once

#include "../profiler.h"

class Transitions : public Profiler
{
public:
Transitions();
virtual ~Transitions() = default;

virtual GUID GetClsid();
virtual HRESULT STDMETHODCALLTYPE Initialize(IUnknown* pICorProfilerInfoUnk);
virtual HRESULT STDMETHODCALLTYPE Shutdown();
virtual HRESULT STDMETHODCALLTYPE UnmanagedToManagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason);
virtual HRESULT STDMETHODCALLTYPE ManagedToUnmanagedTransition(FunctionID functionID, COR_PRF_TRANSITION_REASON reason);

private:
std::atomic<int> _failures;
std::atomic<bool> _sawEnter;
std::atomic<bool> _sawLeave;

bool FunctionIsTargetFunction(FunctionID functionID);
};
35 changes: 35 additions & 0 deletions src/tests/profiler/transitions/transitions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices;

namespace Profiler.Tests
{
class GCTests
{
static readonly Guid TransitionsGuid = new Guid("027AD7BB-578E-4921-B29F-B540363D83EC");

[DllImport("Profiler")]
public static extern void DoPInvoke(int i);

public static int RunTest(String[] args)
{
DoPInvoke(13);

return 100;
}

public static int Main(string[] args)
{
if (args.Length > 0 && args[0].Equals("RunTest", StringComparison.OrdinalIgnoreCase))
{
return RunTest(args);
}

return ProfilerTestRunner.Run(profileePath: System.Reflection.Assembly.GetExecutingAssembly().Location,
testName: "Transitions",
profilerClsid: TransitionsGuid);
}
}
}
15 changes: 15 additions & 0 deletions src/tests/profiler/transitions/transitions.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
<OutputType>exe</OutputType>
<CLRTestKind>BuildAndRun</CLRTestKind>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CLRTestPriority>0</CLRTestPriority>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildProjectName).cs" />
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
<ProjectReference Include="../common/profiler_common.csproj" />
<ProjectReference Include="$(MSBuildThisFileDirectory)/../native/CMakeLists.txt" />
</ItemGroup>
</Project>