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

Add new DiagnosticMethodInfo public API #103220

Merged
merged 6 commits into from
Jun 13, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -837,4 +837,10 @@
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:System.Threading.Lock.#ctor(System.Boolean)</Target>
</Suppression>
</Suppressions>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:System.Diagnostics.DiagnosticMethodInfo.#ctor(System.String,System.String,System.String)</Target>
<Left>ref/net9.0/System.Private.CoreLib.dll</Left>
<Right>lib/net9.0/System.Private.CoreLib.dll</Right>
</Suppression>
</Suppressions>
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;

using Internal.Runtime.CompilerServices;
using System.Diagnostics;

namespace Internal.Runtime.Augments
{
Expand All @@ -26,5 +25,7 @@ public abstract class StackTraceMetadataCallbacks
/// <param name="isStackTraceHidden">Returns a value indicating whether the method should be hidden in stack traces</param>
/// <returns>Formatted method name or null if metadata for the method is not available</returns>
public abstract string TryGetMethodNameFromStartAddress(IntPtr methodStartAddress, out bool isStackTraceHidden);

public abstract DiagnosticMethodInfo TryGetDiagnosticMethodInfoFromStartAddress(IntPtr methodStartAddress);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
<Compile Include="Internal\Reflection\Extensions\NonPortable\CustomAttributeInheritanceRules.cs" />
<Compile Include="Internal\Reflection\Extensions\NonPortable\CustomAttributeInstantiator.cs" />
<Compile Include="Internal\Reflection\Extensions\NonPortable\CustomAttributeSearcher.cs" />
<Compile Include="System\Diagnostics\DiagnosticMethodInfo.NativeAot.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="System\Reflection\RuntimeAssembly.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

using Internal.Reflection.Augments;
using Internal.Runtime;
using Internal.Runtime.Augments;
using Internal.Runtime.CompilerServices;

namespace System
Expand Down Expand Up @@ -254,6 +255,8 @@ private IntPtr GetActualTargetFunctionPointer(object thisObject)

protected virtual MethodInfo GetMethodImpl()
{
// NOTE: this implementation is mirrored in GetDiagnosticMethodInfo below

// Multi-cast delegates return the Method of the last delegate in the list
if (_helperObject is Wrapper[] invocationList)
{
Expand All @@ -270,6 +273,52 @@ protected virtual MethodInfo GetMethodImpl()
return ReflectionAugments.ReflectionCoreCallbacks.GetDelegateMethod(this);
}

internal DiagnosticMethodInfo GetDiagnosticMethodInfo()
{
// NOTE: this implementation is mirrored in GetMethodImpl above

// Multi-cast delegates return the diagnostic method info of the last delegate in the list
if (_helperObject is Wrapper[] invocationList)
{
int invocationCount = (int)_extraFunctionPointerOrData;
return invocationList[invocationCount - 1].Value.GetDiagnosticMethodInfo();
}

// Return the delegate Invoke method for marshalled function pointers and LINQ expressions
if ((_firstParameter is NativeFunctionPointerWrapper) || (_functionPointer == GetThunk(ObjectArrayThunk)))
{
Type t = GetType();
return new DiagnosticMethodInfo("Invoke", t.FullName, t.Module.Assembly.FullName);
}

IntPtr ldftnResult = GetDelegateLdFtnResult(out RuntimeTypeHandle _, out bool isOpenResolver);
if (isOpenResolver)
{
MethodInfo mi = ReflectionAugments.ReflectionCoreCallbacks.GetDelegateMethod(this);
Type? declaringType = mi.DeclaringType;
if (declaringType.IsConstructedGenericType)
declaringType = declaringType.GetGenericTypeDefinition();
return new DiagnosticMethodInfo(mi.Name, declaringType.FullName, mi.Module.Assembly.FullName);
}
else
{
IntPtr functionPointer;
if (FunctionPointerOps.IsGenericMethodPointer(ldftnResult))
{
unsafe
{
GenericMethodDescriptor* realTargetData = FunctionPointerOps.ConvertToGenericDescriptor(ldftnResult);
functionPointer = RuntimeAugments.GetCodeTarget(realTargetData->MethodFunctionPointer);
}
}
else
{
functionPointer = ldftnResult;
}
return RuntimeAugments.StackTraceCallbacksIfAvailable?.TryGetDiagnosticMethodInfoFromStartAddress(functionPointer);
}
}

public object? Target
{
get
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Internal.Runtime.Augments;

namespace System.Diagnostics
{
public sealed partial class DiagnosticMethodInfo
{
// Public for System.Private.StackTraceMetadata sake
public DiagnosticMethodInfo(string name, string declaringTypeName, string declaringAssemblyName)
=> (Name, DeclaringTypeName, DeclaringAssemblyName) = (name, declaringTypeName, declaringAssemblyName);

public string Name { get; }

public string? DeclaringTypeName { get; }

public string? DeclaringAssemblyName { get; }

public static DiagnosticMethodInfo? Create(Delegate @delegate)
{
ArgumentNullException.ThrowIfNull(@delegate);
return @delegate.GetDiagnosticMethodInfo();
}

public static DiagnosticMethodInfo? Create(StackFrame frame)
{
ArgumentNullException.ThrowIfNull(frame);
return frame.TryGetMethodStartAddress(out IntPtr startAddress)
? RuntimeAugments.StackTraceCallbacksIfAvailable?.TryGetDiagnosticMethodInfoFromStartAddress(startAddress)
: null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ public partial class StackFrame
return _method;
}

internal bool TryGetMethodStartAddress(out IntPtr startAddress)
{
if (_ipAddress == IntPtr.Zero || _ipAddress == Exception.EdiSeparator)
{
startAddress = IntPtr.Zero;
return false;
}

startAddress = _ipAddress - _nativeOffset;
Debug.Assert(RuntimeImports.RhFindMethodStartAddress(_ipAddress) == startAddress);
return true;
}

private bool TryInitializeMethodBase()
{
if (_noMethodBaseAvailable || _ipAddress == IntPtr.Zero || _ipAddress == Exception.EdiSeparator)
Expand Down
Loading
Loading