Skip to content

PERRY_NO_AUTO_OPTIMIZE: importing node:http makes String.prototype.match segfault in mi_free (stdlib rebuilt without the runtime) #11240

Description

@proggeramlug

Summary

With PERRY_NO_AUTO_OPTIMIZE=1, a program that imports node:http and then calls String.prototype.match segfaults inside mi_free. It dies deterministically on the first regex match. The same program with node:net instead of node:http runs fine, and so does the same program without the import.

Repro (no packages)

// m3.ts
import http from "node:http";
console.log(typeof http.request);
console.log("abc".match(/b/)?.[0]);
cargo build --release -p perry -p perry-runtime-static -p perry-stdlib-static \
  -p perry-ext-net -p perry-ext-http -p perry-ext-zlib -p perry-ext-events   # one invocation
PERRY_KEEP_SYMBOLS=1 PERRY_NO_AUTO_OPTIMIZE=1 PERRY_RUNTIME_DIR=$PWD/target/release \
  target/release/perry compile m3.ts -o m3 && ./m3

Node 26.5.1 prints function then b. Perry prints function and then gets SIGSEGV (exit 139), 3 of 3 runs:

#0  mi_free ()
#1  perry_runtime::symbol::well_known_symbol ()
#2  perry_runtime::exception::arm_trap_and_run::invoke::<perry_runtime::regex::perex_dispatch::get_symbol::{closure#0}, f64> ()
#3  perry_sjlj_try ()
#4  perry_runtime::exception::catch_js_throw::<f64, perry_runtime::regex::perex_dispatch::get_symbol::{closure#0}> ()
#5  perry_runtime::regex::perex_dispatch::get_symbol ()
#6  perry_runtime::regex::perex_match_search::string ()
#7  js_string_match_js ()
#8  main ()

Controls:

program no-auto result
"abc".match(/b/) alone OK
import net from "node:net" + match OK
import http from "node:http" + match SIGSEGV

Reproduced on perrymaster (linux-x64), on main @ 19e7d4a plus #11235, and on main plus the mongodb binding removal branch. The mongodb change is not involved.

Likely mechanism (not verified)

The compile log shows that only the http case takes the extra step:

well-known (no-auto): routing `http` → target/release/libperry_ext_http.a
http-client-pump (no-auto): rebuilding stdlib (external-http-client-pump) + perry-ext-http together

optimized_libs/no_auto.rs runs that rebuild as cargo build --release -p perry-stdlib-static -p perry-ext-http --features perry-stdlib/external-http-client-pump into target/perry-no-auto-http-pump/. perry-runtime-static is not in that invocation, so cargo can unify perry-runtime's features differently from the target/release/libperry_runtime.a that ends up in the same link. alloc-mimalloc is in perry-runtime's default features, and perry-runtime-static enables perry-runtime/default, so it is a feature that can differ between the two invocations. A mi_free on a pointer that was not allocated by mimalloc, reached from runtime code, fits an allocator split across the two archives. The existing link guard compares tokio compilations across archives (#10671, #507), but nothing compares the runtime's feature set.

Impact

A no-auto build of a program that pulls in node:http crashes on its first regex match. That includes the npm mongodb driver compiled from source: ConnectionString's constructor calls String.prototype.match on the URI inside new MongoClient(...). The auto-optimize build of the mongodb CRUD fixture links and matches Node byte for byte.

Activity

  1. proggeramlug commented on Sep 24, 2026

    @proggeramlug
    ContributorAuthor

    Possibly already fixed by #11226 (merged; Fixes #11174). With auto-optimize off, importing http rebuilt the stdlib without selecting perry-runtime in the same cargo invocation, so the runtime's default engines were dropped. That is the same cause suspected here. Needs a re-check on current main before anyone works on it.

  2. proggeramlug commented on Sep 25, 2026

    @proggeramlug
    ContributorAuthor

    Fixed by #11226. Re-checked on current main by the #11263 agent: the repro matches Node.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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