Skip to content
Draft
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
58 changes: 45 additions & 13 deletions src/coreclr/debug/crashreport/inproccrashreporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ class ThreadEnumerationContext
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset,
const char* genericArgs,
void* ctx);

private:
Expand All @@ -312,7 +313,8 @@ class ThreadEnumerationContext
const GUID* moduleGuid,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset);
uint32_t ilOffset,
const char* genericArgs);

void EndCurrentConsoleThreadBlock();
void EndCurrentJsonThreadBlock();
Expand Down Expand Up @@ -500,7 +502,8 @@ class CrashReportHelpers
const GUID* moduleGuid,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset);
uint32_t ilOffset,
const char* genericArgs);

static void WriteFrameToConsole(
SignalSafeConsoleWriter* consoleWriter,
Expand All @@ -514,7 +517,8 @@ class CrashReportHelpers
const char* fallbackModuleName,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset);
uint32_t ilOffset,
const char* genericArgs);

static void WriteStackOverflowFrameToJson(
SignalSafeJsonWriter* writer,
Expand Down Expand Up @@ -568,6 +572,7 @@ class CrashReportHelpers
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset,
const char* genericArgs,
void* ctx);

static void WriteFrameToReport(
Expand All @@ -583,7 +588,8 @@ class CrashReportHelpers
const GUID* moduleGuid,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset);
uint32_t ilOffset,
const char* genericArgs);

static bool WriteToFile(
int fd,
Expand Down Expand Up @@ -1417,7 +1423,8 @@ CrashReportHelpers::WriteFrameToJson(
const GUID* moduleGuid,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset)
uint32_t ilOffset,
const char* genericArgs)
{
if (writer == nullptr)
{
Expand Down Expand Up @@ -1447,6 +1454,14 @@ CrashReportHelpers::WriteFrameToJson(
writer->WriteHexAsString("token", token);
writer->WriteHexAsString("il_offset", ilOffset);
}
// Generic instantiation arguments cannot be recovered off-device from the
// token + PDB (instantiations are a runtime construct, not metadata), so
// record them here alongside the deferred keys to keep the JSON report a
// complete, self-describing store.
if (genericArgs != nullptr && genericArgs[0] != '\0')
{
writer->WriteString("generic_args", genericArgs);
}
if (HasModuleName(moduleName))
{
writer->WriteString("filename", moduleName);
Expand Down Expand Up @@ -1492,7 +1507,8 @@ CrashReportHelpers::WriteFrameToConsole(
const char* fallbackModuleName,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset)
uint32_t ilOffset,
const char* genericArgs)
{
if (consoleWriter == nullptr)
{
Expand Down Expand Up @@ -1534,6 +1550,14 @@ CrashReportHelpers::WriteFrameToConsole(
consoleWriter->AppendStr(" (token=0x");
consoleWriter->AppendHex(static_cast<uint64_t>(token));
consoleWriter->AppendChar(')');
// Generic instantiation arguments travel inline because they cannot be
// recovered off-device from the token + PDB. Format: "<classArgs;methodArgs>"
// (value-type args exact; reference-type args show as System.__Canon).
if (genericArgs != nullptr && genericArgs[0] != '\0')
{
consoleWriter->AppendChar(' ');
consoleWriter->AppendStr(genericArgs);
}
}
else if (token != 0 && HasModuleName(fallbackModuleName))
{
Expand Down Expand Up @@ -1730,6 +1754,7 @@ CrashReportHelpers::WriteFrame(
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset,
const char* genericArgs,
void* ctx)
{
FrameContext* frameContext = reinterpret_cast<FrameContext*>(ctx);
Expand All @@ -1751,7 +1776,8 @@ CrashReportHelpers::WriteFrame(
moduleGuid,
nativeOffset,
token,
ilOffset);
ilOffset,
genericArgs);
}

void
Expand All @@ -1768,7 +1794,8 @@ CrashReportHelpers::WriteFrameToReport(
const GUID* moduleGuid,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset)
uint32_t ilOffset,
const char* genericArgs)
{
if (frameContext == nullptr)
{
Expand Down Expand Up @@ -1796,7 +1823,8 @@ CrashReportHelpers::WriteFrameToReport(
methodNameBuffer,
methodNameBufferSize,
ip, stackPointer, methodName, className, moduleName,
moduleTimestamp, moduleSize, moduleGuid, nativeOffset, token, ilOffset);
moduleTimestamp, moduleSize, moduleGuid, nativeOffset, token, ilOffset,
genericArgs);

bool consoleCapped = frameLimitPerThread != 0 &&
frameIndex >= frameLimitPerThread;
Expand All @@ -1817,7 +1845,7 @@ CrashReportHelpers::WriteFrameToReport(
methodNameBuffer,
methodNameBufferSize,
frameIndex, moduleIndex, ip, methodName, className, moduleName,
nativeOffset, token, ilOffset);
nativeOffset, token, ilOffset, genericArgs);
}
else if (currentThreadDroppedCount != nullptr)
{
Expand All @@ -1843,7 +1871,8 @@ ThreadEnumerationContext::OnFrame(
const GUID* moduleGuid,
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset)
uint32_t ilOffset,
const char* genericArgs)
{
CrashReportHelpers::WriteFrameToReport(
&m_frameContext,
Expand All @@ -1858,7 +1887,8 @@ ThreadEnumerationContext::OnFrame(
moduleGuid,
nativeOffset,
token,
ilOffset);
ilOffset,
genericArgs);
}

void
Expand All @@ -1875,6 +1905,7 @@ ThreadEnumerationContext::FrameCallback(
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset,
const char* genericArgs,
void* ctx)
{
if (ctx == nullptr)
Expand All @@ -1893,7 +1924,8 @@ ThreadEnumerationContext::FrameCallback(
moduleGuid,
nativeOffset,
token,
ilOffset);
ilOffset,
genericArgs);
}

void
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/debug/crashreport/inproccrashreporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ using InProcCrashReportFrameCallback = void (*)(
uint32_t nativeOffset,
uint32_t token,
uint32_t ilOffset,
// Generic instantiation arguments for this frame's method, pre-formatted by
// the VM-side walker as "<classArgs;methodArgs>" (empty/null when the method
// is non-generic). Generic instantiations are a runtime construct absent from
// metadata, so they cannot be recovered off-device from the token + PDB and
// must travel with the frame. Value-type args are exact; reference-type args
// collapse to System.__Canon under shared generics.
const char* genericArgs,
void* ctx);

using InProcCrashReportWalkStackCallback = void (*)(
Expand Down
Loading
Loading