@@ -318,7 +318,7 @@ std::string GetThreadState(Isolate *isolate,
318318
319319struct InterruptArgs {
320320 std::promise<JsStackTrace> promise;
321- const std::optional<AsyncLocalStorageLookup> * store;
321+ std::shared_ptr<std:: optional<AsyncLocalStorageLookup>> store;
322322};
323323
324324// Function to be called when an isolate's execution is interrupted
@@ -348,9 +348,9 @@ static void ExecutionInterrupted(Isolate *isolate, void *data) {
348348}
349349
350350// Function to capture the stack trace of a single isolate
351- JsStackTrace
352- CaptureStackTrace ( Isolate *isolate,
353- const std::optional<AsyncLocalStorageLookup> &store) {
351+ JsStackTrace CaptureStackTrace (
352+ Isolate *isolate,
353+ const std::shared_ptr<std:: optional<AsyncLocalStorageLookup> > &store) {
354354 if (isolate->IsExecutionTerminating ()) {
355355 return JsStackTrace{{}, " " };
356356 }
@@ -359,12 +359,18 @@ CaptureStackTrace(Isolate *isolate,
359359 auto future = promise.get_future ();
360360
361361 // The v8 isolate must be interrupted to capture the stack trace
362+ // Note: Even if we timeout below, the interrupt may still fire later.
363+ // The InterruptArgs holds a shared_ptr to keep data alive until the callback
364+ // executes.
362365 isolate->RequestInterrupt (ExecutionInterrupted,
363- new InterruptArgs{std::move (promise), & store});
366+ new InterruptArgs{std::move (promise), store});
364367
365368 // Wait with timeout to prevent infinite hang if isolate never processes
366369 // interrupt (e.g., stuck in native code or terminating)
367370 if (future.wait_for (std::chrono::seconds (5 )) == std::future_status::timeout) {
371+ // Timeout occurred. The InterruptArgs is intentionally leaked - it will be
372+ // deleted by ExecutionInterrupted if/when the callback eventually fires.
373+ // The shared_ptr keeps the store data alive.
368374 return JsStackTrace{{}, " " };
369375 }
370376
@@ -393,15 +399,14 @@ void CaptureStackTraces(const FunctionCallbackInfo<Value> &args) {
393399 // from map
394400 auto async_store_ptr = thread_info.async_store ;
395401
396- futures.emplace_back (
397- std::async (std::launch::async,
398- [thread_isolate, thread_name, poll_state,
399- async_store_ptr]() -> ThreadResult {
400- return ThreadResult{
401- thread_name,
402- CaptureStackTrace (thread_isolate, *async_store_ptr),
403- poll_state};
404- }));
402+ futures.emplace_back (std::async (
403+ std::launch::async,
404+ [thread_isolate, thread_name, poll_state,
405+ async_store_ptr]() -> ThreadResult {
406+ return ThreadResult{
407+ thread_name, CaptureStackTrace (thread_isolate, async_store_ptr),
408+ poll_state};
409+ }));
405410 }
406411 }
407412
0 commit comments