RSCG – Silhouette

RSCG – Silhouette
 
 

name Silhouette
nuget https://www.nuget.org/packages/Silhouette/
link https://github.com/kevingosse/Silhouette
author Kevin Gosse

Profiling .net applications

Measuring performance improvements

 

This is how you can use Silhouette .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
	  <PublishAot>true</PublishAot>
	  <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Silhouette" Version="3.2.0" />
  </ItemGroup>
	
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	
</Project>


The code that you will use is


// See https://andrewlock.net/creating-a-dotnet-profiler-using-csharp-with-silhouette/
Console.WriteLine("Please read https://andrewlock.net/creating-a-dotnet-profiler-using-csharp-with-silhouette/");



using Silhouette;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace ProfilerDemo;

[Profiler("8AD62131-BF21-47C1-A4D4-3AEF5D7C75C6")]
internal class MyProfiler : CorProfilerCallback5Base
{
    protected override HResult Initialize(int iCorProfilerInfoVersion)
    {
        Console.WriteLine("[SilhouetteProf] Initialize");
        if (iCorProfilerInfoVersion < 5)
        {
            // we need at least ICorProfilerInfo5 and we got < 5
            return HResult.E_FAIL;
        }

        // Call SetEventMask to tell the .NET runtime which events we're interested in
        return ICorProfilerInfo5.SetEventMask(COR_PRF_MONITOR.COR_PRF_MONITOR_ALL);
    }
    protected override HResult ClassLoadStarted(ClassId classId)
    {
        try
        {
            ClassIdInfo classIdInfo = ICorProfilerInfo.GetClassIdInfo(classId).ThrowIfFailed();

            using ComPtr<IMetaDataImport>? metaDataImport = ICorProfilerInfo2
                                                                .GetModuleMetaDataImport(classIdInfo.ModuleId, CorOpenFlags.ofRead)
                                                                .ThrowIfFailed()
                                                                .Wrap();
            TypeDefPropsWithName classProps = metaDataImport.Value.GetTypeDefProps(classIdInfo.TypeDef).ThrowIfFailed();

            Console.WriteLine($"[SilhouetteProf] ClassLoadStarted: {classProps.TypeName}");
            return HResult.S_OK;
        }
        catch (Win32Exception ex)
        {
            Console.WriteLine($"[SilhouetteProf] ClassLoadStarted failed: {ex}");
            return ex.NativeErrorCode;
        }

    }
    protected override HResult Shutdown()
    {
        Console.WriteLine("[SilhouetteProf] Shutdown");
        return HResult.S_OK;
    }

}


 

The code that is generated is

namespace Silhouette._Generated
{
    using System;
    using System.Runtime.InteropServices;

    file static class DllMain
    {
        [UnmanagedCallersOnly(EntryPoint = "DllGetClassObject")]
        public static unsafe HResult DllGetClassObject(Guid* rclsid, Guid* riid, nint* ppv)
        {
            if (*rclsid != new Guid("8ad62131-bf21-47c1-a4d4-3aef5d7c75c6"))
            {
                return HResult.CORPROF_E_PROFILER_CANCEL_ACTIVATION;
            }

            *ppv = ClassFactory.For(new global::ProfilerDemo.MyProfiler());
            return HResult.S_OK;
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/Silhouette


Posted

in

, ,

by

Tags: