BBS: TELESC.NET.BR Assunto: get_all_msg_headers(): cold *_NULL fields read undefined via dot-acces De: Deucе Data: Fri, 22 May 2026 20:00:08 -0700 ----------------------------------------------------------- https://gitlab.synchro.net/main/sbbs/-/issues/1143#note_9016 **The OS split lines up with `3rdp/build/GNUmakefile:38-43` TraceMonkey is compile-in-or-not based on host OS, and the runtime opt-in is unconditional** Nice nail-down with the A/B. Walking it back into the build to surface why this divergence existed. ## Smoking gun in 3rdp/build/GNUmakefile ```makefile # OS/2 and "GNU" (HURD?) also need this, but we never plan to support them. ifneq ($(os),linux) ifneq ($(os),sunos) JS_CONFIGURE_ARGS += '--disable-tracejit' endif endif ``` `--disable-tracejit` is passed to mozjs configure on every `gmake`-built OS **except Linux and Solaris**. The Windows build path is the MSVC `.vcxproj` chain, which doesn't go through this makefile, so `JS_TRACER` ends up compiled on Windows by mozjs's own defaults. That gives: | build path | OS | `--disable-tracejit` | `JS_TRACER` in lib | symptom | |------------|-----|----------------------|--------------------|---------| | gmake | Linux | no | yes | **yes** | | gmake | Solaris | no | yes | yes (presumed, not tested) | | gmake | FreeBSD | yes | no | no | | gmake | macOS | yes | no | no (presumed) | | MSVC | Windows | n/a | yes (mozjs default) | **yes** | Which matches the three-row table in your last note exactly. So the reproduce/no-reproduce split is fully predicted by "is `JS_TRACER` in the linked `libmozjs`," with no per-compiler quirk needed. ## Runtime side `sbbsdefs.h:69` defines `JAVASCRIPT_OPTIONS = 0x810` = `JSOPTION_JIT (0x800) | JSOPTION_COMPILE_N_GO (0x10)`. That's the default options the BBS/jsexec/services pass to SpiderMonkey unless explicitly overridden. Bit 11 (`JSOPTION_JIT`) is the **TraceMonkey** opt-in. So on any build where `JS_TRACER` is compiled in, the tracer is also engaged at runtime both halves of the bug are unconditional. `JSOPTION_METHODJIT` (bit 14, 0x4000) is **not** set, so MethodJIT which has the same general shape-guarded inline-cache structure (PolyIC/MonoIC) and therefore is plausibly susceptible to the same shared-shape / conditional-resolve mispredict is dormant. Compiled in on Linux/Windows, never engaged. ## Why the prior diagnoses arrived where they did - The interpreter-`PropertyCache` writeup in my discussion-2 source-trace was right that the interpreter cache can't mis-serve the way described. We were just looking at the wrong cache. The trace recorder operates **above** the interpreter, recording a shape-guarded GETPROP across the hot `for..in` loop and replaying `undefined` for the slot that wasn't an own property on the shape-twin headers. - `666ff71ce`'s eager-resolve works because it eliminates the "present on some headers, absent on others under a shared shape" divergence the tracer is recording. The shape transitions per-header reflect actual property sets, and the trace replay slot is correct on every shape-match. So the fix is structurally sound its commit-message theory just named the wrong cache. With the recorder on, the eager-resolve is the right shape of fix; with the recorder off, it's a no-op (which is consistent with our FreeBSD runs showing zero spurious undefineds across HEAD / ca448cb8b / both-reverted). ## Candidate fix paths (your call which to take or which combination) 1. **Drop `JSOPTION_JIT` from `JAVASCRIPT_OPTIONS`** (`sbbsdefs.h:69`, change `0x810` `0x10`). Single-line, ships immediately on every build with no mozjs rebuild needed. Stops the tracer from engaging even where it's compiled in. Probe rerun against the same base should drop spurious undefineds to 0 on Linux/Windows just as it did in your `js.options = 0x10` A/B. 2. **Extend `--disable-tracejit` to all OSes** in `3rdp/build/GNUmakefile:38-43` (remove the linux/sunos exemption) and do the equivalent on the MSVC mozjs build path. Removes `JS_TRACER` from the library entirely; future rebuilds are tracer-free. Requires a one-time mozjs rebuild on Linux and Windows. 3. **Revert `ca448cb8b` + `666ff71ce`** once (1) is in place. Both are correct workarounds for a tracer that's no longer in the picture; with the tracer off the original lazy resolve hook is correct. `defer_listing`, the eager `js_get_msg_header_resolve(JSID_VOID)` call, and the regression test all become unnecessary. (Optional they're harmless if left in.) 4. **Add a comment near `JAVASCRIPT_OPTIONS`** (or wherever JIT options land) noting that `JSOPTION_METHODJIT` (bit 14) is not safe to enable without first re-running `probe_to_ext.js` / `probe_enum.js` against a real mail base MethodJIT's PolyIC is shape-guarded the same way TraceMonkey is, and the same shared-shape conditional-resolve pattern would plausibly bite it. (1) is the minimum surgical fix. (1)+(3) restores the laziness we lost. (2) is hygiene since SM-1.8.5's tracer is dead upstream and we've now demonstrated it's wrong even on the platforms the original exemption thought were OK. (4) is cheap insurance. Reproducers and binaries are still in place on the FreeBSD investigation host if you'd like any of the above validated here before merging happy to apply (1), rebuild, and rerun the probes against both the FreeBSD-local live mail base and Rob's copied base, to confirm zero spurious undefineds in both. Or against a Linux build if a peer wants to drive that side. *Authored by Claude (Claude Code), on behalf of @Deuce* --- SBBSecho 3.37-Linux * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705) ----------------------------------------------------------- [Voltar]