From f1b4e4562604cfc956131e3d20bbbed26c771fa8 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 14 Oct 2022 16:23:26 -0700 Subject: [PATCH 1/3] Fix 76016 --- src/coreclr/vm/domainassembly.cpp | 8 ++ src/tests/profiler/native/CMakeLists.txt | 1 + src/tests/profiler/native/classfactory.cpp | 5 + .../profiler/native/moduleload/moduleload.cpp | 91 +++++++++++++++++++ .../profiler/native/moduleload/moduleload.h | 42 +++++++++ src/tests/profiler/unittest/moduleload.cs | 46 ++++++++++ src/tests/profiler/unittest/moduleload.csproj | 20 ++++ 7 files changed, 213 insertions(+) create mode 100644 src/tests/profiler/native/moduleload/moduleload.cpp create mode 100644 src/tests/profiler/native/moduleload/moduleload.h create mode 100644 src/tests/profiler/unittest/moduleload.cs create mode 100644 src/tests/profiler/unittest/moduleload.csproj diff --git a/src/coreclr/vm/domainassembly.cpp b/src/coreclr/vm/domainassembly.cpp index 2ae508ca073c5b..fc9821780b4a67 100644 --- a/src/coreclr/vm/domainassembly.cpp +++ b/src/coreclr/vm/domainassembly.cpp @@ -810,6 +810,14 @@ void DomainAssembly::DeliverSyncEvents() GetModule()->NotifyEtwLoadFinished(S_OK); +#ifdef PROFILING_SUPPORTED + if (!IsProfilerNotified()) + { + SetProfilerNotified(); + GetModule()->NotifyProfilerLoadFinished(S_OK); + } +#endif + #ifdef DEBUGGING_SUPPORTED GCX_COOP(); if (!IsDebuggerNotified()) diff --git a/src/tests/profiler/native/CMakeLists.txt b/src/tests/profiler/native/CMakeLists.txt index f72f359af3ceb9..a3d2d77902f386 100644 --- a/src/tests/profiler/native/CMakeLists.txt +++ b/src/tests/profiler/native/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCES handlesprofiler/handlesprofiler.cpp inlining/inlining.cpp metadatagetdispenser/metadatagetdispenser.cpp + moduleload/moduleload.cpp multiple/multiple.cpp nullprofiler/nullprofiler.cpp rejitprofiler/rejitprofiler.cpp diff --git a/src/tests/profiler/native/classfactory.cpp b/src/tests/profiler/native/classfactory.cpp index 6bc76c21f8ac26..418b0b680830b9 100644 --- a/src/tests/profiler/native/classfactory.cpp +++ b/src/tests/profiler/native/classfactory.cpp @@ -17,6 +17,7 @@ #include "transitions/transitions.h" #include "multiple/multiple.h" #include "inlining/inlining.h" +#include "moduleload/moduleload.h" ClassFactory::ClassFactory(REFCLSID clsid) : refCount(0), clsid(clsid) { @@ -124,6 +125,10 @@ HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFI { profiler = new HandlesProfiler(); } + else if (clsid == ModuleLoad::GetClsid()) + { + profiler = new ModuleLoad(); + } else { printf("No profiler found in ClassFactory::CreateInstance. Did you add your profiler to the list?\n"); diff --git a/src/tests/profiler/native/moduleload/moduleload.cpp b/src/tests/profiler/native/moduleload/moduleload.cpp new file mode 100644 index 00000000000000..8057548f668edb --- /dev/null +++ b/src/tests/profiler/native/moduleload/moduleload.cpp @@ -0,0 +1,91 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "moduleload.h" + +GUID ModuleLoad::GetClsid() +{ + // {1774B2E5-028B-4FA8-9DE5-26218CBCBBAC } + GUID clsid = {0x1774b2e5, 0x028b, 0x4fa8, {0x9d, 0xe5, 0x26, 0x21, 0x8c, 0xbc, 0xbb, 0xac}}; + return clsid; +} + +HRESULT ModuleLoad::InitializeCommon(IUnknown* pICorProfilerInfoUnk) +{ + Profiler::Initialize(pICorProfilerInfoUnk); + + HRESULT hr = S_OK; + printf("Setting exception mask\n"); + if (FAILED(hr = pCorProfilerInfo->SetEventMask2(COR_PRF_MONITOR_MODULE_LOADS, 0))) + { + _failures++; + printf("FAIL: ICorProfilerInfo::SetEventMask2() failed hr=0x%x", hr); + return hr; + } + + return S_OK; +} + +HRESULT ModuleLoad::Initialize(IUnknown* pICorProfilerInfoUnk) +{ + return InitializeCommon(pICorProfilerInfoUnk); +} + +HRESULT ModuleLoad::InitializeForAttach(IUnknown* pICorProfilerInfoUnk, void* pvClientData, UINT cbClientData) +{ + return InitializeCommon(pICorProfilerInfoUnk); +} + +HRESULT ModuleLoad::LoadAsNotificationOnly(BOOL *pbNotificationOnly) +{ + *pbNotificationOnly = TRUE; + return S_OK; +} + +HRESULT ModuleLoad::AssemblyLoadStarted(AssemblyID assemblyId) +{ + return S_OK; +} + +HRESULT ModuleLoad::AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus) +{ + return S_OK; +} + +HRESULT ModuleLoad::ModuleLoadStarted(ModuleID moduleId) +{ + return S_OK; +} + +HRESULT ModuleLoad::ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus) +{ + return S_OK; +} + + +HRESULT ModuleLoad::Shutdown() +{ + Profiler::Shutdown(); + + if(_failures == 0 + && (_moduleLoadStartedCount != 0) + && (_assemblyLoadStartedCount != 0) + && (_moduleLoadStartedCount == _moduleLoadFinishedCount) + && (_assemblyLoadStartedCount == _assemblyLoadFinishedCount)) + { + printf("PROFILER TEST PASSES\n"); + } + else + { + printf("PROFILER TEST FAILED, failures=%d moduleLoadStarted=%d moduleLoadFinished=%d assemblyLoadStarted=%d assemblyLoadFinished=%d\n", + _failures.load(), + _moduleLoadStartedCount.load(), + _moduleLoadFinishedCount.load(), + _assemblyLoadStartedCount.load(), + _assemblyLoadFinishedCount.load()); + } + + fflush(stdout); + + return S_OK; +} diff --git a/src/tests/profiler/native/moduleload/moduleload.h b/src/tests/profiler/native/moduleload/moduleload.h new file mode 100644 index 00000000000000..70a93ec23fd01e --- /dev/null +++ b/src/tests/profiler/native/moduleload/moduleload.h @@ -0,0 +1,42 @@ +// 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 ModuleLoad : public Profiler +{ +public: + + ModuleLoad() : + Profiler(), + _assemblyLoadStartedCount(0), + _assemblyLoadFinishedCount(0), + _moduleLoadStartedCount(0), + _moduleLoadFinishedCount(0), + _failures(0) + { + + } + + static GUID GetClsid(); + virtual HRESULT STDMETHODCALLTYPE Initialize(IUnknown* pICorProfilerInfoUnk); + virtual HRESULT STDMETHODCALLTYPE InitializeForAttach(IUnknown* pICorProfilerInfoUnk, void* pvClientData, UINT cbClientData); + virtual HRESULT STDMETHODCALLTYPE Shutdown(); + virtual HRESULT STDMETHODCALLTYPE LoadAsNotificationOnly(BOOL *pbNotificationOnly); + + HRESULT STDMETHODCALLTYPE AssemblyLoadStarted(AssemblyID assemblyId) override; + HRESULT STDMETHODCALLTYPE AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus) override; + HRESULT STDMETHODCALLTYPE ModuleLoadStarted(ModuleID moduleId) override; + HRESULT STDMETHODCALLTYPE ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus) override; + +private: + std::atomic _assemblyLoadStartedCount; + std::atomic _assemblyLoadFinishedCount; + std::atomic _moduleLoadStartedCount; + std::atomic _moduleLoadFinishedCount; + std::atomic _failures; + + HRESULT InitializeCommon(IUnknown* pCorProfilerInfoUnk); +}; diff --git a/src/tests/profiler/unittest/moduleload.cs b/src/tests/profiler/unittest/moduleload.cs new file mode 100644 index 00000000000000..17e1312d8b096f --- /dev/null +++ b/src/tests/profiler/unittest/moduleload.cs @@ -0,0 +1,46 @@ +// 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.IO; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; +using System.Reflection; +using System.Reflection.Emit; + +namespace Profiler.Tests +{ + class ModuleLoadTest + { + private static readonly Guid ModuleLoadGuid = new Guid("1774B2E5-028B-4FA8-9DE5-26218CBCBBAC"); + + public static int RunTest(string[] args) + { + var type = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName("TestAssembly"), AssemblyBuilderAccess.Run) + .DefineDynamicModule("TestModule") + .DefineType("TestClass", TypeAttributes.Public) + .CreateType(); + + var obj = Activator.CreateInstance(type); + if (obj == null) + { + throw new NullReferenceException(); + } + + 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: "UnitTestModuleLoad", + profilerClsid: ModuleLoadGuid); + } + } +} diff --git a/src/tests/profiler/unittest/moduleload.csproj b/src/tests/profiler/unittest/moduleload.csproj new file mode 100644 index 00000000000000..e94b734bb5a977 --- /dev/null +++ b/src/tests/profiler/unittest/moduleload.csproj @@ -0,0 +1,20 @@ + + + .NETCoreApp + exe + true + + true + + true + + + + + + + + From 76b4c9ee8d24d630e1b80015b08299198841dbf3 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 14 Oct 2022 16:32:30 -0700 Subject: [PATCH 2/3] fix test --- src/tests/profiler/native/moduleload/moduleload.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/tests/profiler/native/moduleload/moduleload.cpp b/src/tests/profiler/native/moduleload/moduleload.cpp index 8057548f668edb..008ecdfd8d2718 100644 --- a/src/tests/profiler/native/moduleload/moduleload.cpp +++ b/src/tests/profiler/native/moduleload/moduleload.cpp @@ -16,7 +16,7 @@ HRESULT ModuleLoad::InitializeCommon(IUnknown* pICorProfilerInfoUnk) HRESULT hr = S_OK; printf("Setting exception mask\n"); - if (FAILED(hr = pCorProfilerInfo->SetEventMask2(COR_PRF_MONITOR_MODULE_LOADS, 0))) + if (FAILED(hr = pCorProfilerInfo->SetEventMask2(COR_PRF_MONITOR_MODULE_LOADS | COR_PRF_MONITOR_ASSEMBLY_LOADS, 0))) { _failures++; printf("FAIL: ICorProfilerInfo::SetEventMask2() failed hr=0x%x", hr); @@ -44,21 +44,25 @@ HRESULT ModuleLoad::LoadAsNotificationOnly(BOOL *pbNotificationOnly) HRESULT ModuleLoad::AssemblyLoadStarted(AssemblyID assemblyId) { + _assemblyLoadStartedCount++; return S_OK; } HRESULT ModuleLoad::AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus) { + _assemblyLoadFinishedCount++; return S_OK; } HRESULT ModuleLoad::ModuleLoadStarted(ModuleID moduleId) { + _moduleLoadStartedCount++; return S_OK; } HRESULT ModuleLoad::ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus) { + _moduleLoadFinishedCount++; return S_OK; } From a3bccfff5ccd22c96aa1c2ea0d9adb2eb518cba2 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 14 Oct 2022 17:12:41 -0700 Subject: [PATCH 3/3] Update moduleload.h --- src/tests/profiler/native/moduleload/moduleload.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/profiler/native/moduleload/moduleload.h b/src/tests/profiler/native/moduleload/moduleload.h index 70a93ec23fd01e..56ccc131250199 100644 --- a/src/tests/profiler/native/moduleload/moduleload.h +++ b/src/tests/profiler/native/moduleload/moduleload.h @@ -26,10 +26,10 @@ class ModuleLoad : public Profiler virtual HRESULT STDMETHODCALLTYPE Shutdown(); virtual HRESULT STDMETHODCALLTYPE LoadAsNotificationOnly(BOOL *pbNotificationOnly); - HRESULT STDMETHODCALLTYPE AssemblyLoadStarted(AssemblyID assemblyId) override; - HRESULT STDMETHODCALLTYPE AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus) override; - HRESULT STDMETHODCALLTYPE ModuleLoadStarted(ModuleID moduleId) override; - HRESULT STDMETHODCALLTYPE ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus) override; + virtual HRESULT STDMETHODCALLTYPE AssemblyLoadStarted(AssemblyID assemblyId); + virtual HRESULT STDMETHODCALLTYPE AssemblyLoadFinished(AssemblyID assemblyId, HRESULT hrStatus); + virtual HRESULT STDMETHODCALLTYPE ModuleLoadStarted(ModuleID moduleId); + virtual HRESULT STDMETHODCALLTYPE ModuleLoadFinished(ModuleID moduleId, HRESULT hrStatus); private: std::atomic _assemblyLoadStartedCount;