From: Simon Marchi Date: Fri, 24 Nov 2017 15:39:30 +0000 (-0500) Subject: Create private_inferior class hierarchy X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=089354bb0613ca1559813f0a79fbe73655113785;p=binutils-gdb.git Create private_inferior class hierarchy There are currently multiple definitions of private_inferior, defined in remote.c and darwin-nat.h. The patch that poisons XNEW and friends for non-POD types trips on that, because private_inferior is freed in ~inferior(), where it is an opaque type. Since the compiler can't tell whether the type is POD, it gives an error. Also, we can't start using C++ features in these structures (make them non-POD) as long as there are multiple definitions with the same name. For these reasons, this patch makes a class hierarchy, with private_inferior being the abstract base class, and darwin_inferior & remote_inferior inheriting from it. Destruction is done through the virtual destructor. I stumbled on some suspicious code in the darwin implementation though. darwin_check_new_threads does an XCNEW(darwin_thread_t) when it finds a new thread, allocating a new structure for it (darwin_thread_t is a typedef for private_thread_info). It then VEC_safe_pushes it in a vector defined as DEF_VEC_O (a vector of objects). This means that the structure content gets copied in the vector. The thread_info object is created with the XCNEW'ed structure as the private thread info, while the rest of the code works with the instance in the vector. We have therefore two distinct instances of darwin_thread_t/private_thread_info for each thread. This is not really a problem in practice, because thread_info::priv is not used in the darwin code. I still find it weird and far from ideal, so I tried to fix it by changing the vector to be a vector of pointers. There should now be a single instance of the structure for each thread. The deallocation of the darwin_thread_t/private_thread_info structure is done by the thread_info destructor. I am able to build on macOS, but not really test, since the port seems a bit broken. I am not able to debug reliably on the machine I have access to, which runs macOS 10.12.6. gdb/ChangeLog: * inferior.h (private_inferior): Define structure type, add virtual pure destructor. (inferior) : Change type to unique_ptr. * inferior.c (private_inferior::~private_inferior): Provide default implementation. (inferior::~inferior): Don't free priv field. (exit_inferior_1): Likewise. * darwin-nat.h (struct darwin_exception_info): Initialize fields. (darwin_exception_info): Remove typedef. (DEF_VEC_O (darwin_thread_t)); Remove. (private_inferior): Rename to ... (darwin_private_inferior): ... this, extend private_inferior. (get_darwin_inferior): New. : Change type to std::vector of darwin_thread_t pointers. * darwin-nat.c (darwin_check_new_threads): Adjust. (find_inferior_task_it): Adjust. (darwin_find_thread); Adjust. (darwin_suspend_inferior): Adjust. (darwin_resume_inferior): Adjust. (darwin_find_new_inferior): Adjust. (darwin_decode_notify_message): Adjust. (darwin_send_reply): Adjust. (darwin_resume_inferior_threads): Adjust. (darwin_suspend_inferior_threads): Adjust. (darwin_decode_message): Adjust. (darwin_wait): Adjust. (darwin_interrupt): Adjust. (darwin_deallocate_threads): Adjust. (darwin_mourn_inferior): Adjust, don't free private data. (darwin_reply_to_all_pending_messages): Adjust. (darwin_stop_inferior): Adjust. (darwin_setup_exceptions): Adjust. (darwin_kill_inferior): Adjust. (darwin_setup_request_notification): Adjust. (darwin_attach_pid): Adjust. (darwin_init_thread_list): Adjust. (darwin_setup_fake_stop_event): Adjust. (darwin_attach): Adjust. (darwin_detach): Adjust. (darwin_xfer_partial): Adjust. (set_enable_mach_exceptions): Adjust. (darwin_pid_to_exec_file): Adjust. (darwin_get_ada_task_ptid): Adjust. * darwin-nat-info.c (get_task_from_args): Adjust. (info_mach_ports_command): Adjust. (info_mach_region_command): Adjust. (info_mach_exceptions_command): Adjust. * remote.c (private_inferior): Rename to ... (remote_private_inferior): ... this, initialize fields. (get_remote_inferior); New. (remote_commit_resume): Use get_remote_inferior. (check_pending_event_prevents_wildcard_vcont_callback): Likewise. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e6762bb92da..b0356dbde37 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,58 @@ +2017-11-24 Simon Marchi + + * inferior.h (private_inferior): Define structure type, add + virtual pure destructor. + (inferior) : Change type to unique_ptr. + * inferior.c (private_inferior::~private_inferior): Provide + default implementation. + (inferior::~inferior): Don't free priv field. + (exit_inferior_1): Likewise. + * darwin-nat.h (struct darwin_exception_info): Initialize fields. + (darwin_exception_info): Remove typedef. + (DEF_VEC_O (darwin_thread_t)); Remove. + (private_inferior): Rename to ... + (darwin_private_inferior): ... this, extend private_inferior. + (get_darwin_inferior): New. + : Change type to std::vector of darwin_thread_t pointers. + * darwin-nat.c (darwin_check_new_threads): Adjust. + (find_inferior_task_it): Adjust. + (darwin_find_thread); Adjust. + (darwin_suspend_inferior): Adjust. + (darwin_resume_inferior): Adjust. + (darwin_find_new_inferior): Adjust. + (darwin_decode_notify_message): Adjust. + (darwin_send_reply): Adjust. + (darwin_resume_inferior_threads): Adjust. + (darwin_suspend_inferior_threads): Adjust. + (darwin_decode_message): Adjust. + (darwin_wait): Adjust. + (darwin_interrupt): Adjust. + (darwin_deallocate_threads): Adjust. + (darwin_mourn_inferior): Adjust, don't free private data. + (darwin_reply_to_all_pending_messages): Adjust. + (darwin_stop_inferior): Adjust. + (darwin_setup_exceptions): Adjust. + (darwin_kill_inferior): Adjust. + (darwin_setup_request_notification): Adjust. + (darwin_attach_pid): Adjust. + (darwin_init_thread_list): Adjust. + (darwin_setup_fake_stop_event): Adjust. + (darwin_attach): Adjust. + (darwin_detach): Adjust. + (darwin_xfer_partial): Adjust. + (set_enable_mach_exceptions): Adjust. + (darwin_pid_to_exec_file): Adjust. + (darwin_get_ada_task_ptid): Adjust. + * darwin-nat-info.c (get_task_from_args): Adjust. + (info_mach_ports_command): Adjust. + (info_mach_region_command): Adjust. + (info_mach_exceptions_command): Adjust. + * remote.c (private_inferior): Rename to ... + (remote_private_inferior): ... this, initialize fields. + (get_remote_inferior); New. + (remote_commit_resume): Use get_remote_inferior. + (check_pending_event_prevents_wildcard_vcont_callback): Likewise. + 2017-11-24 Pedro Alves * NEWS: Mention linespecs and explicit locations, and completion diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c index 44782bfa78d..97847b9f059 100644 --- a/gdb/darwin-nat-info.c +++ b/gdb/darwin-nat-info.c @@ -118,7 +118,10 @@ get_task_from_args (const char *args) { if (ptid_equal (inferior_ptid, null_ptid)) printf_unfiltered (_("No inferior running\n")); - return current_inferior ()->priv->task; + + darwin_inferior *priv = get_darwin_inferior (current_inferior ()); + + return priv->task; } if (strcmp (args, "gdb") == 0) return mach_task_self (); @@ -257,36 +260,31 @@ info_mach_ports_command (const char *args, int from_tty) else if (!ptid_equal (inferior_ptid, null_ptid)) { struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); - if (port == inf->priv->task) + if (port == priv->task) printf_unfiltered (_(" inferior-task")); - else if (port == inf->priv->notify_port) + else if (port == priv->notify_port) printf_unfiltered (_(" inferior-notify")); else { - int k; - darwin_thread_t *t; - - for (k = 0; k < inf->priv->exception_info.count; k++) - if (port == inf->priv->exception_info.ports[k]) + for (int k = 0; k < priv->exception_info.count; k++) + if (port == priv->exception_info.ports[k]) { printf_unfiltered (_(" inferior-excp-port")); break; } - if (inf->priv->threads) + for (darwin_thread_t *t : priv->threads) { - for (k = 0; - VEC_iterate(darwin_thread_t, - inf->priv->threads, k, t); - k++) - if (port == t->gdb_port) - { - printf_unfiltered (_(" inferior-thread for 0x%x"), - inf->priv->task); - break; - } + if (port == t->gdb_port) + { + printf_unfiltered (_(" inferior-thread for 0x%x"), + priv->task); + break; + } } + } } } @@ -738,7 +736,8 @@ info_mach_region_command (const char *exp, int from_tty) error (_("Inferior not available")); inf = current_inferior (); - darwin_debug_region (inf->priv->task, address); + darwin_inferior *priv = get_darwin_inferior (inf); + darwin_debug_region (priv->task, address); } static void @@ -807,7 +806,10 @@ info_mach_exceptions_command (const char *args, int from_tty) { if (ptid_equal (inferior_ptid, null_ptid)) printf_unfiltered (_("No inferior running\n")); - disp_exception (¤t_inferior ()->priv->exception_info); + + darwin_inferior *priv = get_darwin_inferior (current_inferior ()); + + disp_exception (&priv->exception_info); return; } else if (strcmp (args, "host") == 0) @@ -830,8 +832,10 @@ info_mach_exceptions_command (const char *args, int from_tty) printf_unfiltered (_("No inferior running\n")); inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); + kret = task_get_exception_ports - (inf->priv->task, EXC_MASK_ALL, info.masks, + (priv->task, EXC_MASK_ALL, info.masks, &info.count, info.ports, info.behaviors, info.flavors); MACH_CHECK_ERROR (kret); disp_exception (&info); diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index 6e420c42555..ed195d910c7 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -279,13 +279,12 @@ static void darwin_check_new_threads (struct inferior *inf) { kern_return_t kret; - unsigned int i; thread_array_t thread_list; unsigned int new_nbr; unsigned int old_nbr; unsigned int new_ix, old_ix; - darwin_inferior *darwin_inf = inf->priv; - VEC (darwin_thread_t) *thread_vec; + darwin_inferior *darwin_inf = get_darwin_inferior (inf); + std::vector new_thread_vec; /* Get list of threads. */ kret = task_threads (darwin_inf->task, &thread_list, &new_nbr); @@ -297,17 +296,15 @@ darwin_check_new_threads (struct inferior *inf) if (new_nbr > 1) qsort (thread_list, new_nbr, sizeof (thread_t), cmp_thread_t); - if (darwin_inf->threads) - old_nbr = VEC_length (darwin_thread_t, darwin_inf->threads); - else - old_nbr = 0; + old_nbr = darwin_inf->threads.size (); /* Quick check for no changes. */ if (old_nbr == new_nbr) { + size_t i; + for (i = 0; i < new_nbr; i++) - if (thread_list[i] - != VEC_index (darwin_thread_t, darwin_inf->threads, i)->gdb_port) + if (thread_list[i] != darwin_inf->threads[i]->gdb_port) break; if (i == new_nbr) { @@ -328,15 +325,15 @@ darwin_check_new_threads (struct inferior *inf) } /* Full handling: detect new threads, remove dead threads. */ - thread_vec = VEC_alloc (darwin_thread_t, new_nbr); + + new_thread_vec.reserve (new_nbr); for (new_ix = 0, old_ix = 0; new_ix < new_nbr || old_ix < old_nbr;) { - thread_t new_id = (new_ix < new_nbr) ? - thread_list[new_ix] : THREAD_NULL; - darwin_thread_t *old = (old_ix < old_nbr) ? - VEC_index (darwin_thread_t, darwin_inf->threads, old_ix) : NULL; - thread_t old_id = old ? old->gdb_port : THREAD_NULL; + thread_t new_id = (new_ix < new_nbr) ? thread_list[new_ix] : THREAD_NULL; + darwin_thread_t *old + = (old_ix < old_nbr) ? darwin_inf->threads[old_ix] : NULL; + thread_t old_id = old != NULL ? old->gdb_port : THREAD_NULL; inferior_debug (12, _(" new_ix:%d/%d, old_ix:%d/%d, new_id:0x%x old_id:0x%x\n"), @@ -345,7 +342,7 @@ darwin_check_new_threads (struct inferior *inf) if (old_id == new_id) { /* Thread still exist. */ - VEC_safe_push (darwin_thread_t, thread_vec, old); + new_thread_vec.push_back (old); new_ix++; old_ix++; @@ -368,13 +365,13 @@ darwin_check_new_threads (struct inferior *inf) /* A thread was created. */ struct private_thread_info *pti; - pti = XCNEW (struct private_thread_info); + pti = XCNEW (darwin_thread_t); pti->gdb_port = new_id; pti->msg_state = DARWIN_RUNNING; /* Add the new thread. */ add_thread_with_info (ptid_build (inf->pid, 0, new_id), pti); - VEC_safe_push (darwin_thread_t, thread_vec, pti); + new_thread_vec.push_back (pti); new_ix++; continue; } @@ -390,9 +387,7 @@ darwin_check_new_threads (struct inferior *inf) gdb_assert_not_reached ("unexpected thread case"); } - if (darwin_inf->threads) - VEC_free (darwin_thread_t, darwin_inf->threads); - darwin_inf->threads = thread_vec; + darwin_inf->threads = std::move (new_thread_vec); /* Deallocate the buffer. */ kret = vm_deallocate (gdb_task, (vm_address_t) thread_list, @@ -403,7 +398,9 @@ darwin_check_new_threads (struct inferior *inf) static int find_inferior_task_it (struct inferior *inf, void *port_ptr) { - return inf->priv->task == *(task_t *)port_ptr; + darwin_inferior *priv = get_darwin_inferior (inf); + + return priv->task == *(task_t *)port_ptr; } static int @@ -430,14 +427,14 @@ darwin_find_inferior_by_pid (int pid) static darwin_thread_t * darwin_find_thread (struct inferior *inf, thread_t thread) { - darwin_thread_t *t; - int k; + darwin_inferior *priv = get_darwin_inferior (inf); + + for (darwin_thread_t *t : priv->threads) + { + if (t->gdb_port == thread) + return t; + } - for (k = 0; - VEC_iterate (darwin_thread_t, inf->priv->threads, k, t); - k++) - if (t->gdb_port == thread) - return t; return NULL; } @@ -446,14 +443,16 @@ darwin_find_thread (struct inferior *inf, thread_t thread) static void darwin_suspend_inferior (struct inferior *inf) { - if (!inf->priv->suspended) + darwin_inferior *priv = get_darwin_inferior (inf); + + if (!priv->suspended) { kern_return_t kret; - kret = task_suspend (inf->priv->task); + kret = task_suspend (priv->task); MACH_CHECK_ERROR (kret); - inf->priv->suspended = 1; + priv->suspended = 1; } } @@ -462,14 +461,16 @@ darwin_suspend_inferior (struct inferior *inf) static void darwin_resume_inferior (struct inferior *inf) { - if (inf->priv->suspended) + darwin_inferior *priv = get_darwin_inferior (inf); + + if (priv->suspended) { kern_return_t kret; - kret = task_resume (inf->priv->task); + kret = task_resume (priv->task); MACH_CHECK_ERROR (kret); - inf->priv->suspended = 0; + priv->suspended = 0; } } @@ -580,11 +581,13 @@ darwin_find_new_inferior (task_t task_port, thread_t thread_port) if (inf == NULL) return NULL; + darwin_inferior *priv = get_darwin_inferior (inf); + /* Deallocate saved exception ports. */ - darwin_deallocate_exception_ports (inf->priv); + darwin_deallocate_exception_ports (priv); /* No need to remove dead_name notification, but still... */ - kret = mach_port_request_notification (gdb_task, inf->priv->task, + kret = mach_port_request_notification (gdb_task, priv->task, MACH_NOTIFY_DEAD_NAME, 0, MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND_ONCE, @@ -593,9 +596,9 @@ darwin_find_new_inferior (task_t task_port, thread_t thread_port) MACH_CHECK_ERROR (kret); /* Replace old task port. */ - kret = mach_port_deallocate (gdb_task, inf->priv->task); + kret = mach_port_deallocate (gdb_task, priv->task); MACH_CHECK_ERROR (kret); - inf->priv->task = task_port; + priv->task = task_port; darwin_setup_request_notification (inf); darwin_setup_exceptions (inf); @@ -789,8 +792,10 @@ darwin_decode_notify_message (mach_msg_header_t *hdr, struct inferior **pinf) inf = darwin_find_inferior_by_task (task_port); *pinf = inf; + darwin_inferior *priv = get_darwin_inferior (inf); + /* Check message destination. */ - if (inf != NULL && hdr->msgh_local_port != inf->priv->notify_port) + if (inf != NULL && hdr->msgh_local_port != priv->notify_port) return -4; return 0; @@ -817,6 +822,7 @@ darwin_send_reply (struct inferior *inf, darwin_thread_t *thread) { kern_return_t kret; mig_reply_error_t reply; + darwin_inferior *priv = get_darwin_inferior (inf); darwin_encode_reply (&reply, &thread->event.header, KERN_SUCCESS); @@ -826,7 +832,7 @@ darwin_send_reply (struct inferior *inf, darwin_thread_t *thread) MACH_PORT_NULL); MACH_CHECK_ERROR (kret); - inf->priv->pending_messages--; + priv->pending_messages--; } static void @@ -889,12 +895,9 @@ darwin_resume_thread (struct inferior *inf, darwin_thread_t *thread, static void darwin_resume_inferior_threads (struct inferior *inf, int step, int nsignal) { - darwin_thread_t *thread; - int k; + darwin_inferior *priv = get_darwin_inferior (inf); - for (k = 0; - VEC_iterate (darwin_thread_t, inf->priv->threads, k, thread); - k++) + for (darwin_thread_t *thread : priv->threads) darwin_resume_thread (inf, thread, step, nsignal); } @@ -920,24 +923,24 @@ darwin_resume_inferior_threads_it (struct inferior *inf, void *param) static void darwin_suspend_inferior_threads (struct inferior *inf) { - darwin_thread_t *thread; - kern_return_t kret; - int k; + darwin_inferior *priv = get_darwin_inferior (inf); - for (k = 0; - VEC_iterate (darwin_thread_t, inf->priv->threads, k, thread); - k++) - switch (thread->msg_state) - { - case DARWIN_STOPPED: - case DARWIN_MESSAGE: - break; - case DARWIN_RUNNING: - kret = thread_suspend (thread->gdb_port); - MACH_CHECK_ERROR (kret); - thread->msg_state = DARWIN_STOPPED; - break; - } + for (darwin_thread_t *thread : priv->threads) + { + switch (thread->msg_state) + { + case DARWIN_STOPPED: + case DARWIN_MESSAGE: + break; + case DARWIN_RUNNING: + { + kern_return_t kret = thread_suspend (thread->gdb_port); + MACH_CHECK_ERROR (kret); + thread->msg_state = DARWIN_STOPPED; + break; + } + } + } } static void @@ -1045,7 +1048,10 @@ darwin_decode_message (mach_msg_header_t *hdr, } *pinf = inf; *pthread = thread; - inf->priv->pending_messages++; + + darwin_inferior *priv = get_darwin_inferior (inf); + + priv->pending_messages++; status->kind = TARGET_WAITKIND_STOPPED; thread->msg_state = DARWIN_MESSAGE; @@ -1129,7 +1135,9 @@ darwin_decode_message (mach_msg_header_t *hdr, if (inf != NULL) { - if (!inf->priv->no_ptrace) + darwin_inferior *priv = get_darwin_inferior (inf); + + if (!priv->no_ptrace) { pid_t res; int wstatus; @@ -1232,9 +1240,11 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status) inf = darwin_inf_fake_stop; darwin_inf_fake_stop = NULL; + darwin_inferior *priv = get_darwin_inferior (inf); + status->kind = TARGET_WAITKIND_STOPPED; status->value.sig = GDB_SIGNAL_TRAP; - thread = VEC_index (darwin_thread_t, inf->priv->threads, 0); + thread = priv->threads[0]; thread->msg_state = DARWIN_STOPPED; return ptid_build (inf->pid, 0, thread->gdb_port); } @@ -1336,9 +1346,10 @@ static void darwin_interrupt (struct target_ops *self, ptid_t t) { struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); /* FIXME: handle in no_ptrace mode. */ - gdb_assert (!inf->priv->no_ptrace); + gdb_assert (!priv->no_ptrace); kill (inf->pid, SIGINT); } @@ -1347,27 +1358,22 @@ darwin_interrupt (struct target_ops *self, ptid_t t) static void darwin_deallocate_threads (struct inferior *inf) { - if (inf->priv->threads) + darwin_inferior *priv = get_darwin_inferior (inf); + + for (darwin_thread_t *t : priv->threads) { - kern_return_t kret; - int k; - darwin_thread_t *t; - for (k = 0; - VEC_iterate (darwin_thread_t, inf->priv->threads, k, t); - k++) - { - kret = mach_port_deallocate (gdb_task, t->gdb_port); - MACH_CHECK_ERROR (kret); - } - VEC_free (darwin_thread_t, inf->priv->threads); - inf->priv->threads = NULL; + kern_return_t kret = mach_port_deallocate (gdb_task, t->gdb_port); + MACH_CHECK_ERROR (kret); } + + priv->threads.clear (); } static void darwin_mourn_inferior (struct target_ops *ops) { struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); kern_return_t kret; mach_port_t prev; int i; @@ -1377,18 +1383,18 @@ darwin_mourn_inferior (struct target_ops *ops) /* Remove notify_port from darwin_port_set. */ kret = mach_port_move_member (gdb_task, - inf->priv->notify_port, MACH_PORT_NULL); + priv->notify_port, MACH_PORT_NULL); MACH_CHECK_ERROR (kret); /* Remove task port dead_name notification. */ - kret = mach_port_request_notification (gdb_task, inf->priv->task, + kret = mach_port_request_notification (gdb_task, priv->task, MACH_NOTIFY_DEAD_NAME, 0, MACH_PORT_NULL, MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev); /* This can fail if the task is dead. */ inferior_debug (4, "task=0x%x, prev=0x%x, notify_port=0x%x\n", - inf->priv->task, prev, inf->priv->notify_port); + priv->task, prev, priv->notify_port); if (kret == KERN_SUCCESS) { @@ -1397,17 +1403,16 @@ darwin_mourn_inferior (struct target_ops *ops) } /* Destroy notify_port. */ - kret = mach_port_destroy (gdb_task, inf->priv->notify_port); + kret = mach_port_destroy (gdb_task, priv->notify_port); MACH_CHECK_ERROR (kret); /* Deallocate saved exception ports. */ - darwin_deallocate_exception_ports (inf->priv); + darwin_deallocate_exception_ports (priv); /* Deallocate task port. */ - kret = mach_port_deallocate (gdb_task, inf->priv->task); + kret = mach_port_deallocate (gdb_task, priv->task); MACH_CHECK_ERROR (kret); - xfree (inf->priv); inf->priv = NULL; inf_child_mourn_inferior (ops); @@ -1416,12 +1421,9 @@ darwin_mourn_inferior (struct target_ops *ops) static void darwin_reply_to_all_pending_messages (struct inferior *inf) { - int k; - darwin_thread_t *t; + darwin_inferior *priv = get_darwin_inferior (inf); - for (k = 0; - VEC_iterate (darwin_thread_t, inf->priv->threads, k, t); - k++) + for (darwin_thread_t *t : priv->threads) { if (t->msg_state == DARWIN_MESSAGE) darwin_resume_thread (inf, t, 0, 0); @@ -1436,6 +1438,7 @@ darwin_stop_inferior (struct inferior *inf) kern_return_t kret; int status; int res; + darwin_inferior *priv = get_darwin_inferior (inf); gdb_assert (inf != NULL); @@ -1443,7 +1446,7 @@ darwin_stop_inferior (struct inferior *inf) darwin_reply_to_all_pending_messages (inf); - if (inf->priv->no_ptrace) + if (priv->no_ptrace) return; res = kill (inf->pid, SIGSTOP); @@ -1512,11 +1515,12 @@ darwin_deallocate_exception_ports (darwin_inferior *inf) static void darwin_setup_exceptions (struct inferior *inf) { + darwin_inferior *priv = get_darwin_inferior (inf); kern_return_t kret; int traps_expected; exception_mask_t mask; - kret = darwin_save_exception_ports (inf->priv); + kret = darwin_save_exception_ports (priv); if (kret != KERN_SUCCESS) error (_("Unable to save exception ports, task_get_exception_ports" "returned: %d"), @@ -1527,7 +1531,7 @@ darwin_setup_exceptions (struct inferior *inf) mask = EXC_MASK_ALL; else mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT; - kret = task_set_exception_ports (inf->priv->task, mask, darwin_ex_port, + kret = task_set_exception_ports (priv->task, mask, darwin_ex_port, EXCEPTION_DEFAULT, THREAD_STATE_NONE); if (kret != KERN_SUCCESS) error (_("Unable to set exception ports, task_set_exception_ports" @@ -1539,6 +1543,7 @@ static void darwin_kill_inferior (struct target_ops *ops) { struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); struct target_waitstatus wstatus; ptid_t ptid; kern_return_t kret; @@ -1550,7 +1555,7 @@ darwin_kill_inferior (struct target_ops *ops) gdb_assert (inf != NULL); - kret = darwin_restore_exception_ports (inf->priv); + kret = darwin_restore_exception_ports (priv); MACH_CHECK_ERROR (kret); darwin_reply_to_all_pending_messages (inf); @@ -1573,12 +1578,13 @@ darwin_kill_inferior (struct target_ops *ops) static void darwin_setup_request_notification (struct inferior *inf) { + darwin_inferior *priv = get_darwin_inferior (inf); kern_return_t kret; mach_port_t prev_not; - kret = mach_port_request_notification (gdb_task, inf->priv->task, + kret = mach_port_request_notification (gdb_task, priv->task, MACH_NOTIFY_DEAD_NAME, 0, - inf->priv->notify_port, + priv->notify_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &prev_not); if (kret != KERN_SUCCESS) @@ -1607,9 +1613,10 @@ darwin_attach_pid (struct inferior *inf) mach_port_t prev_not; exception_mask_t mask; - inf->priv = XCNEW (darwin_inferior); + darwin_inferior *priv = new darwin_inferior; + inf->priv.reset (priv); - kret = task_for_pid (gdb_task, inf->pid, &inf->priv->task); + kret = task_for_pid (gdb_task, inf->pid, &priv->task); if (kret != KERN_SUCCESS) { int status; @@ -1626,7 +1633,7 @@ darwin_attach_pid (struct inferior *inf) } inferior_debug (2, _("inferior task: 0x%x, pid: %d\n"), - inf->priv->task, inf->pid); + priv->task, inf->pid); if (darwin_ex_port == MACH_PORT_NULL) { @@ -1663,14 +1670,14 @@ darwin_attach_pid (struct inferior *inf) /* Create a port to be notified when the child task terminates. */ kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE, - &inf->priv->notify_port); + &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, - inf->priv->notify_port, darwin_port_set); + 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" @@ -1708,11 +1715,11 @@ darwin_init_thread_list (struct inferior *inf) { darwin_check_new_threads (inf); - gdb_assert (inf->priv->threads != NULL); - gdb_assert (VEC_length (darwin_thread_t, inf->priv->threads) > 0); + darwin_inferior *priv = get_darwin_inferior (inf); - private_thread_info *first_pti - = VEC_index (darwin_thread_t, inf->priv->threads, 0); + gdb_assert (!priv->threads.empty ()); + + private_thread_info *first_pti = priv->threads.front (); struct thread_info *first_thread = thread_info_from_private_thread_info (first_pti); @@ -1849,6 +1856,7 @@ darwin_create_inferior (struct target_ops *ops, static void darwin_setup_fake_stop_event (struct inferior *inf) { + darwin_inferior *priv = get_darwin_inferior (inf); darwin_thread_t *thread; kern_return_t kret; @@ -1861,7 +1869,7 @@ darwin_setup_fake_stop_event (struct inferior *inf) as well. Otherwise, we'll try resuming it when resuming the inferior, and get a warning because the thread's suspend count is already zero, making the resume request useless. */ - thread = VEC_index (darwin_thread_t, inf->priv->threads, 0); + thread = priv->threads[0]; kret = thread_suspend (thread->gdb_port); MACH_CHECK_ERROR (kret); } @@ -1912,11 +1920,13 @@ darwin_attach (struct target_ops *ops, const char *args, int from_tty) darwin_init_thread_list (inf); - darwin_check_osabi (inf->priv, ptid_get_tid (inferior_ptid)); + darwin_inferior *priv = get_darwin_inferior (inf); + + darwin_check_osabi (priv, ptid_get_tid (inferior_ptid)); darwin_setup_fake_stop_event (inf); - inf->priv->no_ptrace = 1; + priv->no_ptrace = 1; } /* Take a program previously attached to and detaches it. @@ -1931,6 +1941,7 @@ darwin_detach (struct target_ops *ops, const char *args, int from_tty) { pid_t pid = ptid_get_pid (inferior_ptid); struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); kern_return_t kret; int res; @@ -1938,13 +1949,13 @@ darwin_detach (struct target_ops *ops, const char *args, int from_tty) target_announce_detach (from_tty); /* If ptrace() is in use, stop the process. */ - if (!inf->priv->no_ptrace) + if (!priv->no_ptrace) darwin_stop_inferior (inf); - kret = darwin_restore_exception_ports (inf->priv); + kret = darwin_restore_exception_ports (priv); MACH_CHECK_ERROR (kret); - if (!inf->priv->no_ptrace) + if (!priv->no_ptrace) { res = PTRACE (PT_DETACH, inf->pid, 0, 0); if (res != 0) @@ -1957,7 +1968,7 @@ darwin_detach (struct target_ops *ops, const char *args, int from_tty) /* When using ptrace, we have just performed a PT_DETACH, which resumes the inferior. On the other hand, when we are not using ptrace, we need to resume its execution ourselves. */ - if (inf->priv->no_ptrace) + if (priv->no_ptrace) darwin_resume_inferior (inf); darwin_mourn_inferior (ops); @@ -2189,6 +2200,7 @@ darwin_xfer_partial (struct target_ops *ops, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); inferior_debug (8, _("darwin_xfer_partial(%s, %s, rbuf=%s, wbuf=%s) pid=%u\n"), @@ -2200,7 +2212,7 @@ darwin_xfer_partial (struct target_ops *ops, { case TARGET_OBJECT_MEMORY: { - int l = darwin_read_write_inferior (inf->priv->task, offset, + int l = darwin_read_write_inferior (priv->task, offset, readbuf, writebuf, len); if (l == 0) @@ -2219,7 +2231,7 @@ darwin_xfer_partial (struct target_ops *ops, /* Support only read. */ return TARGET_XFER_E_IO; } - return darwin_read_dyld_info (inf->priv->task, offset, readbuf, len, + return darwin_read_dyld_info (priv->task, offset, readbuf, len, xfered_len); #endif default: @@ -2235,6 +2247,7 @@ set_enable_mach_exceptions (const char *args, int from_tty, if (!ptid_equal (inferior_ptid, null_ptid)) { struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); exception_mask_t mask; kern_return_t kret; @@ -2242,10 +2255,10 @@ set_enable_mach_exceptions (const char *args, int from_tty, mask = EXC_MASK_ALL; else { - darwin_restore_exception_ports (inf->priv); + darwin_restore_exception_ports (priv); mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT; } - kret = task_set_exception_ports (inf->priv->task, mask, darwin_ex_port, + kret = task_set_exception_ports (priv->task, mask, darwin_ex_port, EXCEPTION_DEFAULT, THREAD_STATE_NONE); MACH_CHECK_ERROR (kret); } @@ -2267,10 +2280,8 @@ darwin_pid_to_exec_file (struct target_ops *self, int pid) static ptid_t darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread) { - int i; - darwin_thread_t *t; - int k; struct inferior *inf = current_inferior (); + darwin_inferior *priv = get_darwin_inferior (inf); kern_return_t kret; mach_port_name_array_t names; mach_msg_type_number_t names_count; @@ -2279,16 +2290,16 @@ darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread) long res = 0; /* First linear search. */ - for (k = 0; - VEC_iterate (darwin_thread_t, inf->priv->threads, k, t); - k++) - if (t->inf_port == lwp) - return ptid_build (ptid_get_pid (inferior_ptid), 0, t->gdb_port); + for (darwin_thread_t *t : priv->threads) + { + if (t->inf_port == lwp) + return ptid_build (ptid_get_pid (inferior_ptid), 0, t->gdb_port); + } /* Maybe the port was never extract. Do it now. */ /* First get inferior port names. */ - kret = mach_port_names (inf->priv->task, &names, &names_count, &types, + kret = mach_port_names (priv->task, &names, &names_count, &types, &types_count); MACH_CHECK_ERROR (kret); if (kret != KERN_SUCCESS) @@ -2297,29 +2308,29 @@ darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread) /* For each name, copy the right in the gdb space and then compare with our view of the inferior threads. We don't forget to deallocate the right. */ - for (i = 0; i < names_count; i++) + for (int i = 0; i < names_count; i++) { mach_port_t local_name; mach_msg_type_name_t local_type; /* We just need to know the corresponding name in gdb name space. So extract and deallocate the right. */ - kret = mach_port_extract_right (inf->priv->task, names[i], + kret = mach_port_extract_right (priv->task, names[i], MACH_MSG_TYPE_COPY_SEND, &local_name, &local_type); if (kret != KERN_SUCCESS) continue; mach_port_deallocate (gdb_task, local_name); - for (k = 0; - VEC_iterate (darwin_thread_t, inf->priv->threads, k, t); - k++) - if (t->gdb_port == local_name) - { - t->inf_port = names[i]; - if (names[i] == lwp) - res = t->gdb_port; - } + for (darwin_thread_t *t : priv->threads) + { + if (t->gdb_port == local_name) + { + t->inf_port = names[i]; + if (names[i] == lwp) + res = t->gdb_port; + } + } } vm_deallocate (gdb_task, (vm_address_t) names, diff --git a/gdb/darwin-nat.h b/gdb/darwin-nat.h index 77feb0e8f95..db72698aa46 100644 --- a/gdb/darwin-nat.h +++ b/gdb/darwin-nat.h @@ -26,21 +26,20 @@ struct darwin_exception_info { /* Exceptions handled by the port. */ - exception_mask_t masks[EXC_TYPES_COUNT]; + exception_mask_t masks[EXC_TYPES_COUNT] {}; /* Ports receiving exception messages. */ - mach_port_t ports[EXC_TYPES_COUNT]; + mach_port_t ports[EXC_TYPES_COUNT] {}; /* Type of messages sent. */ - exception_behavior_t behaviors[EXC_TYPES_COUNT]; + exception_behavior_t behaviors[EXC_TYPES_COUNT] {}; /* Type of state to be sent. */ - thread_state_flavor_t flavors[EXC_TYPES_COUNT]; + thread_state_flavor_t flavors[EXC_TYPES_COUNT] {}; /* Number of elements set. */ - mach_msg_type_number_t count; + mach_msg_type_number_t count = 0; }; -typedef struct darwin_exception_info darwin_exception_info; struct darwin_exception_msg { @@ -95,36 +94,39 @@ struct private_thread_info }; typedef struct private_thread_info darwin_thread_t; -/* Define the threads vector type. */ -DEF_VEC_O (darwin_thread_t); - - /* Describe an inferior. */ -struct private_inferior +struct darwin_inferior : public private_inferior { /* Corresponding task port. */ - task_t task; + task_t task = 0; /* Port which will receive the dead-name notification for the task port. This is used to detect the death of the task. */ - mach_port_t notify_port; + mach_port_t notify_port = 0; /* Initial exception handling. */ darwin_exception_info exception_info; /* Number of messages that have been received but not yet replied. */ - unsigned int pending_messages; + unsigned int pending_messages = 0; /* Set if inferior is not controlled by ptrace(2) but through Mach. */ - unsigned char no_ptrace; + bool no_ptrace = false; /* True if this task is suspended. */ - unsigned char suspended; + bool suspended = false; /* Sorted vector of known threads. */ - VEC(darwin_thread_t) *threads; + std::vector threads; }; -typedef struct private_inferior darwin_inferior; + +/* Return the darwin_inferior attached to INF. */ + +static inline darwin_inferior * +get_darwin_inferior (inferior *inf) +{ + return static_cast (inf->priv.get ()); +} /* Exception port. */ extern mach_port_t darwin_ex_port; diff --git a/gdb/inferior.c b/gdb/inferior.c index bcac98180a2..9b3043d0099 100644 --- a/gdb/inferior.c +++ b/gdb/inferior.c @@ -71,6 +71,8 @@ set_current_inferior (struct inferior *inf) current_inferior_ = inf; } +private_inferior::~private_inferior () = default; + inferior::~inferior () { inferior *inf = this; @@ -80,7 +82,6 @@ inferior::~inferior () xfree (inf->args); xfree (inf->terminal); target_desc_info_free (inf->tdesc_info); - xfree (inf->priv); } inferior::inferior (int pid_) @@ -209,7 +210,6 @@ exit_inferior_1 (struct inferior *inftoex, int silent) inf->pid = 0; inf->fake_pid_p = 0; - xfree (inf->priv); inf->priv = NULL; if (inf->vfork_parent != NULL) diff --git a/gdb/inferior.h b/gdb/inferior.h index 37252a695cd..0705dd9d753 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -263,7 +263,12 @@ enum stop_kind #define ON_STACK 1 #define AT_ENTRY_POINT 4 -struct private_inferior; +/* Base class for target-specific inferior data. */ + +struct private_inferior +{ + virtual ~private_inferior () = 0; +}; /* Inferior process specific part of `struct infcall_control_state'. @@ -403,7 +408,7 @@ public: bool needs_setup = false; /* Private data used by the target vector implementation. */ - private_inferior *priv = NULL; + std::unique_ptr priv; /* HAS_EXIT_CODE is true if the inferior exited with an exit code. In this case, the EXIT_CODE field is also valid. */ diff --git a/gdb/remote.c b/gdb/remote.c index 62ac0551196..5445bb298bf 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -5826,12 +5826,23 @@ static int is_pending_fork_parent_thread (struct thread_info *thread); /* Private per-inferior info for target remote processes. */ -struct private_inferior +struct remote_inferior : public private_inferior { /* Whether we can send a wildcard vCont for this process. */ - int may_wildcard_vcont; + bool may_wildcard_vcont = true; }; +/* Get the remote private inferior data associated to INF. */ + +static remote_inferior * +get_remote_inferior (inferior *inf) +{ + if (inf->priv == NULL) + inf->priv.reset (new remote_inferior); + + return static_cast (inf->priv.get ()); +} + /* Structure used to track the construction of a vCont packet in the outgoing packet buffer. This is used to send multiple vCont packets if we have more actions than would fit a single packet. */ @@ -5993,9 +6004,9 @@ remote_commit_resume (struct target_ops *ops) /* And assume every process is individually wildcard-able too. */ ALL_NON_EXITED_INFERIORS (inf) { - if (inf->priv == NULL) - inf->priv = XNEW (struct private_inferior); - inf->priv->may_wildcard_vcont = 1; + remote_inferior *priv = get_remote_inferior (inf); + + priv->may_wildcard_vcont = true; } /* Check for any pending events (not reported or processed yet) and @@ -6008,7 +6019,7 @@ remote_commit_resume (struct target_ops *ops) can't wildcard that process. */ if (!tp->executing) { - tp->inf->priv->may_wildcard_vcont = 0; + get_remote_inferior (tp->inf)->may_wildcard_vcont = false; /* And if we can't wildcard a process, we can't wildcard everything either. */ @@ -6042,7 +6053,7 @@ remote_commit_resume (struct target_ops *ops) if (!remote_thr->last_resume_step && remote_thr->last_resume_sig == GDB_SIGNAL_0 - && tp->inf->priv->may_wildcard_vcont) + && get_remote_inferior (tp->inf)->may_wildcard_vcont) { /* We'll send a wildcard resume instead. */ remote_thr->vcont_resumed = 1; @@ -6062,7 +6073,7 @@ remote_commit_resume (struct target_ops *ops) ALL_NON_EXITED_INFERIORS (inf) { - if (inf->priv->may_wildcard_vcont) + if (get_remote_inferior (inf)->may_wildcard_vcont) { any_process_wildcard = 1; break; @@ -6083,7 +6094,7 @@ remote_commit_resume (struct target_ops *ops) { ALL_NON_EXITED_INFERIORS (inf) { - if (inf->priv->may_wildcard_vcont) + if (get_remote_inferior (inf)->may_wildcard_vcont) { vcont_builder_push_action (&vcont_builder, pid_to_ptid (inf->pid), @@ -6579,7 +6590,7 @@ check_pending_event_prevents_wildcard_vcont_callback we'd resume this process too. */ *may_global_wildcard_vcont = 0; if (inf != NULL) - inf->priv->may_wildcard_vcont = 0; + get_remote_inferior (inf)->may_wildcard_vcont = false; return 1; }