Skip to content

Worker resourceLimits are not enforced while DevTools has the Debugger domain enabled #2107

Open

Description

@edusperoni

Summary

In a debug build, once a DevTools session enables the Debugger domain on a worker target, that worker's resourceLimits stop being enforced and the parent never receives the heap-limit error.

Why

WorkerWrapper::OnNearHeapLimit is registered with AddNearHeapLimitCallback in PrepareV8Runtime. It reports ERR_WORKER_OUT_OF_MEMORY to the parent and terminates the worker. V8 only invokes the most recently added near-heap-limit callback (Heap::InvokeNearHeapLimitCallback calls near_heap_limit_callbacks_.back(), src/heap/heap.cc). V8Debugger::enable adds its own callback (src/inspector/v8-debugger.cc), which shadows the worker's for as long as the Debugger domain stays enabled. That callback:

  • schedules an OOM break (BreakReason::kOOM), and
  • returns HeapLimitForDebugging(initial_heap_limit), which raises the limit well past the configured maxOldGenerationSizeMb.

So while a debugger is attached to the worker, the worker either pauses on OOM in DevTools or keeps running above its cap. Either way OnNearHeapLimit never runs: the parent gets no error event, terminate/exit never follow, and code that relies on resourceLimits to contain a runaway worker behaves differently under the debugger than without it. Detaching restores the worker's callback (V8Debugger::disable removes the debugger's).

Release builds are unaffected (no inspector), and so are debug builds with no DevTools session, or with one that never enables Debugger on the worker target.

Expected

Pausing on OOM while debugging is reasonable and matches Chrome. But after the user resumes (or if the debugger's raised limit is also exhausted), the worker should still be reported and terminated as it is without a debugger. Possible directions:

  • Re-register OnNearHeapLimit after the worker's inspector session enables Debugger, so it stays last, and decide explicitly whether to break first.
  • Or chain: keep the debugger's break, but have the worker's handler run on resume, or once the debug allowance is exhausted.

Repro (sketch)

  1. Debug build of an app with a worker created with resourceLimits: { maxOldGenerationSizeMb: 16 } whose script allocates until it runs out of memory.
  2. Without DevTools: the parent gets the heap-limit error, and the worker ends.
  3. Attach Chrome DevTools to the worker target (which enables Debugger) and rerun: no error reaches the parent. The worker pauses on OOM, or, after resuming, keeps allocating past 16 MB.

Found while reviewing #2070.

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