Skip to content

feat(debug-files): add --il2cpp-mapping for Unity IL2CPP line mappings#1165

Merged
BYK merged 1 commit into
mainfrom
byk/feat/debug-files-il2cpp-mapping
Jul 2, 2026
Merged

feat(debug-files): add --il2cpp-mapping for Unity IL2CPP line mappings#1165
BYK merged 1 commit into
mainfrom
byk/feat/debug-files-il2cpp-mapping

Conversation

@BYK

@BYK BYK commented Jul 2, 2026

Copy link
Copy Markdown
Member

Follows #1163 (embedded Portable PDB extraction), now merged. This PR is rebased onto main. (Re-opened from #1164, which GitHub auto-closed when its base branch was deleted on #1163's merge.)

What

Adds sentry debug-files upload --il2cpp-mapping: for each prepared debug file it computes a Unity IL2CPP C++→C# line mapping (from the file's primary debug-info object) and uploads it as a separate il2cpp DIF carrying the object's debug id — faithful to legacy sentry-cli's create_il2cpp_mappings.

Consumes the new WASM API from @sentry/symbolic@13.7.0 (getsentry/symbolic#1005):

  • top-level il2cppLineMapping(object, provider)
  • SourceBundleWriter.collectIl2cppSources (present since 13.5.0)

Behavior (matches legacy)

  • The generated C++ source files an object references are read from disk via a provider; IL2CPP //<source_info:File.cs:line> markers are parsed from them. Objects that yield an empty mapping are skipped.
  • The mapping DIF is named <name>.il2cpp and carries the source file's debug id.
  • When combined with --include-sources, the per-file source bundle also collects the referenced C# source files (collectIl2cppSources) — otherwise the source bundle is unchanged.
  • Missing/unreadable sources and mapping failures are swallowed (debug-logged), never aborting the upload.
  • --symbol-maps (BCSymbolMap resolution) remains the only deferred legacy upload option.

Implementation

  • src/lib/dif/index.ts: createIl2cppLineMapping(data, readSource) + a collectIl2cppSources option on createSourceBundle().
  • src/commands/debug-files/upload.ts: --il2cpp-mapping flag; extracted a shared readSourceFile disk-reader used by both the source bundle and the IL2CPP provider.

Tests

  • test/lib/dif/il2cpp.test.tscreateIl2cppLineMapping (mapping JSON, provider-null → null, no-markers → null) and createSourceBundle collectIl2cppSources (C# included only when enabled, verified by unzipping the bundle).
  • test/commands/debug-files/upload.test.ts--il2cpp-mapping queues the .il2cpp DIF, absent without the flag, and is threaded through to uploadDebugFiles.

All text fixtures (Breakpad FILE records + synthetic C++/C#), no binaries.

Verified locally: typecheck, lint, test (358 debug-files/dif/scan tests), check:deps, check:fragments all green.

Adds `debug-files upload --il2cpp-mapping`, which computes a Unity IL2CPP
C++→C# line mapping for each scanned object and uploads it as a separate
`il2cpp` DIF carrying the object's debug id — faithful to legacy
sentry-cli's `create_il2cpp_mappings`.

The generated C++ source files an object references are read from disk via
a provider (IL2CPP `source_info` markers are parsed from them); mappings
that come out empty are skipped. When combined with `--include-sources`,
the per-file source bundle also collects the referenced C# source files
(`SourceBundleWriter.collectIl2cppSources`).

Adds `createIl2cppLineMapping()` and a `collectIl2cppSources` option on
`createSourceBundle()` in the DIF module, consuming the top-level
`il2cppLineMapping(object, provider)` export and the `collectIl2cppSources`
setter from @sentry/symbolic 13.7.0. `--symbol-maps` remains the only
deferred legacy upload option.
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-1165/

Built to branch gh-pages at 2026-07-02 10:41 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9e2377d. Configure here.

Comment thread src/lib/dif/index.ts
if (!mapping) {
return null;
}
return { mapping, debugId: object.debugId };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IL2CPP mapping wrong object

Medium Severity

For archives with multiple debug objects, createIl2cppLineMapping always maps the first debug-info object in the file, while PreparedDif.debugId comes from the filter-matched primary. With --id targeting another slice, the uploaded .il2cpp DIF can advertise that debug id but contain line mappings for a different object.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9e2377d. Configure here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good catch — this is a real mismatch for the fat-archive + --id case. Fixed in #1166: createIl2cppLineMapping now maps the object identified by the target debug id, and the DIF is stamped with the mapped object's own id, so the id always matches the contents.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

❌ Patch coverage is 76.92%. Project has 5145 uncovered lines.
✅ Project coverage is 81.5%. Comparing base (base) to head (head).

Files with missing lines (2)
File Patch % Lines
src/commands/debug-files/upload.ts 64.29% ⚠️ 5 Missing and 1 partials
src/lib/dif/index.ts 91.67% ⚠️ 1 Missing and 1 partials
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    81.49%    81.50%    +0.01%
==========================================
  Files          399       399         —
  Lines        27744     27809       +65
  Branches     18025     18063       +38
==========================================
+ Hits         22609     22664       +55
- Misses        5135      5145       +10
- Partials      1859      1864        +5

Generated by Codecov Action

@BYK BYK merged commit 49033dc into main Jul 2, 2026
30 checks passed
@BYK BYK deleted the byk/feat/debug-files-il2cpp-mapping branch July 2, 2026 10:50
BYK added a commit that referenced this pull request Jul 2, 2026
…M handles (#1166)

Post-merge follow-ups for the `debug-files` DIF work (#1163, #1165).

## 1. `fix`: map the targeted object for `--il2cpp-mapping`

Addresses a Cursor Bugbot finding on #1165 ("IL2CPP mapping wrong
object", Medium).

For a fat archive, `createIl2cppLineMapping` mapped the first debug-info
object (`selectBundledObject` over **all** objects), while the uploaded
`.il2cpp` DIF was stamped with `file.debugId` (the **filter-matched
primary**). With `--id` targeting a non-primary slice, the DIF could
advertise one debug id while containing another object's line mappings.

- `createIl2cppLineMapping` now takes a `targetDebugId` and maps that
specific object (falling back to `selectBundledObject` when omitted/not
found).
- `appendIl2cppMapping` passes `file.debugId` and stamps the DIF with
the **mapped object's own** id — so the id always matches the contents.

Tests: added cases asserting the returned id tracks the targeted object
and the fallback path.

## 2. `perf`: free WASM archive handles after use

Addresses review finding M-1. The DIF helpers (`parseDebugFile`,
`extractEmbeddedPpdb`, `createSourceBundle`, `createIl2cppLineMapping`,
`listSources`) created `Archive`/`PeFile` WASM handles that were never
released, so a scan accumulated them (and their backing byte views) in
WASM linear memory until process exit.

- Declared each with `using` so the handle is freed on return.
- Each helper returns only plain values or copied byte buffers, so
releasing the archive is safe. Verified empirically that disposing the
archive independently of the objects derived from it does **not**
double-free (symbolic's self-cell objects own their data), including
after forcing GC.

## Verification
`typecheck`, `lint`, `check:deps`, `check:fragments`, and the full
debug-files/dif/scan suite (360 tests) all pass. No behavior change for
the common single-object case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant