Skip to content
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
2 changes: 1 addition & 1 deletion src/coreclr/debug/runtimeinfo/datadescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,7 @@ CDAC_GLOBAL_POINTER(GCThread, &::g_pSuspensionThread)

// Add FrameIdentifier for all defined Frame types. Used to differentiate Frame objects.
#define FRAME_TYPE_NAME(frameType) \
CDAC_GLOBAL_POINTER(frameType##Identifier, FrameIdentifier::frameType)
CDAC_GLOBAL(frameType##Identifier, nuint, (uint64_t)FrameIdentifier::frameType)

#include "frames.h"
#undef FRAME_TYPE_NAME
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ public enum CorDebugPlatform : int
/// <returns>The value of the global</returns>
public abstract TargetPointer ReadGlobalPointer(string global);

/// <summary>
/// Reads a well-known global pointer value from the target process
/// </summary>
/// <param name="global">The name of the global</param>
/// <param name="value">The value of the global, if found.</param>
/// <returns>True if the global is found, false otherwise.</returns>
public abstract bool TryReadGlobalPointer(string name, [NotNullWhen(true)] out TargetPointer? value);

/// <summary>
/// Read a pointer from the target in target endianness
/// </summary>
Expand Down Expand Up @@ -119,6 +127,15 @@ public enum CorDebugPlatform : int
/// <returns>A numeric value</returns>
public abstract T ReadGlobal<T>(string name) where T : struct, INumber<T>;

/// <summary>
/// Read a well known global from the target process as a number in the target endianness
/// </summary>
/// <typeparam name="T">The numeric type to be read</typeparam>
/// <param name="name">The name of the global</param>
/// <param name="value">The numeric value read.</param>
/// <returns>True if a global is found, false otherwise.</returns>
public abstract bool TryReadGlobal<T>(string name, [NotNullWhen(true)] out T? value) where T : struct, INumber<T>;

/// <summary>
/// Read a value from the target in target endianness
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,13 @@ private static FrameType GetFrameType(Target target, TargetPointer frameIdentifi
{
foreach (FrameType frameType in Enum.GetValues<FrameType>())
Comment thread
davmason marked this conversation as resolved.
{
TargetPointer foundFrameIdentifier;
try
if (target.TryReadGlobalPointer(frameType.ToString() + "Identifier", out TargetPointer? id))
{
// not all Frames are in all builds, so we need to catch the exception
foundFrameIdentifier = target.ReadGlobalPointer(frameType.ToString() + "Identifier");
if (frameIdentifier == foundFrameIdentifier)
if (frameIdentifier == id)
{
return frameType;
}
}
catch (InvalidOperationException)
{
}
}

return FrameType.Unknown;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,22 @@ public bool IsAlignedToPointerSize(ulong value)
public override bool IsAlignedToPointerSize(TargetPointer pointer)
=> IsAligned(pointer.Value, _config.PointerSize);

public override bool TryReadGlobal<T>(string name, [NotNullWhen(true)] out T? value)
=> TryReadGlobal<T>(name, out value, out _);

public bool TryReadGlobal<T>(string name, [NotNullWhen(true)] out T? value, out string? type) where T : struct, INumber<T>
{
value = null;
type = null;
if (!_globals.TryGetValue(name, out (ulong Value, string? Type) global))
{
return false;
}
type = global.Type;
value = T.CreateChecked(global.Value);
return true;
}

public override T ReadGlobal<T>(string name)
=> ReadGlobal<T>(name, out _);

Expand All @@ -508,6 +524,21 @@ public T ReadGlobal<T>(string name, out string? type) where T : struct, INumber<
return T.CreateChecked(global.Value);
}

public override bool TryReadGlobalPointer(string name, [NotNullWhen(true)] out TargetPointer? value)
=> TryReadGlobalPointer(name, out value, out _);

public bool TryReadGlobalPointer(string name, [NotNullWhen(true)] out TargetPointer? value, out string? type)
{
value = null;
type = null;
if (!_globals.TryGetValue(name, out (ulong Value, string? Type) global))
return false;

type = global.Type;
value = new TargetPointer(global.Value);
return true;
}

public override TargetPointer ReadGlobalPointer(string name)
=> ReadGlobalPointer(name, out _);

Expand Down
28 changes: 28 additions & 0 deletions src/native/managed/cdacreader/tests/TestPlaceholderTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ public override bool IsAlignedToPointerSize(TargetPointer pointer)
return (pointer.Value & (ulong)(PointerSize - 1)) == 0;
}

public override bool TryReadGlobalPointer(string name, [NotNullWhen(true)] out TargetPointer? value)
{
value = null;
foreach (var global in _globals)
{
if (global.Name == name)
{
value = new TargetPointer(global.Value);
return true;
}
}
return false;
}

public override TargetPointer ReadGlobalPointer(string name)
{
foreach (var global in _globals)
Expand Down Expand Up @@ -93,6 +107,20 @@ public override string ReadUtf16String(ulong address)
}

public override TargetNUInt ReadNUInt(ulong address) => DefaultReadNUInt(address);

public override bool TryReadGlobal<T>(string name, [NotNullWhen(true)] out T? value)
{
value = default;
foreach (var global in _globals)
{
if (global.Name == name)
{
value = T.CreateChecked(global.Value);
return true;
}
}
return false;
}
public override T ReadGlobal<T>(string name)
{
foreach (var global in _globals)
Expand Down