Problem
Found while tracing #242: once a js-debug child target dies mid-adoption, every remaining adoption step runs to its full timeout against a dead client instead of aborting. None of these hang start_debugging anymore (#242 fixed the barrier), but they keep the worker busy long after the debuggee is gone and delay teardown.
Specifics (all in src/proxy/child-session-manager.ts unless noted):
attachChild (:346-369): 20 retries × 20s per-request timeout + 200ms sleeps — worst case ~400s — with all errors swallowed, no death check, no total deadline. A dead socket collapses to ~4s (sync throws), but a live js-debug socket that simply never answers attach for a vanished pending target burns the full ~400s.
waitForEvent (:459-490) resolves false on timeout only and never observes client death; ensureChildStopped (15s + 5s threads + 30s pause), initializeChild (12s), handlePostAttachInit (3s) all burn their full windows once the child is gone.
- The
close handler (:447-453) clears activeChild/childSessions but does not abort an in-flight createChildSession — the remaining steps keep running against a dead client.
ChildSessionManager.shutdown() (:502-517) is never called from src/; MinimalDapClient.shutdown() only iterates children registered via childCreated (adoption success), so a child socket created mid-adoption is orphaned at worker shutdown.
Suggested direction
Thread a death signal (client close/error, or an AbortSignal) through createChildSession so each step (and the attachChild retry loop) bails immediately when the child dies; register the child socket for shutdown at creation time, not adoption success; give attachChild a total deadline.
Problem
Found while tracing #242: once a js-debug child target dies mid-adoption, every remaining adoption step runs to its full timeout against a dead client instead of aborting. None of these hang
start_debugginganymore (#242 fixed the barrier), but they keep the worker busy long after the debuggee is gone and delay teardown.Specifics (all in
src/proxy/child-session-manager.tsunless noted):attachChild(:346-369): 20 retries × 20s per-request timeout + 200ms sleeps — worst case ~400s — with all errors swallowed, no death check, no total deadline. A dead socket collapses to ~4s (sync throws), but a live js-debug socket that simply never answersattachfor a vanished pending target burns the full ~400s.waitForEvent(:459-490) resolvesfalseon timeout only and never observes client death;ensureChildStopped(15s + 5sthreads+ 30spause),initializeChild(12s),handlePostAttachInit(3s) all burn their full windows once the child is gone.closehandler (:447-453) clearsactiveChild/childSessionsbut does not abort an in-flightcreateChildSession— the remaining steps keep running against a dead client.ChildSessionManager.shutdown()(:502-517) is never called fromsrc/;MinimalDapClient.shutdown()only iterates children registered viachildCreated(adoption success), so a child socket created mid-adoption is orphaned at worker shutdown.Suggested direction
Thread a death signal (client
close/error, or anAbortSignal) throughcreateChildSessionso each step (and theattachChildretry loop) bails immediately when the child dies; register the child socket for shutdown at creation time, not adoption success; giveattachChilda total deadline.