From 7ae1a67ed9d3d26ecf30279907e267f546eb43d3 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Wed, 28 Sep 2016 21:07:34 +0000 Subject: [PATCH] Add the ability for the task port to change when a process execs. llvm-svn: 282632 --- .../test/functionalities/exec/TestExec.py | 1 - .../source/MacOSX/MachException.cpp | 21 ++++++++++++++++--- .../debugserver/source/MacOSX/MachTask.h | 1 + .../debugserver/source/MacOSX/MachTask.mm | 15 +++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py b/lldb/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py index e89d99c21beb..98b002eb288b 100644 --- a/lldb/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py +++ b/lldb/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py @@ -27,7 +27,6 @@ class ExecTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) @skipUnlessDarwin - @expectedFailureAll(oslist=["macosx"], bugnumber="rdar://28476369") def test(self): if self.getArchitecture() == 'x86_64': source = os.path.join(os.getcwd(), "main.cpp") diff --git a/lldb/tools/debugserver/source/MacOSX/MachException.cpp b/lldb/tools/debugserver/source/MacOSX/MachException.cpp index 09849312fbb7..f6e778232b82 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachException.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachException.cpp @@ -106,15 +106,30 @@ catch_mach_exception_raise(mach_port_t exc_port, mach_port_t thread_port, (uint64_t)(exc_data_count > 0 ? exc_data[0] : 0xBADDBADD), (uint64_t)(exc_data_count > 1 ? exc_data[1] : 0xBADDBADD)); } + g_message->exc_type = 0; + g_message->exc_data.clear(); if (task_port == g_message->task_port) { g_message->task_port = task_port; g_message->thread_port = thread_port; g_message->exc_type = exc_type; - g_message->exc_data.resize(exc_data_count); - ::memcpy(&g_message->exc_data[0], exc_data, - g_message->exc_data.size() * sizeof(mach_exception_data_type_t)); + for (mach_msg_type_number_t i=0; iexc_data.push_back(exc_data[i]); return KERN_SUCCESS; + } else if (!MachTask::IsValid(g_message->task_port)) { + // Our original exception port isn't valid anymore check for a SIGTRAP + if (exc_type == EXC_SOFTWARE && exc_data_count == 2 && + exc_data[0] == EXC_SOFT_SIGNAL && exc_data[1] == SIGTRAP) { + // We got a SIGTRAP which indicates we might have exec'ed and possibly + // lost our old task port during the exec, so we just need to switch over + // to using this new task port + g_message->task_port = task_port; + g_message->thread_port = thread_port; + g_message->exc_type = exc_type; + for (mach_msg_type_number_t i=0; iexc_data.push_back(exc_data[i]); + return KERN_SUCCESS; + } } return KERN_FAILURE; } diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h index 2fdb22f8e562..1e0e2af9a92b 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachTask.h +++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h @@ -82,6 +82,7 @@ public: bool IsValid() const; static bool IsValid(task_t task); static void *ExceptionThread(void *arg); + void TaskPortChanged(task_t task); task_t TaskPort() const { return m_task; } task_t TaskPortForProcessID(DNBError &err, bool force = false); static task_t TaskPortForProcessID(pid_t pid, DNBError &err, diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.mm b/lldb/tools/debugserver/source/MacOSX/MachTask.mm index f0f086ecbd98..37897a5a6acd 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachTask.mm +++ b/lldb/tools/debugserver/source/MacOSX/MachTask.mm @@ -867,6 +867,16 @@ void *MachTask::ExceptionThread(void *arg) { // TODO: notify of error? } else { if (exception_message.CatchExceptionRaise(task)) { + if (exception_message.state.task_port != task) { + if (exception_message.state.IsValid()) { + // We exec'ed and our task port changed on us. + DNBLogThreadedIf(LOG_EXCEPTIONS, + "task port changed from 0x%4.4x to 0x%4.4x", + task, exception_message.state.task_port); + task = exception_message.state.task_port; + mach_task->TaskPortChanged(exception_message.state.task_port); + } + } ++num_exceptions_received; mach_proc->ExceptionMessageReceived(exception_message); } @@ -984,3 +994,8 @@ nub_bool_t MachTask::DeallocateMemory(nub_addr_t addr) { } nub_size_t MachTask::PageSize() { return m_vm_memory.PageSize(m_task); } + +void MachTask::TaskPortChanged(task_t task) +{ + m_task = task; +}