From fda184b63953cef0f058748b74ebf8d29b4aa8a2 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Mon, 6 May 2013 12:35:46 +0000 Subject: [PATCH] darwin-nat.c: Do not use gdb_assert on system call outcomes. There were many cases were we make a system call which could fail due to reasons outside of the debugger control. We should handle these situations a little more gracefully than triggering an internal error. gdb/ChangeLog: * darwin-nat.c (darwin_mourn_inferior): Replace call to gdb_assert by call to MACH_CHECK_ERROR. (darwin_attach_pid): Raise an error rather than a failed assertion when various system calls failed. Report a warning instead of raising a failed assertion when PREV_NOT is not NULL after call to mach_port_request_notification. (darwin_ptrace_me): Raise an error rather than a failed assertion when read returns nonzero. --- gdb/ChangeLog | 11 +++++++++ gdb/darwin-nat.c | 64 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9091b68a3a7..1988872656d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2013-05-06 Joel Brobecker + + * darwin-nat.c (darwin_mourn_inferior): Replace call to + gdb_assert by call to MACH_CHECK_ERROR. + (darwin_attach_pid): Raise an error rather than a failed + assertion when various system calls failed. Report a warning + instead of raising a failed assertion when PREV_NOT is not NULL + after call to mach_port_request_notification. + (darwin_ptrace_me): Raise an error rather than a failed + assertion when read returns nonzero. + 2013-05-06 Joel Brobecker * amd64-darwin-tdep.c: Remove #include "gdb_assert.h". diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index c4280a4cf69..b6d853f9e42 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -1182,7 +1182,7 @@ darwin_mourn_inferior (struct target_ops *ops) kret = mach_port_move_member (gdb_task, inf->private->notify_port, MACH_PORT_NULL); - gdb_assert (kret == KERN_SUCCESS); + MACH_CHECK_ERROR (kret); kret = mach_port_request_notification (gdb_task, inf->private->task, MACH_NOTIFY_DEAD_NAME, 0, @@ -1371,40 +1371,76 @@ darwin_attach_pid (struct inferior *inf) /* Create a port to get exceptions. */ kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE, &darwin_ex_port); - gdb_assert (kret == KERN_SUCCESS); + 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); - gdb_assert (kret == KERN_SUCCESS); + 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); - gdb_assert (kret == KERN_SUCCESS); + 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); - gdb_assert (kret == KERN_SUCCESS); + 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, &inf->private->notify_port); - gdb_assert (kret == KERN_SUCCESS); + if (kret != KERN_SUCCESS) + error (_("Unable to create notification port, mach_port_allocate " + "returned: %d"), + kret); kret = mach_port_move_member (gdb_task, inf->private->notify_port, darwin_port_set); - gdb_assert (kret == KERN_SUCCESS); + if (kret != KERN_SUCCESS) + error (_("Unable to move notification port into new port set, " + "mach_port_move_member\n" + "returned: %d"), + kret); kret = mach_port_request_notification (gdb_task, inf->private->task, MACH_NOTIFY_DEAD_NAME, 0, inf->private->notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev_not); - gdb_assert (kret == KERN_SUCCESS); - gdb_assert (prev_not == MACH_PORT_NULL); + if (kret != KERN_SUCCESS) + error (_("Termination notification request failed, " + "mach_port_request_notification\n" + "returned: %d"), + kret); + if (prev_not != MACH_PORT_NULL) + { + /* This is unexpected, as there should not be any previously + registered notification request. But this is not a fatal + issue, so just emit a warning. */ + warning (_("\ +A task termination request was registered before the debugger registered\n\ +its own. This is unexpected, but should otherwise not have any actual\n\ +impact on the debugging session.")); + } kret = darwin_save_exception_ports (inf->private); - gdb_assert (kret == KERN_SUCCESS); + if (kret != KERN_SUCCESS) + error (_("Unable to save exception ports, task_get_exception_ports" + "returned: %d"), + kret); /* Set exception port. */ if (enable_mach_exceptions) @@ -1413,7 +1449,10 @@ darwin_attach_pid (struct inferior *inf) mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT; kret = task_set_exception_ports (inf->private->task, mask, darwin_ex_port, EXCEPTION_DEFAULT, THREAD_STATE_NONE); - gdb_assert (kret == KERN_SUCCESS); + if (kret != KERN_SUCCESS) + error (_("Unable to set exception ports, task_set_exception_ports" + "returned: %d"), + kret); push_target (darwin_ops); } @@ -1453,7 +1492,8 @@ darwin_ptrace_me (void) /* Wait until gdb is ready. */ res = read (ptrace_fds[0], &c, 1); - gdb_assert (res == 0); + if (res != 0) + error (_("unable to read from pipe, read returned: %d"), res); close (ptrace_fds[0]); /* Get rid of privileges. */ -- 2.30.2