public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom Tromey <tom@tromey.com>
To: Pedro Alves <palves@redhat.com>
Cc: Tom Tromey <tom@tromey.com>,  gdb-patches@sourceware.org
Subject: Re: [RFA] Fix crash in "run" on macOS when gdb is not signed
Date: Mon, 02 Jul 2018 15:33:00 -0000	[thread overview]
Message-ID: <87o9fpodos.fsf@tromey.com> (raw)
In-Reply-To: <1d40e422-08f4-30c1-de10-bd63396acb0b@redhat.com> (Pedro Alves's	message of "Fri, 29 Jun 2018 20:31:33 +0100")

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> I'd try also with "attach", see if something else needs
Pedro> cleaning up / unwinding.

Thanks.  This seemed to work fine.

Pedro> If you try this with MI as is, I think gdb will output a
Pedro> -thread-group-started notification, and then an ^error.
Pedro> You may want to call exit_inferior instead so that
Pedro> gdb outputs a matching -thread-group-exited.

Indeed; I've changed it to use exit_inferior.

Pedro> Otherwise looks fine to me.

How's this?

Tom

commit 2697c65bdfb0078c6cd60b87f16d73b25399a32c
Author: Tom Tromey <tom@tromey.com>
Date:   Thu Jun 28 11:57:39 2018 -0600

    Fix crash in "run" on macOS when gdb is not signed
    
    On macOS, when gdb is not code-signed, it will throw an exception from
    darwin_attach_pid.  However, gdb also then crashes:
    
    thread.c:93: internal-error: struct thread_info *inferior_thread(): Assertion `tp' failed.
    
    I think the problem here is that darwin_attach_pid does not clean up
    inferior_ptid and inf->pid on failure.  This leads to a situation
    where gdb tries to find a thread, but cannot.
    
    In other cases, gdb would mourn the inferior at this point; but here
    this is not possible because the target has not been pushed.  Instead
    this patch works by simply calling exit_inferior and then updating
    inferior_ptid on failure.
    
    Tested by building an unsigned gdb on macOS and trying to run an
    inferior.  I also tried this with MI, and by attaching; as suggested
    by Pedro.
    
    gdb/ChangeLog
    2018-06-28  Tom Tromey  <tom@tromey.com>
    
            PR cli/23340:
            * darwin-nat.c (darwin_attach_pid): Reset inferior and
            inferior_ptid on error.

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0f601bdbf07..e61d042aa63 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-02  Tom Tromey  <tom@tromey.com>
+
+	PR cli/23340:
+	* darwin-nat.c (darwin_attach_pid): Call exit_inferior and reset
+	inferior_ptid on error.
+
 2018-07-02  Sebastian Huber  <sebastian.huber@embedded-brains.de>
 
 	* riscv-tdep.c (riscv_register_aliases): Swap "fp" and "s0" entries.
diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 7dccce73926..38b3b765159 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -1583,77 +1583,91 @@ darwin_attach_pid (struct inferior *inf)
   darwin_inferior *priv = new darwin_inferior;
   inf->priv.reset (priv);
 
-  kret = task_for_pid (gdb_task, inf->pid, &priv->task);
-  if (kret != KERN_SUCCESS)
+  TRY
     {
-      int status;
-
-      if (!inf->attach_flag)
+      kret = task_for_pid (gdb_task, inf->pid, &priv->task);
+      if (kret != KERN_SUCCESS)
 	{
-	  kill (inf->pid, 9);
-	  waitpid (inf->pid, &status, 0);
-	}
+	  int status;
+
+	  if (!inf->attach_flag)
+	    {
+	      kill (inf->pid, 9);
+	      waitpid (inf->pid, &status, 0);
+	    }
 
-      error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
+	  error
+	    (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
 	       " (please check gdb is codesigned - see taskgated(8))"),
-             inf->pid, mach_error_string (kret), (unsigned long) kret);
-    }
+	     inf->pid, mach_error_string (kret), (unsigned long) kret);
+	}
 
-  inferior_debug (2, _("inferior task: 0x%x, pid: %d\n"),
-		  priv->task, inf->pid);
+      inferior_debug (2, _("inferior task: 0x%x, pid: %d\n"),
+		      priv->task, inf->pid);
 
-  if (darwin_ex_port == MACH_PORT_NULL)
-    {
-      /* Create a port to get exceptions.  */
-      kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
-				 &darwin_ex_port);
-      if (kret != KERN_SUCCESS)
-	error (_("Unable to create exception port, mach_port_allocate "
-		 "returned: %d"),
-	       kret);
+      if (darwin_ex_port == MACH_PORT_NULL)
+	{
+	  /* Create a port to get exceptions.  */
+	  kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
+				     &darwin_ex_port);
+	  if (kret != KERN_SUCCESS)
+	    error (_("Unable to create exception port, mach_port_allocate "
+		     "returned: %d"),
+		   kret);
 
-      kret = mach_port_insert_right (gdb_task, darwin_ex_port, darwin_ex_port,
-				     MACH_MSG_TYPE_MAKE_SEND);
-      if (kret != KERN_SUCCESS)
-	error (_("Unable to create exception port, mach_port_insert_right "
-		 "returned: %d"),
-	       kret);
+	  kret = mach_port_insert_right (gdb_task, darwin_ex_port,
+					 darwin_ex_port,
+					 MACH_MSG_TYPE_MAKE_SEND);
+	  if (kret != KERN_SUCCESS)
+	    error (_("Unable to create exception port, mach_port_insert_right "
+		     "returned: %d"),
+		   kret);
 
-      /* Create a port set and put ex_port in it.  */
-      kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_PORT_SET,
-				 &darwin_port_set);
+	  /* Create a port set and put ex_port in it.  */
+	  kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_PORT_SET,
+				     &darwin_port_set);
+	  if (kret != KERN_SUCCESS)
+	    error (_("Unable to create port set, mach_port_allocate "
+		     "returned: %d"),
+		   kret);
+
+	  kret = mach_port_move_member (gdb_task, darwin_ex_port,
+					darwin_port_set);
+	  if (kret != KERN_SUCCESS)
+	    error (_("Unable to move exception port into new port set, "
+		     "mach_port_move_member\n"
+		     "returned: %d"),
+		   kret);
+	}
+
+      /* Create a port to be notified when the child task terminates.  */
+      kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
+				 &priv->notify_port);
       if (kret != KERN_SUCCESS)
-	error (_("Unable to create port set, mach_port_allocate "
+	error (_("Unable to create notification port, mach_port_allocate "
 		 "returned: %d"),
 	       kret);
 
-      kret = mach_port_move_member (gdb_task, darwin_ex_port, darwin_port_set);
+      kret = mach_port_move_member (gdb_task,
+				    priv->notify_port, darwin_port_set);
       if (kret != KERN_SUCCESS)
-	error (_("Unable to move exception port into new port set, "
+	error (_("Unable to move notification port into new port set, "
 		 "mach_port_move_member\n"
 		 "returned: %d"),
 	       kret);
-    }
-
-  /* Create a port to be notified when the child task terminates.  */
-  kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
-			     &priv->notify_port);
-  if (kret != KERN_SUCCESS)
-    error (_("Unable to create notification port, mach_port_allocate "
-	     "returned: %d"),
-	   kret);
 
-  kret = mach_port_move_member (gdb_task,
-				priv->notify_port, darwin_port_set);
-  if (kret != KERN_SUCCESS)
-    error (_("Unable to move notification port into new port set, "
-	     "mach_port_move_member\n"
-	     "returned: %d"),
-	   kret);
+      darwin_setup_request_notification (inf);
 
-  darwin_setup_request_notification (inf);
+      darwin_setup_exceptions (inf);
+    }
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      exit_inferior (inf);
+      inferior_ptid = null_ptid;
 
-  darwin_setup_exceptions (inf);
+      throw_exception (ex);
+    }
+  END_CATCH
 
   target_ops *darwin_ops = get_native_target ();
   if (!target_is_pushed (darwin_ops))

  reply	other threads:[~2018-07-02 15:33 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-28 18:03 Tom Tromey
2018-06-29 19:31 ` Pedro Alves
2018-07-02 15:33   ` Tom Tromey [this message]
2018-07-03 14:16     ` Pedro Alves
2018-07-04 11:46       ` Pedro Alves
2018-07-04 17:34         ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o9fpodos.fsf@tromey.com \
    --to=tom@tromey.com \
    --cc=gdb-patches@sourceware.org \
    --cc=palves@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).