Skip to content

toolchain: auto-optimize links perry_ext_events against a trimmed runtime — undefined panic_fmt / __rust_alloc_error_handler on a cold object cache (ext-zlib #6847 in a second provider) #6966

Description

@proggeramlug

Summary

On a cold object cache, auto-optimize links the perry_ext_events provider archive against a
feature-stripped/trimmed runtime that no longer supplies Rust's panic and alloc-error machinery, so
the link fails:

Undefined symbols for architecture arm64:
  "__RNvNtCs6sq8b9ugfBC_4core9panicking9panic_fmt", referenced from:
      ... in __libperry_ext_events.a_nosharedeps.lib_trimmed.lib[47](core-….rcgu.o)
  "__RNvNtCs6sq8b9ugfBC_4core9panicking18panic_nounwind_fmt", referenced from:
      ... in __libperry_ext_events.a_nosharedeps.lib_trimmed.lib[47](core-….rcgu.o)
  "__RNvCsGIExRX8pES_7___rustc26___rust_alloc_error_handler", referenced from:
      __RNvNtCs8dnTdrJsiec_5alloc5alloc18handle_alloc_error in __libperry_ext_events.a_nosharedeps.lib_trimmed.lib[46](alloc-….rcgu.o)
ld: symbol(s) not found for architecture arm64
Error: Linking failed

Referencing symbols come from perry_ext_events::EventEmitterHandle::{add_listener, emit_meta_event},
event_name_from_bits, event_emitter_once_wrapper.

This is the ext-zlib bug (#6847) in a second provider

#6847 records exactly this shape for ext-zlib (js_zlib_deflate_raw_sync + panic_unwind
undefined on a cold object cache, masked by warm /tmp caches). This is the same mechanism in
ext-events. Filing separately per the granular-issue convention rather than widening #6847.

Reproduction — variable isolated

Same compiler binary, same source, only auto-optimize toggled:

test PERRY_NO_AUTO_OPTIMIZE=1 default (auto-opt)
test_gap_6316_native_base_override exit 0, executable written exit 1, link failure above
test_gap_6326_indirect_native_base exit 0 exit 1, libperry_ext_events
test_gap_6343_scalar_native_base_surface exit 0 exit 1, libperry_ext_events

Because codegen is held constant across the two arms, this is a link/packaging defect, not a
codegen or parity regression.

Host: quiet 8-core arm64 mini, release build, PERRY_RUNTIME_DIR pinned to the same
target/release.

Why it surfaced now

Cold cache. #6847's own note applies verbatim — "warm /tmp caches mask it, which is how it went
unnoticed." These three tests passed a sweep on this branch before the machine's caches were
cleared during a disk crunch, and failed the sweep afterwards with no code change in between.

That is the part worth fixing beyond the skip entry: the gap gate's verdict currently depends on
object-cache temperature.
A contributor with a warm cache and a contributor with a clean checkout
get different answers from the same commit.

Impact beyond CI

perry_ext_events backs EventEmitter paths, so this is not test-only: a user compiling from a clean
checkout can hit an undefined-symbol link failure that disappears after an unrelated warm build.
That is a bad first-run experience and near-impossible to self-diagnose.

Suggested handling

  1. Fix the packaging so ext provider archives are linked against a runtime that retains the panic /
    alloc-error symbols they reference (or trim them consistently).
  2. Until then, triaged known_failures.json entries for the three tests above, category: toolchain,
    pointing at this issue — matching how auto-opt: ext-zlib provider link failure on cold object cache (undefined js_zlib_deflate_raw_sync + panic_unwind symbols) #6847 was handled.

Found while sweeping PR #6925 (repsel Phase 5a). Not attributable to that PR; see the isolation table.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions