feat(debug-files): add --il2cpp-mapping for Unity IL2CPP line mappings#1165
Conversation
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.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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.
| if (!mapping) { | ||
| return null; | ||
| } | ||
| return { mapping, debugId: object.debugId }; |
There was a problem hiding this comment.
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)
Reviewed by Cursor Bugbot for commit 9e2377d. Configure here.
There was a problem hiding this comment.
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.
Codecov Results 📊❌ Patch coverage is 76.92%. Project has 5145 uncovered lines. Files with missing lines (2)
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 +5Generated by Codecov Action |
…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.


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 separateil2cppDIF carrying the object's debug id — faithful to legacysentry-cli'screate_il2cpp_mappings.Consumes the new WASM API from
@sentry/symbolic@13.7.0(getsentry/symbolic#1005):il2cppLineMapping(object, provider)SourceBundleWriter.collectIl2cppSources(present since 13.5.0)Behavior (matches legacy)
//<source_info:File.cs:line>markers are parsed from them. Objects that yield an empty mapping are skipped.<name>.il2cppand carries the source file's debug id.--include-sources, the per-file source bundle also collects the referenced C# source files (collectIl2cppSources) — otherwise the source bundle is unchanged.--symbol-maps(BCSymbolMap resolution) remains the only deferred legacy upload option.Implementation
src/lib/dif/index.ts:createIl2cppLineMapping(data, readSource)+ acollectIl2cppSourcesoption oncreateSourceBundle().src/commands/debug-files/upload.ts:--il2cpp-mappingflag; extracted a sharedreadSourceFiledisk-reader used by both the source bundle and the IL2CPP provider.Tests
test/lib/dif/il2cpp.test.ts—createIl2cppLineMapping(mapping JSON, provider-null → null, no-markers → null) andcreateSourceBundlecollectIl2cppSources(C# included only when enabled, verified by unzipping the bundle).test/commands/debug-files/upload.test.ts—--il2cpp-mappingqueues the.il2cppDIF, absent without the flag, and is threaded through touploadDebugFiles.All text fixtures (Breakpad
FILErecords + synthetic C++/C#), no binaries.Verified locally:
typecheck,lint,test(358 debug-files/dif/scan tests),check:deps,check:fragmentsall green.