Re: gdb on macOS 10.12 "Sierra"

Jason Molenda <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <[email protected]>
Hi Jonas, there was a change in macOS 10.12.1 that may be impacting gdb.  After an exec, you need to refresh the task port that gdb uses in its mach calls.  You can see the lldb change here:

http://llvm.org/viewvc/llvm-project?view=revision&revision=282632

or



I skimmed this email thread and someone said that disabling launch-with-shell worked around the issue.  That would be in line with this OS change.


Jason

> On Oct 31, 2016, at 4:54 AM, Jonas Maebe <[email protected]> wrote:
> 
> Tristan Gingold wrote:
>>> On 01 Oct 2016, at 14:08, Jonas Maebe <[email protected]> wrote:
>>> 
>>> Has anyone succeeded yet in getting gdb to work on macOS 10.12? Reportedly, it works when you disable SIP (which is understandable, given https://developer.apple.com/library/content/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html ), but plain code signing no longer seems to cut it.
>> 
>> No, I haven't tried yet.  Did you investigate if lldb has updated its build instructions ?
> 
> I finally got time to look into this. lldb's codesigning instructions
> are at
> https://llvm.org/svn/llvm-project/lldb/trunk/docs/code-signing.txt .
> They have not been updated recently, but they do differ from gdb's.
> However, the result is exactly the same: SIG113.
> 
> I've also asked on the darwin-dev@apple list, but did not get any
> replies there.
> 
> ...
> 
> I've now tried building lldb, and regardless of whether I use the GDB or
> LLDB-style codesigning certificate to sign debugserver (lldb itself does
> not need codesigning), it works. So it seems like the problem is not
> necessarily related to codesigning per se.
> 
> 
> Jonas
patch.txt (text/plain, 3.8 KB)
------------------------------------------------------------------------
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.

<rdar://problem/28476369>

------------------------------------------------------------------------
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; i<exc_data_count; ++i)
+      g_message->exc_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; i<exc_data_count; ++i)
+        g_message->exc_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,
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.