------------------------------------------------------------------------ r282632 | gclayton | 2016-09-28 14:07:34 -0700 (Wed, 28 Sep 2016) | 4 lines Add the ability for the task port to change when a process execs. ------------------------------------------------------------------------ Index: source/MacOSX/MachException.cpp =================================================================== --- source/MacOSX/MachException.cpp (revision 282631) +++ source/MacOSX/MachException.cpp (revision 282632) @@ -106,15 +106,30 @@ catch_mach_exception_raise(mach_port_t exc_port, m (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; } Index: source/MacOSX/MachTask.mm =================================================================== --- source/MacOSX/MachTask.mm (revision 282631) +++ source/MacOSX/MachTask.mm (revision 282632) @@ -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 a } nub_size_t MachTask::PageSize() { return m_vm_memory.PageSize(m_task); } + +void MachTask::TaskPortChanged(task_t task) +{ + m_task = task; +} Index: source/MacOSX/MachTask.h =================================================================== --- source/MacOSX/MachTask.h (revision 282631) +++ source/MacOSX/MachTask.h (revision 282632) @@ -82,6 +82,7 @@ class MachTask { 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,