Skip to content

libc++ hardening assertion from V8 aborts cargo test --lib, seen once #3

Description

@max-lt

cargo test --lib aborted once with four simultaneous libc++ hardening assertions from V8's C++ side:

vector.h:415: libc++ Hardening assertion __n < size() failed: vector[] index out of bounds
vector.h:415: libc++ Hardening assertion __n < size() failed: vector[] index out of bounds
vector.h:415: libc++ Hardening assertion __n < size() failed: vector[] index out of bounds
vector.h:415: libc++ Hardening assertion __n < size() failed: vector[] index out of bounds

error: test failed, to rerun pass `--lib`
Caused by:
  process didn't exit successfully: .../openworkers_runtime_v8-0ca5553e5df70fbf (signal: 6, SIGABRT)

Why this is worth a ticket

The assertion is libc++'s bounds check on std::vector::operator[], compiled into the V8 build. It is a real out-of-bounds index, not a Rust panic. Hardening is off in a release build of V8, so the same access there reads or writes past the end silently.

Four assertions at once, one per test thread, points at shared state rather than at one test.

What is not the cause

The last line printed before the abort was test gc::tests::test_gc_traceable_nested_vec ... ok, which is misleading: that test only measures Vec capacities and never touches V8. It was simply the last thread to report.

The tests that do touch V8 and were in flight at that moment live in src/locker_managed_isolate.rs (3), src/pool.rs (7) and src/icudata.rs (5). locker_managed_isolate.rs:45 calls crate::platform::get_platform() and then builds isolates; pool.rs builds and caches them. Platform init itself is behind a OnceLock (src/platform.rs:9), so the suspect is concurrent isolate creation and Locker use across test threads, not the one-time setup.

Reproduction

Seen once. Not reproduced in eight later runs of the same suite on the same machine, in both default and --test-threads=1 mode, with and without the changes that were in flight at the time. No CI runs this suite, so there is no second data point.

Environment

crate openworkers-runtime-v8 0.15.12
V8 openworkers-v8 152.2.0
rustc 1.97.1 (8bab26f4f 2026-07-14)
platform macOS 26.5.1, arm64

Note src/platform.rs:31 sets --single-threaded-gc on macOS only, so a Linux run exercises a different GC path and may or may not show this.

Suggested next steps

  • Loop the suite (for i in $(seq 50); do cargo test --lib || break; done) to get a second occurrence and a core file.
  • Compare default threads against --test-threads=1; if it only happens in parallel, that narrows it to shared isolate or platform state.
  • lldb on the core to name the frame inside V8, which the assertion text alone does not give.
  • Consider whether the isolate-creating unit tests should serialize on a mutex the way ONESHOT_GUARD does in task_executor, if it turns out that concurrent creation is the trigger.

Activity

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