Skip to content

SIGSEGV: async frame slot mis-restored after await in a loop (js_object_get_field_by_name on garbage ptr; not GC) #1824

Description

@proggeramlug

Summary

A compiled Fastify + @perryts/mysql service (gscmaster-api) SIGSEGVs (exit 139, no JS error, PM2 restart) during a long-running background job that performs a large number of sequential await fetch() (HTTPS) interleaved with await mysql execute() in a single async invocation.

This looked like #1597 at first, but it is not that generational-GC bug:

So the GC fix and both GC-disable workarounds don't help — this is a distinct failure.

Shape of the workload

The job processes three "date ranges". For each range it does, for ~37 items, sequentially:

  • 2× await fetchPostWithAuth(googleapis.com, ...) (stats)
  • 1× await fetchPostWithAuth(...) (daily)
  • 4× await fetchPostWithAuth(...) (dimensions)

i.e. ~7 awaited HTTPS round-trips per item × 37 ≈ ~260 sequential await fetch() per range, each followed by await execute("INSERT ... ON DUPLICATE KEY UPDATE", ...) writing JSON blobs up to ~15 KB via @perryts/mysql.

Observed boundary: one full range completes and persists all its DB writes; the process crashes near the start of the second range (the next fetch), ~40–43 s in. One range ≈ ~260 fetches + ~230 inserts = OK; two ranges reliably crash. The crash is silent (empty stderr at the crash point; PM2 sees a restart). Reducing the work to a single range avoids it.

This points at a resource that accumulates across many sequential awaited fetch/DB calls and isn't released (sockets/connections, async frames, or similar) rather than a single offending statement — the same token/site/code path works fine for the first ~260 calls and dies on the ~261st.

Environment

  • Perry: PerryTS/perry main @ c720d2a4 (rebuilt 2026-05-25; includes fix(gc): barrier Promise pointer stores for async resumption #1715).
  • Compiled Fastify service (plain Fastify), @perryts/mysql (mysql2-compatible) pool connectionLimit: 10, await pool.execute(...).
  • fetch via the built-in fetchWithAuth / fetchPostWithAuth helpers.
  • Linux x86_64, run under PM2.

Asks

  • Is there a known cap / leak on the number of sequential fetch() (or awaited mysql execute()) in one async invocation? Any PERRY_* knob to test (e.g. fetch connection pooling)?
  • Happy to produce a trimmed standalone repro (loop of N await fetch() to a local server + N inserts) and bisect N — say the word and I'll attach it plus a core dump / PERRY_* trace if useful.

(Originally mis-attributed to #1597 — corrected: that fix and PERRY_GEN_GC=0 both leave this crash in place, so filing separately.)

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