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.
`sx build --emit-obj` keeps the DWARF-bearing object so a debugger can
step the binary, completing the deep-debug half of the trace story.
- --emit-obj flag + TargetConfig.emit_obj. Implies -O0 (DWARF only
emits at opt none/less); keeps the object at its link-time path
.sx-tmp/main.o so the binary's debug map resolves to it; skips the
Level-1 binary cache; reports the object path. macOS resolves via the
debug map -> .o; Linux carries DWARF in the binary. Build-flow only,
no runtime/codegen change.
- tests/debug_stepping_smoke.sh (3e rung 1; macOS, lldb, not in
run_examples): builds with --emit-obj, drives an lldb file:line
breakpoint, asserts resolution + a source-mapped backtrace. Passing —
proves the slice 1-2 DWARF drives real source-level stepping.
(Also normalizes the 253 .exit trailing newline from the 3c --update.)
Gates: zig build, zig build test, run_examples.sh -> 291 passed.