Skip to content

Commit ff1f624

Browse files
fix(worker): let a heap-limit terminate re-enter the inspector lock from console.log
A worker's console.log holds inspectorMutex_ across the inspector's consoleLog, which captures a stack trace and so allocates. When that allocation hits the worker's heap cap, the near-heap-limit callback calls Terminate(), which takes the same non-recursive mutex on the same thread and deadlocks the worker. The mutex is recursive now, so that re-entry proceeds while other threads stay excluded as before.
1 parent 9b12329 commit ff1f624

2 files changed

Lines changed: 8 additions & 5 deletions

File tree

‎test-app/runtime/src/main/cpp/WorkerWrapper.cpp‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void WorkerWrapper::Terminate() {
170170
// A worker paused at a breakpoint sits in the inspector's nested pause
171171
// loop, not in Looper.loop() - kick it loose so TerminateExecution and
172172
// the looper quit below can take effect.
173-
std::lock_guard<std::mutex> lock(inspectorMutex_);
173+
std::lock_guard<std::recursive_mutex> lock(inspectorMutex_);
174174
if (inspector_ != nullptr) {
175175
inspector_->NotifyTerminating();
176176
}
@@ -810,7 +810,7 @@ void WorkerWrapper::CreateInspector(Isolate* isolate) {
810810

811811
auto* client = new WorkerInspectorClient(workerId_, isolate, ALooper_forThread(), url);
812812
{
813-
std::lock_guard<std::mutex> lock(inspectorMutex_);
813+
std::lock_guard<std::recursive_mutex> lock(inspectorMutex_);
814814
inspector_ = client;
815815
}
816816

@@ -822,7 +822,7 @@ void WorkerWrapper::CreateInspector(Isolate* isolate) {
822822
void WorkerWrapper::DestroyInspector() {
823823
WorkerInspectorClient* client = nullptr;
824824
{
825-
std::lock_guard<std::mutex> lock(inspectorMutex_);
825+
std::lock_guard<std::recursive_mutex> lock(inspectorMutex_);
826826
client = inspector_;
827827
inspector_ = nullptr;
828828
}
@@ -843,7 +843,7 @@ void WorkerWrapper::DestroyInspector() {
843843

844844
void WorkerWrapper::ConsoleLog(v8_inspector::ConsoleAPIType method,
845845
const std::vector<Local<Value>>& args) {
846-
std::lock_guard<std::mutex> lock(inspectorMutex_);
846+
std::lock_guard<std::recursive_mutex> lock(inspectorMutex_);
847847
if (inspector_ != nullptr) {
848848
inspector_->consoleLog(method, args);
849849
}

‎test-app/runtime/src/main/cpp/WorkerWrapper.h‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,10 @@ class WorkerWrapper : public std::enable_shared_from_this<WorkerWrapper> {
238238
void DestroyInspector();
239239

240240
WorkerInspectorClient* inspector_ = nullptr;
241-
std::mutex inspectorMutex_;
241+
// Recursive: ConsoleLog holds it across consoleLog, whose stack capture
242+
// allocates, and a near-heap-limit callback raised by that allocation
243+
// calls Terminate(), which takes it again on the same thread.
244+
std::recursive_mutex inspectorMutex_;
242245
#endif
243246

244247
static std::mutex registryMutex_;

0 commit comments

Comments
 (0)