From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 38505 invoked by alias); 22 Nov 2017 22:20:44 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 38485 invoked by uid 89); 22 Nov 2017 22:20:44 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KB_WAM_FROM_NAME_SINGLEWORD,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=Xavier, xavier X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 22 Nov 2017 22:20:38 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 3B319116562; Wed, 22 Nov 2017 17:20:37 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id W6+M2LEq30Sp; Wed, 22 Nov 2017 17:20:37 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id D271C11654F; Wed, 22 Nov 2017 17:20:36 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id 2589187459; Wed, 22 Nov 2017 14:20:35 -0800 (PST) Date: Wed, 22 Nov 2017 22:20:00 -0000 From: Joel Brobecker To: Xavier Roirand Cc: gdb-patches@sourceware.org, Simon Marchi , Jerome Guitton Subject: Re: [PATCH 1/4] Create private_inferior class hierarchy Message-ID: <20171122222035.t6d7wxxxel4wfbo6@adacore.com> References: <1511368867-19365-1-git-send-email-simon.marchi@ericsson.com> <1511368867-19365-2-git-send-email-simon.marchi@ericsson.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1511368867-19365-2-git-send-email-simon.marchi@ericsson.com> User-Agent: NeoMutt/20170113 (1.7.2) X-SW-Source: 2017-11/txt/msg00519.txt.bz2 Hey Xavier, Could you look at Simon's message below, and maybe review/test his changes? Thank you! On Wed, Nov 22, 2017 at 11:41:04AM -0500, Simon Marchi wrote: > 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. > : 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. > --- > gdb/darwin-nat-info.c | 50 +++++---- > gdb/darwin-nat.c | 287 ++++++++++++++++++++++++++------------------------ > gdb/darwin-nat.h | 30 +++--- > gdb/inferior.c | 4 +- > gdb/inferior.h | 9 +- > gdb/remote.c | 30 ++++-- > 6 files changed, 218 insertions(+), 192 deletions(-) > > diff --git a/gdb/darwin-nat-info.c b/gdb/darwin-nat-info.c > index 44782bf..feab181 100644 > --- a/gdb/darwin-nat-info.c > +++ b/gdb/darwin-nat-info.c > @@ -118,7 +118,11 @@ 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 > + = (darwin_inferior *) current_inferior ()->priv.get (); > + > + return priv->task; > } > if (strcmp (args, "gdb") == 0) > return mach_task_self (); > @@ -257,36 +261,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 = (darwin_inferior *) inf->priv.get (); > > - 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 +737,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 = (darwin_inferior *) inf->priv.get (); > + darwin_debug_region (priv->task, address); > } > > static void > @@ -807,7 +807,11 @@ 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 > + = (darwin_inferior *) current_inferior ()->priv.get (); > + > + disp_exception (&priv->exception_info); > return; > } > else if (strcmp (args, "host") == 0) > @@ -830,8 +834,10 @@ info_mach_exceptions_command (const char *args, int from_tty) > printf_unfiltered (_("No inferior running\n")); > inf = current_inferior (); > > + darwin_inferior *priv = (darwin_inferior *) inf->priv.get (); > + > 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 6e420c4..f4ed455 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 = (darwin_inferior *) inf->priv.get (); > + 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > + > /* 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 = (darwin_inferior *) inf->priv.get (); > + > /* 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 = (darwin_inferior *) inf->priv.get (); > > 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 = (darwin_inferior *) inf->priv.get (); > > - 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 = (darwin_inferior *) inf->priv.get (); > > - 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > + > 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 = (darwin_inferior *) inf->priv.get (); > > /* 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > 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 = (darwin_inferior *) inf->priv.get (); > > - 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 = (darwin_inferior *) inf->priv.get (); > > 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 = (darwin_inferior *) inf->priv.get (); > 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 = (darwin_inferior *) inf->priv.get (); > 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 = (darwin_inferior *) inf->priv.get (); > 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 = (darwin_inferior *) inf->priv.get (); > > - 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 = (darwin_inferior *) inf->priv.get (); > 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 = (darwin_inferior *) inf->priv.get (); > + > + 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 = (darwin_inferior *) inf->priv.get (); > 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 = (darwin_inferior *) inf->priv.get (); > > 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 = (darwin_inferior *) inf->priv.get (); > 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 = (darwin_inferior *) inf->priv.get (); > 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 77feb0e..24c10b5 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,31 @@ 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; > > /* Exception port. */ > extern mach_port_t darwin_ex_port; > diff --git a/gdb/inferior.c b/gdb/inferior.c > index bcac981..9b3043d 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 37252a6..0705dd9 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 62ac055..f328080 100644 > --- a/gdb/remote.c > +++ b/gdb/remote.c > @@ -5826,12 +5826,22 @@ 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 (remote_inferior *) 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 +6003,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 +6018,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 +6052,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 +6072,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 +6093,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 +6589,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; > } > -- > 2.7.4 -- Joel