Skip to content

[Diagnostics] InProc CrashReporter Deferred Symbolication#128937

Open
mdh1418 wants to merge 1 commit into
dotnet:mainfrom
mdh1418:inproc_crashreport_compact
Open

[Diagnostics] InProc CrashReporter Deferred Symbolication#128937
mdh1418 wants to merge 1 commit into
dotnet:mainfrom
mdh1418:inproc_crashreport_compact

Conversation

@mdh1418
Copy link
Copy Markdown
Member

@mdh1418 mdh1418 commented Jun 3, 2026

Compact, tombstone-style frames for the in-proc crash reporter (deferred symbolication)

The in-proc crash reporter (mobile-only, FEATURE_INPROC_CRASHREPORT) currently writes fully-resolved managed frames — Class.Method + 0xILOFFSET (token=0xTOKEN) — to the console/logcat. On Android, logcat is byte-budgeted and rolls over oldest-first, so verbose frames evict earlier frames and can truncate the crashing stack. Android's own native tombstones address this by emitting unsymbolicated frames and leaving symbolication to an offline tool.

This change makes the console report compact by deferring symbolication: each managed frame emits only the stable identifiers an offline tool needs (module index → MVID, MethodDef token, IL offset). Human-readable names are retained in full in the JSON report, which remains the authoritative, post-mortem store.

  • Console grammar — managed frames are now emitted in a compact, greppable form, with a trailing modules: table mapping each module index to its MVID:

Before:

#NN [<moduleIndex>] Class.Method + 0xILOFFSET (token=0xTOKEN)
#NN (in <name>) Class.Method + 0xILOFFSET (token=0xTOKEN)
#NN [<moduleIndex>] 0xIP (module + 0xOFFSET)

After:

#NN [<moduleIndex>] 0xTOKEN 0xILOFFSET        (managed frame; deferred symbolication)
#NN [<moduleIndex>] 0xTOKEN                   (managed frame; IL offset unavailable)
#NN (in <name>) 0xTOKEN 0xILOFFSET            (overflow form: module didn't fit the table)
#NN [<moduleIndex>] 0xIP                      (no method token: raw IP fallback)
  • IL-offset sentinel — introduced CRASHREPORT_NO_IL_OFFSET (0xFFFFFFFF, matching the ICorDebugInfo::NO_MAPPING convention) so a genuine IL offset of 0 (a method's first instruction) stays distinguishable from "unavailable". The console emits the IL offset only when it differs from the sentinel; the JSON maps the sentinel to 0 to keep its schema byte-identical.
  • JSON report is unchanged in fidelity — it still emits method_name, class_name, token, il_offset, and filename. The compact/deferred form is the default and only console format; no environment-variable toggle is added (the names you'd want are already in the JSON).

Design / scope notes

  • The grammar uses stable markers (#NN, [N], 0x…, {MVID}) so a downstream tool can recover symbols from the token + PDB with simple regexes.
  • All emission stays on the existing async-signal-safe path (fixed scratch buffers, no allocation).
  • Mobile-only; compiles only on Android/iOS/tvOS/MacCatalyst (FEATURE_INPROC_CRASHREPORT).

Validation

  • build.cmd clr.runtime -os android -arch x64 -c Release — 0 warnings / 0 errors.
  • Exercised on the Android x64 emulator during development; compact frames + module table render as expected and the JSON retains full names

Replace the fully symbolicated managed console/logcat frame
(Namespace.Class.Method + 0xIL (token=0xTOK)) with the compact,
tombstone-like form '#NN [moduleIdx] 0x<token> 0x<il>'. Drop the
resolved method name and the process-dynamic JIT IP / native offset
from managed console lines, keeping only the stable offline keys
(module index -> MVID via the modules: table, MethodDef token, IL
offset). The line stops after the token when the IL offset is
unavailable, and a sentinel IL-offset value (CRASHREPORT_NO_IL_OFFSET)
disambiguates a genuine IL offset of 0 from a resolution failure. The
token==0 case keeps a raw 0x<IP> so dynamic-method/IL-stub frames stay
locatable. The JSON report is unchanged and remains the authoritative
store.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the in-proc crash reporter’s console/log output to use a compact “tombstone-style” managed-frame format geared toward deferred/offline symbolication, while keeping the JSON report’s managed naming data intact. It also introduces an IL-offset sentinel so an actual IL offset of 0 remains distinguishable from “unavailable” at the collection layer.

Changes:

  • Introduces CRASHREPORT_NO_IL_OFFSET (0xFFFFFFFFu) and uses it as the default IL-offset value until a native→IL mapping succeeds.
  • Changes console frame emission to print module index + MethodDef token (+ optional IL offset) instead of resolved Class.Method names, and omits native offset/address details for managed token frames.
  • Maps the IL-offset sentinel to 0 in JSON output to keep the JSON schema stable while still supporting the compact console format.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/coreclr/vm/crashreportstackwalker.cpp Initializes ilOffset with the new sentinel and preserves best-effort behavior when IL mapping fails.
src/coreclr/debug/crashreport/inproccrashreporter.h Adds CRASHREPORT_NO_IL_OFFSET constant and documents its purpose/convention.
src/coreclr/debug/crashreport/inproccrashreporter.cpp Implements compact console grammar (token/IL offset) and maps sentinel IL offset to 0 for JSON output.

Comment on lines +1516 to +1517
if (token != 0)
{
Comment on lines +65 to +68
// #NN [<moduleIndex>] 0xTOKEN 0xILOFFSET (managed frame; deferred symbolication)
// #NN [<moduleIndex>] 0xTOKEN (managed frame; IL offset unavailable)
// #NN (in <name>) 0xTOKEN 0xILOFFSET (overflow form: module didn't fit the table)
// #NN [<moduleIndex>] 0xIP (no method token: raw IP fallback)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants