From 6d13f35ebbc0337a7b47f07895dacae51726141e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Jun 2023 11:02:36 -0700 Subject: [PATCH 1/9] Call AssemblyUnloadStarted event --- src/coreclr/vm/loaderallocator.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp index c9eed61a132f66..604aa8218b683d 100644 --- a/src/coreclr/vm/loaderallocator.cpp +++ b/src/coreclr/vm/loaderallocator.cpp @@ -535,6 +535,8 @@ void LoaderAllocator::GCLoaderAllocators(LoaderAllocator* pOriginalLoaderAllocat DomainAssemblyIterator domainAssemblyIt(pDomainLoaderAllocatorDestroyIterator->m_pFirstDomainAssemblyFromSameALCToDelete); while (!domainAssemblyIt.end()) { + // Call AssemblyUnloadStarted event + domainAssemblyIt->GetAssembly()->StartUnload(); // Notify the debugger domainAssemblyIt->NotifyDebuggerUnload(); domainAssemblyIt++; From 65c11a93c937dd99ec57f43120458bd56fc636a1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Jun 2023 16:06:28 -0700 Subject: [PATCH 2/9] Add AssemblyUnload profiler test --- .../assemblyprofiler/assemblyprofiler.cpp | 52 +++++++++++++++++++ .../assemblyprofiler/assemblyprofiler.h | 25 +++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp create mode 100644 src/tests/profiler/native/assemblyprofiler/assemblyprofiler.h diff --git a/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp b/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp new file mode 100644 index 00000000000000..4958a360aeff76 --- /dev/null +++ b/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#include "assemblyprofiler.h" + +GUID AssemblyProfiler::GetClsid() +{ + // TODO: Create a new one here I guess + // {A040B953-EDE7-42D9-9077-AA69BB2BE024} + GUID clsid = { 0xa040b953, 0xede7, 0x42d9,{ 0x90, 0x77, 0xaa, 0x69, 0xbb, 0x2b, 0xe0, 0x24 } }; + return clsid; +} + +HRESULT AssemblyProfiler::Initialize(IUnknown* pICorProfilerInfoUnk) +{ + Profiler::Initialize(pICorProfilerInfoUnk); + + return S_OK; +} + +HRESULT AssemblyProfiler::Shutdown() +{ + Profiler::Shutdown(); + + if (_assemblyUnloadStartedCount != _assemblyUnloadFinishedCount) + { + printf("AssemblyProfiler::Shutdown: FAIL: Expected AssemblyUnloadStarted and AssemblyUnloadFinished to be called the same number of times\n"); + } + else + { + printf("PROFILER TEST PASSES\n"); + } + + fflush(stdout); + return S_OK; +} + +HRESULT AssemblyProfiler::AssemblyUnloadStarted(AssemblyID assemblyId) +{ + SHUTDOWNGUARD(); + + _assemblyUnloadStartedCount++; + return S_OK; +} + +HRESULT AssemblyProfiler::AssemblyUnloadFinished(AssemblyID assemblyId, HRESULT hrStatus) +{ + SHUTDOWNGUARD(); + + _assemblyUnloadFinishedCount++; + return S_OK; +} diff --git a/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.h b/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.h new file mode 100644 index 00000000000000..0d77e7c67c9869 --- /dev/null +++ b/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.h @@ -0,0 +1,25 @@ +// 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 AssemblyProfiler : public Profiler +{ +public: + AssemblyProfiler() : Profiler(), + _assemblyUnloadStartedCount(0), + _assemblyUnloadFinishedCount(0) + {} + + static GUID GetClsid(); + virtual HRESULT STDMETHODCALLTYPE Initialize(IUnknown* pICorProfilerInfoUnk); + virtual HRESULT STDMETHODCALLTYPE Shutdown(); + virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadStarted(AssemblyID assemblyId); + virtual HRESULT STDMETHODCALLTYPE AssemblyUnloadFinished(AssemblyID assemblyId, HRESULT hrStatus); + +private: + std::atomic _assemblyUnloadStartedCount; + std::atomic _assemblyUnloadFinishedCount; +}; From 641a2218cff4c8c3a8d481c6fadacd3b62834f5b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Jun 2023 20:36:32 -0700 Subject: [PATCH 3/9] New GUID --- src/tests/profiler/native/CMakeLists.txt | 1 + .../profiler/native/assemblyprofiler/assemblyprofiler.cpp | 4 +--- src/tests/profiler/native/classfactory.cpp | 5 +++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/profiler/native/CMakeLists.txt b/src/tests/profiler/native/CMakeLists.txt index feb446e8846df6..329cd400c818ae 100644 --- a/src/tests/profiler/native/CMakeLists.txt +++ b/src/tests/profiler/native/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.14.5) project(Profiler) set(SOURCES + assemblyprofiler/assemblyprofiler.cpp eltprofiler/slowpatheltprofiler.cpp eventpipeprofiler/eventpipereadingprofiler.cpp eventpipeprofiler/eventpipewritingprofiler.cpp diff --git a/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp b/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp index 4958a360aeff76..fd105cba81af78 100644 --- a/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp +++ b/src/tests/profiler/native/assemblyprofiler/assemblyprofiler.cpp @@ -5,9 +5,7 @@ GUID AssemblyProfiler::GetClsid() { - // TODO: Create a new one here I guess - // {A040B953-EDE7-42D9-9077-AA69BB2BE024} - GUID clsid = { 0xa040b953, 0xede7, 0x42d9,{ 0x90, 0x77, 0xaa, 0x69, 0xbb, 0x2b, 0xe0, 0x24 } }; + GUID clsid = { 0x19A49007, 0x9E58, 0x4E31,{ 0xB6, 0x55, 0x83, 0xEC, 0x3B, 0x92, 0x4E, 0x7B } }; return clsid; } diff --git a/src/tests/profiler/native/classfactory.cpp b/src/tests/profiler/native/classfactory.cpp index 7d8aa7942e5d9d..c1aec6af53b290 100644 --- a/src/tests/profiler/native/classfactory.cpp +++ b/src/tests/profiler/native/classfactory.cpp @@ -19,6 +19,7 @@ #include "multiple/multiple.h" #include "inlining/inlining.h" #include "moduleload/moduleload.h" +#include "assemblyprofiler/assemblyprofiler.h" ClassFactory::ClassFactory(REFCLSID clsid) : refCount(0), clsid(clsid) { @@ -134,6 +135,10 @@ HRESULT STDMETHODCALLTYPE ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFI { profiler = new ModuleLoad(); } + else if (clsid == AssemblyProfiler::GetClsid()) + { + profiler = new AssemblyProfiler(); + } else { printf("No profiler found in ClassFactory::CreateInstance. Did you add your profiler to the list?\n"); From a33809c964b426d27648b18525a6ba5f2cace808 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Jun 2023 12:54:54 -0700 Subject: [PATCH 4/9] Add managed test --- src/tests/profiler/assembly/ALCTest.cs | 42 +++++++++++++++++++++ src/tests/profiler/assembly/ALCTest.csproj | 19 ++++++++++ src/tests/profiler/assembly/TestFile.cs | 16 ++++++++ src/tests/profiler/assembly/TestFile.csproj | 16 ++++++++ 4 files changed, 93 insertions(+) create mode 100644 src/tests/profiler/assembly/ALCTest.cs create mode 100644 src/tests/profiler/assembly/ALCTest.csproj create mode 100644 src/tests/profiler/assembly/TestFile.cs create mode 100644 src/tests/profiler/assembly/TestFile.csproj diff --git a/src/tests/profiler/assembly/ALCTest.cs b/src/tests/profiler/assembly/ALCTest.cs new file mode 100644 index 00000000000000..0f3e1bda86f5ec --- /dev/null +++ b/src/tests/profiler/assembly/ALCTest.cs @@ -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. + +using System; +using System.IO; +using System.Reflection; + +namespace Profiler.Tests +{ + class ALCTest + { + static readonly Guid AssemblyProfilerGuid = new Guid("19A49007-9E58-4E31-B655-83EC3B924E7B"); + + public static int RunTest(String[] args) + { + string currentAssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + string testAssemblyFullPath1 = Path.Combine(currentAssemblyDirectory, "..", "..", "Interop", "MarshalAPI", "IUnknown", "IUnknownTest.dll"); + string testAssemblyFullPath2 = Path.Combine(currentAssemblyDirectory, "TestFile.dll"); + + int exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath1, args); + if (exitCode != 100) + { + return exitCode; + } + + exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath2, args); + return exitCode; + } + + 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: "ALCTest", + profilerClsid: AssemblyProfilerGuid); + } + } +} diff --git a/src/tests/profiler/assembly/ALCTest.csproj b/src/tests/profiler/assembly/ALCTest.csproj new file mode 100644 index 00000000000000..f20fc4207d6ea1 --- /dev/null +++ b/src/tests/profiler/assembly/ALCTest.csproj @@ -0,0 +1,19 @@ + + + .NETCoreApp + exe + true + true + + true + + + + + + + + diff --git a/src/tests/profiler/assembly/TestFile.cs b/src/tests/profiler/assembly/TestFile.cs new file mode 100644 index 00000000000000..037fd3ab4b53a2 --- /dev/null +++ b/src/tests/profiler/assembly/TestFile.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; + +namespace Profiler.Tests +{ + class TestFile + { + + public static int Main(string[] args) + { + return 0; + } + } +} diff --git a/src/tests/profiler/assembly/TestFile.csproj b/src/tests/profiler/assembly/TestFile.csproj new file mode 100644 index 00000000000000..97c5e67025f845 --- /dev/null +++ b/src/tests/profiler/assembly/TestFile.csproj @@ -0,0 +1,16 @@ + + + .NETCoreApp + exe + true + true + + + + + + From d0c04b8646c7ba062d808e793adfa7b4f916bcbc Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jun 2023 12:10:09 -0700 Subject: [PATCH 5/9] Fix test --- src/tests/profiler/assembly/ALCTest.cs | 15 ++++++++++----- src/tests/profiler/assembly/TestFile.csproj | 2 -- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/tests/profiler/assembly/ALCTest.cs b/src/tests/profiler/assembly/ALCTest.cs index 0f3e1bda86f5ec..208618f4556c17 100644 --- a/src/tests/profiler/assembly/ALCTest.cs +++ b/src/tests/profiler/assembly/ALCTest.cs @@ -11,20 +11,25 @@ class ALCTest { static readonly Guid AssemblyProfilerGuid = new Guid("19A49007-9E58-4E31-B655-83EC3B924E7B"); - public static int RunTest(String[] args) + public static int RunTest(String[] args) { string currentAssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - string testAssemblyFullPath1 = Path.Combine(currentAssemblyDirectory, "..", "..", "Interop", "MarshalAPI", "IUnknown", "IUnknownTest.dll"); - string testAssemblyFullPath2 = Path.Combine(currentAssemblyDirectory, "TestFile.dll"); - + string testAssemblyFullPath1 = Path.Combine(currentAssemblyDirectory, "..", "..", "..", "Interop", "MarshalAPI", "IUnknown", "IUnknownTest", "IUnknownTest.dll"); + string testAssemblyFullPath2 = Path.Combine(currentAssemblyDirectory, "..", "TestFile", "TestFile.dll"); + int exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath1, args); + Console.WriteLine("exitCode = " + exitCode); if (exitCode != 100) { return exitCode; } exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath2, args); - return exitCode; + if (exitCode != 0) + { + return exitCode; + } + return 100; } public static int Main(string[] args) diff --git a/src/tests/profiler/assembly/TestFile.csproj b/src/tests/profiler/assembly/TestFile.csproj index 97c5e67025f845..f47300c2a5258a 100644 --- a/src/tests/profiler/assembly/TestFile.csproj +++ b/src/tests/profiler/assembly/TestFile.csproj @@ -7,10 +7,8 @@ - From 9aed8096cd6909247ab7e933bc0e373178ae8e0a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jun 2023 12:11:11 -0700 Subject: [PATCH 6/9] Remove Console.WriteLine info --- src/tests/profiler/assembly/ALCTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/profiler/assembly/ALCTest.cs b/src/tests/profiler/assembly/ALCTest.cs index 208618f4556c17..d53915e995bd0f 100644 --- a/src/tests/profiler/assembly/ALCTest.cs +++ b/src/tests/profiler/assembly/ALCTest.cs @@ -18,7 +18,6 @@ public static int RunTest(String[] args) string testAssemblyFullPath2 = Path.Combine(currentAssemblyDirectory, "..", "TestFile", "TestFile.dll"); int exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath1, args); - Console.WriteLine("exitCode = " + exitCode); if (exitCode != 100) { return exitCode; From 74c35b9cbe06c1a75e3a2f27491d8031774d3ef1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jun 2023 18:05:18 -0700 Subject: [PATCH 7/9] Fix exit code --- src/tests/profiler/assembly/ALCTest.cs | 2 +- src/tests/profiler/assembly/TestFile.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/profiler/assembly/ALCTest.cs b/src/tests/profiler/assembly/ALCTest.cs index d53915e995bd0f..f8f448a3088579 100644 --- a/src/tests/profiler/assembly/ALCTest.cs +++ b/src/tests/profiler/assembly/ALCTest.cs @@ -24,7 +24,7 @@ public static int RunTest(String[] args) } exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath2, args); - if (exitCode != 0) + if (exitCode != 100) { return exitCode; } diff --git a/src/tests/profiler/assembly/TestFile.cs b/src/tests/profiler/assembly/TestFile.cs index 037fd3ab4b53a2..074b25e1547bc7 100644 --- a/src/tests/profiler/assembly/TestFile.cs +++ b/src/tests/profiler/assembly/TestFile.cs @@ -10,7 +10,7 @@ class TestFile public static int Main(string[] args) { - return 0; + return 100; } } } From e134c106ec51f8525f37ffebc06b5a292afe5d56 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Jul 2023 13:09:01 -0700 Subject: [PATCH 8/9] Adding IUnknownTest Locally --- src/tests/profiler/assembly/ALCTest.cs | 2 +- src/tests/profiler/assembly/CMakeLists.txt | 12 + .../profiler/assembly/IUnknownALCTest.cs | 225 ++++++++++++++++++ .../profiler/assembly/IUnknownALCTest.csproj | 20 ++ .../profiler/assembly/IUnknownNativeALC.cpp | 14 ++ 5 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 src/tests/profiler/assembly/CMakeLists.txt create mode 100644 src/tests/profiler/assembly/IUnknownALCTest.cs create mode 100644 src/tests/profiler/assembly/IUnknownALCTest.csproj create mode 100644 src/tests/profiler/assembly/IUnknownNativeALC.cpp diff --git a/src/tests/profiler/assembly/ALCTest.cs b/src/tests/profiler/assembly/ALCTest.cs index f8f448a3088579..8bd865465db700 100644 --- a/src/tests/profiler/assembly/ALCTest.cs +++ b/src/tests/profiler/assembly/ALCTest.cs @@ -14,7 +14,7 @@ class ALCTest public static int RunTest(String[] args) { string currentAssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - string testAssemblyFullPath1 = Path.Combine(currentAssemblyDirectory, "..", "..", "..", "Interop", "MarshalAPI", "IUnknown", "IUnknownTest", "IUnknownTest.dll"); + string testAssemblyFullPath1 = Path.Combine(currentAssemblyDirectory, "..", "IUnknownALCTest", "IUnknownALCTest.dll"); string testAssemblyFullPath2 = Path.Combine(currentAssemblyDirectory, "..", "TestFile", "TestFile.dll"); int exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath1, args); diff --git a/src/tests/profiler/assembly/CMakeLists.txt b/src/tests/profiler/assembly/CMakeLists.txt new file mode 100644 index 00000000000000..85d6bb97473574 --- /dev/null +++ b/src/tests/profiler/assembly/CMakeLists.txt @@ -0,0 +1,12 @@ +project (IUnknownNativeALC) +include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake") +set(SOURCES IUnknownNativeALC.cpp) + +# add the executable +add_library (IUnknownNativeALC SHARED ${SOURCES}) +target_link_libraries(IUnknownNativeALC PRIVATE ${LINK_LIBRARIES_ADDITIONAL}) + +# add the install targets +install (TARGETS IUnknownNativeALC DESTINATION bin) + + diff --git a/src/tests/profiler/assembly/IUnknownALCTest.cs b/src/tests/profiler/assembly/IUnknownALCTest.cs new file mode 100644 index 00000000000000..6c023ee4ee29f2 --- /dev/null +++ b/src/tests/profiler/assembly/IUnknownALCTest.cs @@ -0,0 +1,225 @@ +// 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.Reflection; +using System.Security; +using System.Runtime.InteropServices; +using System.Collections.Generic; +using Xunit; + +#pragma warning disable 618 + +public class TestClass +{ + public int value; + public string str; + + public TestClass() + { + value = int.MaxValue; + str = "Test String"; + } + + public override string ToString() + { + return str + value; + } +} + +public class IUnknownMarshalingTest +{ + [DllImport(@"IUnknownNative", CallingConvention = CallingConvention.Cdecl)] + private static extern bool Marshal_IUnknown([In]IntPtr ptr); + + private object[] TestObjects; + + public void GetIUnknownForObjectTest() + { + + try + { + //test null + IntPtr nullPtr = Marshal.GetIUnknownForObject(null); + } + catch (ArgumentNullException) { } + + + foreach (object obj in TestObjects) + { + IntPtr ptr = IntPtr.Zero; + + try + { + ptr = Marshal.GetIUnknownForObject(obj); + + if (!Marshal_IUnknown(ptr)) + { + throw new Exception("Failure on native side. Ref counts do not work as expected"); + } + } + finally + { + if (ptr != IntPtr.Zero) + Marshal.Release(ptr); + } + } + } + + public void GetComInterfaceForObjectTest() + { + + //test null + IntPtr nullPtr = Marshal.GetComInterfaceForObject(null, typeof(object)); + if (nullPtr != IntPtr.Zero) + throw new Exception("A valid ptr was returned for null object."); + + foreach (object obj in TestObjects) + { + IntPtr ptr = IntPtr.Zero; + + try + { + ptr = Marshal.GetComInterfaceForObject(obj, typeof(object)); + + if (!Marshal_IUnknown(ptr)) + { + throw new Exception("Failure on native side. Ref counts do not work as expected"); + } + } + finally + { + if (ptr != IntPtr.Zero) + Marshal.Release(ptr); + } + } + } + + public void GetComInterfaceForObjectQueryInterfaceTest() + { + IntPtr nullPtr = Marshal.GetComInterfaceForObject(null, typeof(object), CustomQueryInterfaceMode.Allow); + if (nullPtr != IntPtr.Zero) + throw new Exception("A valid ptr was returned for null object."); + + foreach (object obj in TestObjects) + { + IntPtr ptr = IntPtr.Zero; + ptr = Marshal.GetComInterfaceForObject(obj, typeof(object), CustomQueryInterfaceMode.Allow); + try + { + if (!Marshal_IUnknown(ptr)) + { + throw new Exception("Failure on native side. Ref counts do not work as expected"); + } + } + finally + { + if (ptr != IntPtr.Zero) + Marshal.Release(ptr); + } + } + } + + public void GetObjectForIUnknownTest() + { + try + { + //test IntPtr.Zero + Object nullObj = Marshal.GetObjectForIUnknown(IntPtr.Zero); + + } + catch (ArgumentNullException) { } + + foreach (object obj in TestObjects) + { + IntPtr ptr = IntPtr.Zero; + + try + { + ptr = Marshal.GetIUnknownForObject(obj); + + Object tmpObj = Marshal.GetObjectForIUnknown(ptr); + + //compare the new object reference with the original object, they should point to the same underlying object + if (!object.ReferenceEquals(obj, tmpObj)) + throw new Exception("GetObjectForIUnknown returned a different object. Original: " + obj + ", New: " + tmpObj); + } + finally + { + if (ptr != IntPtr.Zero) + Marshal.Release(ptr); + } + } + } + + public void GetUniqueObjectForIUnknownTest() + { + + //test IntPtr.Zero + Object nullObj = Marshal.GetUniqueObjectForIUnknown(IntPtr.Zero); + + if (nullObj != null) + throw new Exception("Object returned for IntPtr.Zero is not null."); + + + foreach (object obj in TestObjects) + { + IntPtr ptr = IntPtr.Zero; + object tmpObj = null; + + try + { + ptr = Marshal.GetIUnknownForObject(obj); + + tmpObj = Marshal.GetUniqueObjectForIUnknown(ptr); + + //compare the new object reference with the original object, they should point to differnet objects + if (object.ReferenceEquals(obj, tmpObj)) + throw new Exception("GetUniqueObjectForIUnknown returned the original object"); + + //The value should be the same + if (!obj.Equals(tmpObj)) + throw new Exception("GetUniqueObjectForIUnknown returned an object with different value. Original: " + obj + ", New: " + tmpObj); + + } + finally + { + if (tmpObj != null) + Marshal.ReleaseComObject(tmpObj); + if (ptr != IntPtr.Zero) + Marshal.Release(ptr); + } + } + } + + public bool RunTests() + { + Initialize(); + GetIUnknownForObjectTest(); + GetObjectForIUnknownTest(); + return true; + } + + public bool Initialize() + { + TestObjects = new object[7]; + TestObjects[0] = 1; //int + TestObjects[1] = 'a'; //char + TestObjects[2] = false; //bool + TestObjects[3] = "string"; //string + TestObjects[4] = new TestClass(); //Object of type TestClass + TestObjects[5] = new List(); //Projected Type + TestObjects[6] = new Nullable(2); //Nullable Type + return true; + } + + public static int Main() + { + IUnknownMarshalingTest testObj = new IUnknownMarshalingTest(); + testObj.Initialize(); + testObj.RunTests(); + return 100; + } + +} +#pragma warning restore 618 diff --git a/src/tests/profiler/assembly/IUnknownALCTest.csproj b/src/tests/profiler/assembly/IUnknownALCTest.csproj new file mode 100644 index 00000000000000..612dbb167f1c3a --- /dev/null +++ b/src/tests/profiler/assembly/IUnknownALCTest.csproj @@ -0,0 +1,20 @@ + + + Exe + + true + true + + true + + + + + + + + + + diff --git a/src/tests/profiler/assembly/IUnknownNativeALC.cpp b/src/tests/profiler/assembly/IUnknownNativeALC.cpp new file mode 100644 index 00000000000000..6b95f5915b84bf --- /dev/null +++ b/src/tests/profiler/assembly/IUnknownNativeALC.cpp @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +#include +#include + +extern "C" DLL_EXPORT BOOL __cdecl Marshal_IUnknown(/*[in]*/IUnknown *o) +{ + //Call AddRef and Release on the passed IUnknown + //test if the ref counts get updated as expected + unsigned long refCount = o->AddRef(); + if((refCount-1) != o->Release()) + return FALSE; + return TRUE; +} From acfdc8108a3f9dbc0a57a598260499dae92d397f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Jul 2023 19:18:43 -0700 Subject: [PATCH 9/9] Test 1 simple file only --- src/tests/profiler/assembly/ALCTest.cs | 17 +- src/tests/profiler/assembly/CMakeLists.txt | 12 - .../profiler/assembly/IUnknownALCTest.cs | 225 ------------------ .../profiler/assembly/IUnknownALCTest.csproj | 20 -- .../profiler/assembly/IUnknownNativeALC.cpp | 14 -- 5 files changed, 3 insertions(+), 285 deletions(-) delete mode 100644 src/tests/profiler/assembly/CMakeLists.txt delete mode 100644 src/tests/profiler/assembly/IUnknownALCTest.cs delete mode 100644 src/tests/profiler/assembly/IUnknownALCTest.csproj delete mode 100644 src/tests/profiler/assembly/IUnknownNativeALC.cpp diff --git a/src/tests/profiler/assembly/ALCTest.cs b/src/tests/profiler/assembly/ALCTest.cs index 8bd865465db700..edc3c18421bec4 100644 --- a/src/tests/profiler/assembly/ALCTest.cs +++ b/src/tests/profiler/assembly/ALCTest.cs @@ -14,21 +14,10 @@ class ALCTest public static int RunTest(String[] args) { string currentAssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - string testAssemblyFullPath1 = Path.Combine(currentAssemblyDirectory, "..", "IUnknownALCTest", "IUnknownALCTest.dll"); - string testAssemblyFullPath2 = Path.Combine(currentAssemblyDirectory, "..", "TestFile", "TestFile.dll"); + string testAssemblyFullPath = Path.Combine(currentAssemblyDirectory, "..", "TestFile", "TestFile.dll"); - int exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath1, args); - if (exitCode != 100) - { - return exitCode; - } - - exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath2, args); - if (exitCode != 100) - { - return exitCode; - } - return 100; + int exitCode = TestLibrary.Utilities.ExecuteAndUnload(testAssemblyFullPath, args); + return exitCode; } public static int Main(string[] args) diff --git a/src/tests/profiler/assembly/CMakeLists.txt b/src/tests/profiler/assembly/CMakeLists.txt deleted file mode 100644 index 85d6bb97473574..00000000000000 --- a/src/tests/profiler/assembly/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -project (IUnknownNativeALC) -include ("${CLR_INTEROP_TEST_ROOT}/Interop.cmake") -set(SOURCES IUnknownNativeALC.cpp) - -# add the executable -add_library (IUnknownNativeALC SHARED ${SOURCES}) -target_link_libraries(IUnknownNativeALC PRIVATE ${LINK_LIBRARIES_ADDITIONAL}) - -# add the install targets -install (TARGETS IUnknownNativeALC DESTINATION bin) - - diff --git a/src/tests/profiler/assembly/IUnknownALCTest.cs b/src/tests/profiler/assembly/IUnknownALCTest.cs deleted file mode 100644 index 6c023ee4ee29f2..00000000000000 --- a/src/tests/profiler/assembly/IUnknownALCTest.cs +++ /dev/null @@ -1,225 +0,0 @@ -// 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.Reflection; -using System.Security; -using System.Runtime.InteropServices; -using System.Collections.Generic; -using Xunit; - -#pragma warning disable 618 - -public class TestClass -{ - public int value; - public string str; - - public TestClass() - { - value = int.MaxValue; - str = "Test String"; - } - - public override string ToString() - { - return str + value; - } -} - -public class IUnknownMarshalingTest -{ - [DllImport(@"IUnknownNative", CallingConvention = CallingConvention.Cdecl)] - private static extern bool Marshal_IUnknown([In]IntPtr ptr); - - private object[] TestObjects; - - public void GetIUnknownForObjectTest() - { - - try - { - //test null - IntPtr nullPtr = Marshal.GetIUnknownForObject(null); - } - catch (ArgumentNullException) { } - - - foreach (object obj in TestObjects) - { - IntPtr ptr = IntPtr.Zero; - - try - { - ptr = Marshal.GetIUnknownForObject(obj); - - if (!Marshal_IUnknown(ptr)) - { - throw new Exception("Failure on native side. Ref counts do not work as expected"); - } - } - finally - { - if (ptr != IntPtr.Zero) - Marshal.Release(ptr); - } - } - } - - public void GetComInterfaceForObjectTest() - { - - //test null - IntPtr nullPtr = Marshal.GetComInterfaceForObject(null, typeof(object)); - if (nullPtr != IntPtr.Zero) - throw new Exception("A valid ptr was returned for null object."); - - foreach (object obj in TestObjects) - { - IntPtr ptr = IntPtr.Zero; - - try - { - ptr = Marshal.GetComInterfaceForObject(obj, typeof(object)); - - if (!Marshal_IUnknown(ptr)) - { - throw new Exception("Failure on native side. Ref counts do not work as expected"); - } - } - finally - { - if (ptr != IntPtr.Zero) - Marshal.Release(ptr); - } - } - } - - public void GetComInterfaceForObjectQueryInterfaceTest() - { - IntPtr nullPtr = Marshal.GetComInterfaceForObject(null, typeof(object), CustomQueryInterfaceMode.Allow); - if (nullPtr != IntPtr.Zero) - throw new Exception("A valid ptr was returned for null object."); - - foreach (object obj in TestObjects) - { - IntPtr ptr = IntPtr.Zero; - ptr = Marshal.GetComInterfaceForObject(obj, typeof(object), CustomQueryInterfaceMode.Allow); - try - { - if (!Marshal_IUnknown(ptr)) - { - throw new Exception("Failure on native side. Ref counts do not work as expected"); - } - } - finally - { - if (ptr != IntPtr.Zero) - Marshal.Release(ptr); - } - } - } - - public void GetObjectForIUnknownTest() - { - try - { - //test IntPtr.Zero - Object nullObj = Marshal.GetObjectForIUnknown(IntPtr.Zero); - - } - catch (ArgumentNullException) { } - - foreach (object obj in TestObjects) - { - IntPtr ptr = IntPtr.Zero; - - try - { - ptr = Marshal.GetIUnknownForObject(obj); - - Object tmpObj = Marshal.GetObjectForIUnknown(ptr); - - //compare the new object reference with the original object, they should point to the same underlying object - if (!object.ReferenceEquals(obj, tmpObj)) - throw new Exception("GetObjectForIUnknown returned a different object. Original: " + obj + ", New: " + tmpObj); - } - finally - { - if (ptr != IntPtr.Zero) - Marshal.Release(ptr); - } - } - } - - public void GetUniqueObjectForIUnknownTest() - { - - //test IntPtr.Zero - Object nullObj = Marshal.GetUniqueObjectForIUnknown(IntPtr.Zero); - - if (nullObj != null) - throw new Exception("Object returned for IntPtr.Zero is not null."); - - - foreach (object obj in TestObjects) - { - IntPtr ptr = IntPtr.Zero; - object tmpObj = null; - - try - { - ptr = Marshal.GetIUnknownForObject(obj); - - tmpObj = Marshal.GetUniqueObjectForIUnknown(ptr); - - //compare the new object reference with the original object, they should point to differnet objects - if (object.ReferenceEquals(obj, tmpObj)) - throw new Exception("GetUniqueObjectForIUnknown returned the original object"); - - //The value should be the same - if (!obj.Equals(tmpObj)) - throw new Exception("GetUniqueObjectForIUnknown returned an object with different value. Original: " + obj + ", New: " + tmpObj); - - } - finally - { - if (tmpObj != null) - Marshal.ReleaseComObject(tmpObj); - if (ptr != IntPtr.Zero) - Marshal.Release(ptr); - } - } - } - - public bool RunTests() - { - Initialize(); - GetIUnknownForObjectTest(); - GetObjectForIUnknownTest(); - return true; - } - - public bool Initialize() - { - TestObjects = new object[7]; - TestObjects[0] = 1; //int - TestObjects[1] = 'a'; //char - TestObjects[2] = false; //bool - TestObjects[3] = "string"; //string - TestObjects[4] = new TestClass(); //Object of type TestClass - TestObjects[5] = new List(); //Projected Type - TestObjects[6] = new Nullable(2); //Nullable Type - return true; - } - - public static int Main() - { - IUnknownMarshalingTest testObj = new IUnknownMarshalingTest(); - testObj.Initialize(); - testObj.RunTests(); - return 100; - } - -} -#pragma warning restore 618 diff --git a/src/tests/profiler/assembly/IUnknownALCTest.csproj b/src/tests/profiler/assembly/IUnknownALCTest.csproj deleted file mode 100644 index 612dbb167f1c3a..00000000000000 --- a/src/tests/profiler/assembly/IUnknownALCTest.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - Exe - - true - true - - true - - - - - - - - - - diff --git a/src/tests/profiler/assembly/IUnknownNativeALC.cpp b/src/tests/profiler/assembly/IUnknownNativeALC.cpp deleted file mode 100644 index 6b95f5915b84bf..00000000000000 --- a/src/tests/profiler/assembly/IUnknownNativeALC.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -#include -#include - -extern "C" DLL_EXPORT BOOL __cdecl Marshal_IUnknown(/*[in]*/IUnknown *o) -{ - //Call AddRef and Release on the passed IUnknown - //test if the ref counts get updated as expected - unsigned long refCount = o->AddRef(); - if((refCount-1) != o->Release()) - return FALSE; - return TRUE; -}