https://github.com/jasonmolenda created 
https://github.com/llvm/llvm-project/pull/70979

MachProcess has a MachTask as an ivar.  In the MachProcess dtor, we call 
MachTask::Clear() to clear its state, before running the dtor of all our ivars, 
including the MachTask one.

When we attach on darwin, MachProcess calls MachTask::StartExceptionThread 
which does the task_for_pid and then starts a thread to listen for mach 
messages.  Then MachProcess calls ptrace(PT_ATTACHEXC).  If that ptrace() 
fails, MachProcess will call MachTask::Clear.  But the exception thread is now 
up & running and is not stopped; its ivars will be reset by the Clear() method, 
and its object will be freed after the dtor runs.

Actually eliciting a crash in this scenario is very timing sensitive; I 
hand-modified debugserver to fail to PT_ATTACHEXC trying to simulate it on my 
desktop and was unable.  But looking at the source, and an occasional crash 
report we've received, it's clear that this is possible.

rdar://117521198

>From 027e2ce8fcad6f1d6f5776033a938e34156cfaa7 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmole...@apple.com>
Date: Wed, 1 Nov 2023 13:25:55 -0700
Subject: [PATCH] [lldb] [debugserver] Shut down the exception thread when
 clearing

MachProcess has a MachTask as an ivar.  In the MachProcess dtor,
we call MachTask::Clear() to clear its state, before running the
dtor of all our ivars, including the MachTask one.

When we attach on darwin, MachProcess calls MachTask::StartExceptionThread
which does the task_for_pid and then starts a thread to listen for
mach messages.  Then MachProcess calls ptrace(PT_ATTACHEXC).  If
that ptrace() fails, MachProcess will call MachTask::Clear.  But
the exception thread is now up & running and is not stopped; its
ivars will be reset by the Clear() method, and its object will be
freed after the dtor runs.

Actually eliciting a crash in this scenario is very timing sensitive;
I hand-modified debugserver to fail to PT_ATTACHEXC trying to simulate
it on my desktop and was unable.  But looking at the source, and an
occasional crash report we've received, it's clear that this is
possible.

rdar://117521198
---
 lldb/tools/debugserver/source/MacOSX/MachTask.mm | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.mm 
b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
index 4f5b4039243f662..fd2ac64ac6cf79c 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
@@ -145,6 +145,8 @@
 //----------------------------------------------------------------------
 void MachTask::Clear() {
   // Do any cleanup needed for this task
+  if (m_exception_thread)
+    ShutDownExcecptionThread();
   m_task = TASK_NULL;
   m_exception_thread = 0;
   m_exception_port = MACH_PORT_NULL;

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to