aboutsummaryrefslogtreecommitdiff
path: root/gdb/darwin-nat.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2018-06-28 11:57:39 -0600
committerTom Tromey <tom@tromey.com>2018-07-03 09:28:26 -0600
commita50c11c666e07b922d64aa5bb2747f180ce17c03 (patch)
tree80d95fd601e4a2aadee6e5bc34d1f921f306333f /gdb/darwin-nat.c
parentb8a6ced79668ec8af3180e50b76f7517ebbab0d9 (diff)
downloadbinutils-a50c11c666e07b922d64aa5bb2747f180ce17c03.zip
binutils-a50c11c666e07b922d64aa5bb2747f180ce17c03.tar.gz
binutils-a50c11c666e07b922d64aa5bb2747f180ce17c03.tar.bz2
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 updating the inferior and inferior_ptid on failure. Tested by building an unsigned gdb on macOS and trying to run an inferior. gdb/ChangeLog 2018-07-03 Tom Tromey <tom@tromey.com> PR cli/23340: * darwin-nat.c (darwin_attach_pid): Reset inferior and inferior_ptid on error.
Diffstat (limited to 'gdb/darwin-nat.c')
-rw-r--r--gdb/darwin-nat.c119
1 files changed, 67 insertions, 52 deletions
diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 7dccce7..6fb1088 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -1583,77 +1583,92 @@ 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)
+ {
+ inf->pid = 0;
+ inf->priv.reset ();
+ 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))