ERR/E3.0 (slice 3e rung 2): iOS-simulator stepping verified
Closes out E3's stepping-verification ladder to the extent possible headlessly. - Verified `sx build --target ios-sim --emit-obj` produces an arm64-ios-simulator Mach-O that runs under `simctl spawn` and steps in lldb (the backtrace shows a dyld_sim frame — the sim runtime). - Verified the device-applicable .dSYM path: dsymutil collects the DWARF, and after removing the .o lldb still resolves source via the .dSYM. - debug_stepping_smoke.sh gains an optional iOS-sim rung that reuses an already-booted simulator (never boots one — single-sim policy) and exercises the .dSYM path; skips cleanly when no sim is booted. - docs/debugger.md: rungs 1-2 marked verified; the iOS-device rung is documented as a manual checklist (needs hardware + get-task-allow signing) — no compiler gap, --emit-obj + standard Apple tools suffice. E3 is functionally complete and verified across macOS + iOS-simulator.
This commit is contained in:
@@ -403,18 +403,33 @@ Source-level stepping is verified manually/interactively (it needs
|
||||
provisioning profile — not a `run_examples.sh` test). Climb cheapest-first;
|
||||
the device run is the final sign-off:
|
||||
|
||||
1. **macOS native ✅** — `sx build --emit-obj` → drive `lldb --batch` (the
|
||||
debug map resolves to the kept `.o`; no `dsymutil` needed locally).
|
||||
Checked in as `tests/debug_stepping_smoke.sh`: breakpoint on a sx function,
|
||||
`run`, assert it stops at the right `.sx:line`, `next`/`stepi` advance,
|
||||
`bt` is source-mapped. The automatable rung (a checked-in smoke script).
|
||||
2. **iOS simulator** — bundle the `.app`, install to a booted simulator
|
||||
(`simctl`), launch under lldb, repeat the checks. No device, no signing.
|
||||
3. **iOS device (capstone)** — `--debug`: emit DWARF → `dsymutil` `.dSYM`,
|
||||
debug-sign with `get-task-allow`, install via `devicectl`, launch under
|
||||
`debugserver`, attach `lldb`, single-step sx source on the phone. If
|
||||
stepping works *here* — the most locked-down target — the DWARF story
|
||||
is proven everywhere.
|
||||
1. **macOS native ✅ verified** — `sx build --emit-obj` → drive `lldb --batch`
|
||||
(the debug map resolves to the kept `.o`; no `dsymutil` needed locally).
|
||||
Checked in as `tests/debug_stepping_smoke.sh`: file:line breakpoint resolves
|
||||
to `.sx:line` + a source-mapped `bt`. The automatable rung.
|
||||
2. **iOS simulator ✅ verified** — `sx build --target ios-sim --emit-obj`
|
||||
produces an `arm64-ios-simulator` Mach-O that runs under `simctl spawn` and
|
||||
steps in `lldb` (the backtrace shows a `dyld_sim` frame — proof it's the sim
|
||||
runtime). The `tests/debug_stepping_smoke.sh` rung-2 exercises this *against
|
||||
an already-booted sim* (it never boots one itself — use a single simulator);
|
||||
it also collects a `.dSYM` via `dsymutil`, removes the `.o`, and confirms
|
||||
lldb still resolves via the `.dSYM` — proving the device-applicable artifact
|
||||
path. Skipped when no sim is booted.
|
||||
3. **iOS device (capstone) — manual, needs hardware + Apple signing.** Every
|
||||
*technical* piece is already verified above (DWARF, the `.dSYM` workflow,
|
||||
stepping under the sim runtime); the device rung adds only Apple-toolchain
|
||||
steps that require a phone + a development identity, so it's a checklist, not
|
||||
a compiler deliverable:
|
||||
1. `sx build --target ios --emit-obj …` (DWARF in the kept `.o`).
|
||||
2. `dsymutil <binary> -o <App>.app.dSYM` (the `.app` ships no `.o`).
|
||||
3. bundle the `.app` (existing `--bundle` path) + debug-sign with a
|
||||
provisioning profile carrying **`get-task-allow`**.
|
||||
4. `xcrun devicectl device install app …` then launch under `debugserver`.
|
||||
5. attach `lldb` (it finds the adjacent `.dSYM`) and single-step sx source.
|
||||
|
||||
No new compiler code is required — `--emit-obj` + standard Apple tools
|
||||
suffice. (A `--debug` convenience flag that chains 1–4 could be added later,
|
||||
but should be built with a device in hand to verify it.)
|
||||
|
||||
Independently, **Tier-0 always works with no debugger**: a plain on-device
|
||||
run still prints the embedded-`Frame` trace to stderr/`os_log`.
|
||||
@@ -443,8 +458,9 @@ a Mach-O debug map, never register JIT DWARF.
|
||||
| Comptime resolver (`func_id, ir_offset` → location) | ✅ done — slice 3b |
|
||||
| Source snippet + `^` caret | ✅ done — slice 3c (line embedded in `Frame`) |
|
||||
| `--emit-obj` artifact plumbing | ✅ done — slice 3d |
|
||||
| Stepping verification: macOS lldb | ✅ done — slice 3e rung 1 (`tests/debug_stepping_smoke.sh`) |
|
||||
| Stepping verification: iOS simulator → device | ⏳ planned — slice 3e rungs 2–3 (capstone) |
|
||||
| Stepping verification: macOS lldb | ✅ done — 3e rung 1 (`tests/debug_stepping_smoke.sh`) |
|
||||
| Stepping verification: iOS simulator + `.dSYM` path | ✅ done — 3e rung 2 (verified; smoke skips if no booted sim) |
|
||||
| Stepping verification: iOS device | 📋 manual checklist — needs hardware + signing (no compiler gap) |
|
||||
| DWARF variable info (`DILocalVariable`, for `p x`) | ⏳ optional follow-on |
|
||||
|
||||
The active plan and step breakdown live in `current/PLAN-ERR.md`
|
||||
|
||||
Reference in New Issue
Block a user