From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12440 invoked by alias); 10 Dec 2015 15:49:43 -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 12425 invoked by uid 89); 10 Dec 2015 15:49:41 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: usplmg21.ericsson.net Received: from usplmg21.ericsson.net (HELO usplmg21.ericsson.net) (198.24.6.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 10 Dec 2015 15:49:37 +0000 Received: from EUSAAHC003.ericsson.se (Unknown_Domain [147.117.188.81]) by usplmg21.ericsson.net (Symantec Mail Security) with SMTP id EE.8B.32102.A0F99665; Thu, 10 Dec 2015 16:49:30 +0100 (CET) Received: from [142.133.110.95] (147.117.188.8) by smtp-am.internal.ericsson.com (147.117.188.83) with Microsoft SMTP Server id 14.3.248.2; Thu, 10 Dec 2015 10:49:34 -0500 Subject: Re: [PATCH v2] Remove support for thread events without PTRACE_EVENT_CLONE in GDB. To: References: <1449760930-23203-1-git-send-email-antoine.tremblay@ericsson.com> From: Antoine Tremblay Message-ID: <56699F0E.3020301@ericsson.com> Date: Thu, 10 Dec 2015 15:49:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 In-Reply-To: <1449760930-23203-1-git-send-email-antoine.tremblay@ericsson.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2015-12/txt/msg00194.txt.bz2 On 12/10/2015 10:22 AM, Antoine Tremblay wrote: > Before, on systems that did not support PTRACE_EVENT_CLONE, both GDB and > GDBServer coordinated with libthread_db.so to insert breakpoints at magic > locations in libpthread.so, in order to break at thread creation and > thread death. > > Support for thread events was removed from GDBServer as patch: > https://sourceware.org/ml/gdb-patches/2015-11/msg00466.html > > This patch removes support for thread events in GDB. > > No regressions found on Ubuntu 14.04 x86_64. > > gdb/ChangeLog: > * breakpoint.c (remove_thread_event_breakpoints): Remove. > * breakpoint.h (remove_thread_event_breakpoints): Remove > declaration. > * linux-nat.c (in_pid_list_p): Remove. > (lin_lwp_attach_lwp): Remove. > * linux-nat.h (lin_lwp_attach_lwp): Remove declaration. > * linux-thread-db.c (thread_db_use_events): Remove. > (struct thread_db_info) : Remove. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > : Likewise. > (attach_thread): Likewise. > (detach_thread): Likewise. > (have_threads_callback): Likewise. > (have_threads): Likewise. > (enable_thread_event): Likewise. > (enable_thread_event_reporting): Likewise. > (try_thread_db_load_1): Remove td_ta_event_addr, td_ta_set_event, > td_ta_clear_event, td_ta_event_getmsg, td_thr_event_enable > initializations. > (try_thread_db_load_1): Remove enable_thread_event_reporting call. > (disable_thread_event_reporting): Remove. > (record_thread): Adapt to thread_db_use_event removal. > (detach_thread): Remove. > (thread_db_detach): Adapt to thread_db_use_event removal. > (check_event): Remove. > (thread_db_wait): Adapt to thread events support removal. > (thread_db_mourn_inferior): Likewise. > (find_new_threads_callback): Likewise. > (find_new_threads_once): Likewise. > (thread_db_update_thread_list): Likewise. > --- > gdb/breakpoint.c | 11 -- > gdb/breakpoint.h | 2 - > gdb/linux-nat.c | 144 ----------------- > gdb/linux-nat.h | 2 - > gdb/linux-thread-db.c | 437 ++------------------------------------------------ > 5 files changed, 9 insertions(+), 587 deletions(-) > > diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c > index bc6b2ef..f105042 100644 > --- a/gdb/breakpoint.c > +++ b/gdb/breakpoint.c > @@ -7765,17 +7765,6 @@ create_thread_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address) > return b; > } > > -void > -remove_thread_event_breakpoints (void) > -{ > - struct breakpoint *b, *b_tmp; > - > - ALL_BREAKPOINTS_SAFE (b, b_tmp) > - if (b->type == bp_thread_event > - && b->loc->pspace == current_program_space) > - delete_breakpoint (b); > -} > - > struct lang_and_radix > { > enum language lang; > diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h > index ee8b2e0..7079b75 100644 > --- a/gdb/breakpoint.h > +++ b/gdb/breakpoint.h > @@ -1498,8 +1498,6 @@ extern void remove_solib_event_breakpoints (void); > delete at next stop disposition. */ > extern void remove_solib_event_breakpoints_at_next_stop (void); > > -extern void remove_thread_event_breakpoints (void); > - > extern void disable_breakpoints_in_shlibs (void); > > /* This function returns TRUE if ep is a catchpoint. */ > diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c > index 9bc1324..95192f6 100644 > --- a/gdb/linux-nat.c > +++ b/gdb/linux-nat.c > @@ -345,17 +345,6 @@ add_to_pid_list (struct simple_pid_list **listp, int pid, int status) > } > > static int > -in_pid_list_p (struct simple_pid_list *list, int pid) > -{ > - struct simple_pid_list *p; > - > - for (p = list; p != NULL; p = p->next) > - if (p->pid == pid) > - return 1; > - return 0; > -} > - > -static int > pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp) > { > struct simple_pid_list **p; > @@ -1044,139 +1033,6 @@ linux_nat_post_attach_wait (ptid_t ptid, int first, int *cloned, > return status; > } > > -/* Attach to the LWP specified by PID. Return 0 if successful, -1 if > - the new LWP could not be attached, or 1 if we're already auto > - attached to this thread, but haven't processed the > - PTRACE_EVENT_CLONE event of its parent thread, so we just ignore > - its existance, without considering it an error. */ > - > -int > -lin_lwp_attach_lwp (ptid_t ptid) > -{ > - struct lwp_info *lp; > - int lwpid; > - > - gdb_assert (ptid_lwp_p (ptid)); > - > - lp = find_lwp_pid (ptid); > - lwpid = ptid_get_lwp (ptid); > - > - /* We assume that we're already attached to any LWP that is already > - in our list of LWPs. If we're not seeing exit events from threads > - and we've had PID wraparound since we last tried to stop all threads, > - this assumption might be wrong; fortunately, this is very unlikely > - to happen. */ > - if (lp == NULL) > - { > - int status, cloned = 0, signalled = 0; > - > - if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) < 0) > - { > - if (linux_supports_tracefork ()) > - { > - /* If we haven't stopped all threads when we get here, > - we may have seen a thread listed in thread_db's list, > - but not processed the PTRACE_EVENT_CLONE yet. If > - that's the case, ignore this new thread, and let > - normal event handling discover it later. */ > - if (in_pid_list_p (stopped_pids, lwpid)) > - { > - /* We've already seen this thread stop, but we > - haven't seen the PTRACE_EVENT_CLONE extended > - event yet. */ > - if (debug_linux_nat) > - fprintf_unfiltered (gdb_stdlog, > - "LLAL: attach failed, but already seen " > - "this thread %s stop\n", > - target_pid_to_str (ptid)); > - return 1; > - } > - else > - { > - int new_pid; > - int status; > - > - if (debug_linux_nat) > - fprintf_unfiltered (gdb_stdlog, > - "LLAL: attach failed, and haven't seen " > - "this thread %s stop yet\n", > - target_pid_to_str (ptid)); > - > - /* We may or may not be attached to the LWP already. > - Try waitpid on it. If that errors, we're not > - attached to the LWP yet. Otherwise, we're > - already attached. */ > - gdb_assert (lwpid > 0); > - new_pid = my_waitpid (lwpid, &status, WNOHANG); > - if (new_pid == -1 && errno == ECHILD) > - new_pid = my_waitpid (lwpid, &status, __WCLONE | WNOHANG); > - if (new_pid != -1) > - { > - if (new_pid == 0) > - { > - /* The child hasn't stopped for its initial > - SIGSTOP stop yet. */ > - if (debug_linux_nat) > - fprintf_unfiltered (gdb_stdlog, > - "LLAL: child hasn't " > - "stopped yet\n"); > - } > - else if (WIFSTOPPED (status)) > - { > - if (debug_linux_nat) > - fprintf_unfiltered (gdb_stdlog, > - "LLAL: adding to stopped_pids\n"); > - add_to_pid_list (&stopped_pids, lwpid, status); > - } > - return 1; > - } > - } > - } > - > - /* If we fail to attach to the thread, issue a warning, > - but continue. One way this can happen is if thread > - creation is interrupted; as of Linux kernel 2.6.19, a > - bug may place threads in the thread list and then fail > - to create them. */ > - warning (_("Can't attach %s: %s"), target_pid_to_str (ptid), > - safe_strerror (errno)); > - return -1; > - } > - > - if (debug_linux_nat) > - fprintf_unfiltered (gdb_stdlog, > - "LLAL: PTRACE_ATTACH %s, 0, 0 (OK)\n", > - target_pid_to_str (ptid)); > - > - status = linux_nat_post_attach_wait (ptid, 0, &cloned, &signalled); > - if (!WIFSTOPPED (status)) > - return 1; > - > - lp = add_lwp (ptid); > - lp->stopped = 1; > - lp->last_resume_kind = resume_stop; > - lp->cloned = cloned; > - lp->signalled = signalled; > - if (WSTOPSIG (status) != SIGSTOP) > - { > - lp->resumed = 1; > - lp->status = status; > - } > - > - target_post_attach (ptid_get_lwp (lp->ptid)); > - > - if (debug_linux_nat) > - { > - fprintf_unfiltered (gdb_stdlog, > - "LLAL: waitpid %s received %s\n", > - target_pid_to_str (ptid), > - status_to_str (status)); > - } > - } > - > - return 0; > -} > - > static void > linux_nat_create_inferior (struct target_ops *ops, > char *exec_file, char *allargs, char **env, > diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h > index f7b45f7..f5ec74e 100644 > --- a/gdb/linux-nat.h > +++ b/gdb/linux-nat.h > @@ -141,8 +141,6 @@ extern void lin_thread_get_thread_signals (sigset_t *mask); > void linux_proc_pending_signals (int pid, sigset_t *pending, > sigset_t *blocked, sigset_t *ignored); > > -extern int lin_lwp_attach_lwp (ptid_t ptid); > - > /* For linux_stop_lwp see nat/linux-nat.h. */ > > /* Stop all LWPs, synchronously. (Any events that trigger while LWPs > diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c > index 229bb0b..8a80ca3 100644 > --- a/gdb/linux-thread-db.c > +++ b/gdb/linux-thread-db.c > @@ -78,16 +78,6 @@ static char *libthread_db_search_path; > by the "set auto-load libthread-db" command. */ > static int auto_load_thread_db = 1; > > -/* Returns true if we need to use thread_db thread create/death event > - breakpoints to learn about threads. */ > - > -static int > -thread_db_use_events (void) > -{ > - /* Not necessary if the kernel supports clone events. */ > - return !linux_supports_traceclone (); > -} > - > /* "show" command for the auto_load_thread_db configuration variable. */ > > static void > @@ -161,30 +151,14 @@ struct thread_db_info > be able to ignore such stale entries. */ > int need_stale_parent_threads_check; > > - /* Location of the thread creation event breakpoint. The code at > - this location in the child process will be called by the pthread > - library whenever a new thread is created. By setting a special > - breakpoint at this location, GDB can detect when a new thread is > - created. We obtain this location via the td_ta_event_addr > - call. */ > - CORE_ADDR td_create_bp_addr; > - > - /* Location of the thread death event breakpoint. */ > - CORE_ADDR td_death_bp_addr; > - > /* Pointers to the libthread_db functions. */ > > td_init_ftype *td_init_p; > td_ta_new_ftype *td_ta_new_p; > td_ta_map_lwp2thr_ftype *td_ta_map_lwp2thr_p; > td_ta_thr_iter_ftype *td_ta_thr_iter_p; > - td_ta_event_addr_ftype *td_ta_event_addr_p; > - td_ta_set_event_ftype *td_ta_set_event_p; > - td_ta_clear_event_ftype *td_ta_clear_event_p; > - td_ta_event_getmsg_ftype * td_ta_event_getmsg_p; > td_thr_validate_ftype *td_thr_validate_p; > td_thr_get_info_ftype *td_thr_get_info_p; > - td_thr_event_enable_ftype *td_thr_event_enable_p; > td_thr_tls_get_addr_ftype *td_thr_tls_get_addr_p; > td_thr_tlsbase_ftype *td_thr_tlsbase_p; > }; > @@ -273,12 +247,6 @@ delete_thread_db_info (int pid) > xfree (info); > } > > -/* Prototypes for local functions. */ > -static int attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, > - const td_thrinfo_t *ti_p); > -static void detach_thread (ptid_t ptid); > - > - > /* Use "struct private_thread_info" to cache thread state. This is > a substantial optimization. */ > > @@ -359,30 +327,7 @@ thread_db_err_str (td_err_e err) > return buf; > } > } > - > -/* Return 1 if any threads have been registered. There may be none if > - the threading library is not fully initialized yet. */ > - > -static int > -have_threads_callback (struct thread_info *thread, void *args) > -{ > - int pid = * (int *) args; > - > - if (ptid_get_pid (thread->ptid) != pid) > - return 0; > - > - return thread->priv != NULL; > -} > - > -static int > -have_threads (ptid_t ptid) > -{ > - int pid = ptid_get_pid (ptid); > - > - return iterate_over_threads (have_threads_callback, &pid) != NULL; > -} > > - > /* Fetch the user-level thread id of PTID. */ > > static struct thread_info * > @@ -455,37 +400,6 @@ verbose_dlsym (void *handle, const char *name) > return sym; > } > > -static td_err_e > -enable_thread_event (td_event_e event, CORE_ADDR *bp) > -{ > - td_notify_t notify; > - td_err_e err; > - struct thread_db_info *info; > - > - info = get_thread_db_info (ptid_get_pid (inferior_ptid)); > - > - /* Access an lwp we know is stopped. */ > - info->proc_handle.ptid = inferior_ptid; > - > - /* Get the breakpoint address for thread EVENT. */ > - err = info->td_ta_event_addr_p (info->thread_agent, event, ¬ify); > - if (err != TD_OK) > - return err; > - > - /* Set up the breakpoint. */ > - gdb_assert (exec_bfd); > - (*bp) = (gdbarch_convert_from_func_ptr_addr > - (target_gdbarch (), > - /* Do proper sign extension for the target. */ > - (bfd_get_sign_extend_vma (exec_bfd) > 0 > - ? (CORE_ADDR) (intptr_t) notify.u.bptaddr > - : (CORE_ADDR) (uintptr_t) notify.u.bptaddr), > - ¤t_target)); > - create_thread_event_breakpoint (target_gdbarch (), *bp); > - > - return TD_OK; > -} > - > /* Verify inferior's '\0'-terminated symbol VER_SYMBOL starts with "%d.%d" and > return 1 if this version is lower (and not equal) to > VER_MAJOR_MIN.VER_MINOR_MIN. Return 0 in all other cases. */ > @@ -517,68 +431,6 @@ inferior_has_bug (const char *ver_symbol, int ver_major_min, int ver_minor_min) > return retval; > } > > -static void > -enable_thread_event_reporting (void) > -{ > - td_thr_events_t events; > - td_err_e err; > - struct thread_db_info *info; > - > - info = get_thread_db_info (ptid_get_pid (inferior_ptid)); > - > - /* We cannot use the thread event reporting facility if these > - functions aren't available. */ > - if (info->td_ta_event_addr_p == NULL > - || info->td_ta_set_event_p == NULL > - || info->td_ta_event_getmsg_p == NULL > - || info->td_thr_event_enable_p == NULL) > - return; > - > - /* Set the process wide mask saying which events we're interested in. */ > - td_event_emptyset (&events); > - td_event_addset (&events, TD_CREATE); > - > - /* There is a bug fixed between linuxthreads 2.1.3 and 2.2 by > - commit 2e4581e4fba917f1779cd0a010a45698586c190a > - * manager.c (pthread_exited): Correctly report event as TD_REAP > - instead of TD_DEATH. Fix comments. > - where event reporting facility is broken for TD_DEATH events, > - so don't enable it if we have glibc but a lower version. */ > - if (!inferior_has_bug ("__linuxthreads_version", 2, 2)) > - td_event_addset (&events, TD_DEATH); > - > - err = info->td_ta_set_event_p (info->thread_agent, &events); > - if (err != TD_OK) > - { > - warning (_("Unable to set global thread event mask: %s"), > - thread_db_err_str (err)); > - return; > - } > - > - /* Delete previous thread event breakpoints, if any. */ > - remove_thread_event_breakpoints (); > - info->td_create_bp_addr = 0; > - info->td_death_bp_addr = 0; > - > - /* Set up the thread creation event. */ > - err = enable_thread_event (TD_CREATE, &info->td_create_bp_addr); > - if (err != TD_OK) > - { > - warning (_("Unable to get location for thread creation breakpoint: %s"), > - thread_db_err_str (err)); > - return; > - } > - > - /* Set up the thread death event. */ > - err = enable_thread_event (TD_DEATH, &info->td_death_bp_addr); > - if (err != TD_OK) > - { > - warning (_("Unable to get location for thread death breakpoint: %s"), > - thread_db_err_str (err)); > - return; > - } > -} > - > /* Similar as thread_db_find_new_threads_1, but try to silently ignore errors > if appropriate. > > @@ -716,11 +568,6 @@ try_thread_db_load_1 (struct thread_db_info *info) > CHK (TDB_VERBOSE_DLSYM (info, td_thr_get_info)); > > /* These are not essential. */ > - TDB_DLSYM (info, td_ta_event_addr); > - TDB_DLSYM (info, td_ta_set_event); > - TDB_DLSYM (info, td_ta_clear_event); > - TDB_DLSYM (info, td_ta_event_getmsg); > - TDB_DLSYM (info, td_thr_event_enable); > TDB_DLSYM (info, td_thr_tls_get_addr); > TDB_DLSYM (info, td_thr_tlsbase); > > @@ -784,10 +631,6 @@ try_thread_db_load_1 (struct thread_db_info *info) > if (thread_db_list->next == NULL) > push_target (&thread_db_ops); > > - /* Enable event reporting, but not when debugging a core file. */ > - if (target_has_execution && thread_db_use_events ()) > - enable_thread_event_reporting (); > - > return 1; > } > > @@ -1096,23 +939,6 @@ thread_db_load (void) > } > > static void > -disable_thread_event_reporting (struct thread_db_info *info) > -{ > - if (info->td_ta_clear_event_p != NULL) > - { > - td_thr_events_t events; > - > - /* Set the process wide mask saying we aren't interested in any > - events anymore. */ > - td_event_fillset (&events); > - info->td_ta_clear_event_p (info->thread_agent, &events); > - } > - > - info->td_create_bp_addr = 0; > - info->td_death_bp_addr = 0; > -} > - > -static void > check_thread_signals (void) > { > if (!thread_signals) > @@ -1219,75 +1045,6 @@ update_thread_state (struct private_thread_info *priv, > || ti_p->ti_state == TD_THR_ZOMBIE); > } > > -/* Attach to a new thread. This function is called when we receive a > - TD_CREATE event or when we iterate over all threads and find one > - that wasn't already in our list. Returns true on success. */ > - > -static int > -attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, > - const td_thrinfo_t *ti_p) > -{ > - struct thread_info *tp; > - struct thread_db_info *info; > - > - /* If we're being called after a TD_CREATE event, we may already > - know about this thread. There are two ways this can happen. We > - may have iterated over all threads between the thread creation > - and the TD_CREATE event, for instance when the user has issued > - the `info threads' command before the SIGTRAP for hitting the > - thread creation breakpoint was reported. Alternatively, the > - thread may have exited and a new one been created with the same > - thread ID. In the first case we don't need to do anything; in > - the second case we should discard information about the dead > - thread and attach to the new one. */ > - tp = find_thread_ptid (ptid); > - if (tp != NULL) > - { > - /* If tp->priv is NULL, then GDB is already attached to this > - thread, but we do not know anything about it. We can learn > - about it here. This can only happen if we have some other > - way besides libthread_db to notice new threads (i.e. > - PTRACE_EVENT_CLONE); assume the same mechanism notices thread > - exit, so this can not be a stale thread recreated with the > - same ID. */ > - if (tp->priv != NULL) > - { > - if (!tp->priv->dying) > - return 0; > - > - delete_thread (ptid); > - tp = NULL; > - } > - } > - > - /* Under GNU/Linux, we have to attach to each and every thread. */ > - if (target_has_execution > - && tp == NULL) > - { > - int res; > - > - res = lin_lwp_attach_lwp (ptid_build (ptid_get_pid (ptid), > - ti_p->ti_lid, 0)); > - if (res < 0) > - { > - /* Error, stop iterating. */ > - return 0; > - } > - else if (res > 0) > - { > - /* Pretend this thread doesn't exist yet, and keep > - iterating. */ > - return 1; > - } > - > - /* Otherwise, we sucessfully attached to the thread. */ > - } > - > - info = get_thread_db_info (ptid_get_pid (ptid)); > - record_thread (info, tp, ptid, th_p, ti_p); > - return 1; > -} > - > /* Record a new thread in GDB's thread list. Creates the thread's > private info. If TP is NULL or TP is marked as having exited, > creates a new thread. Otherwise, uses TP. */ > @@ -1323,16 +1080,6 @@ record_thread (struct thread_db_info *info, > else > tp->priv = priv; > > - /* Enable thread event reporting for this thread, except when > - debugging a core file. */ > - if (target_has_execution && thread_db_use_events () && new_thread) > - { > - err = info->td_thr_event_enable_p (th_p, 1); > - if (err != TD_OK) > - error (_("Cannot enable thread event reporting for %s: %s"), > - target_pid_to_str (ptid), thread_db_err_str (err)); > - } > - > if (target_has_execution) > check_thread_signals (); > > @@ -1340,24 +1087,6 @@ record_thread (struct thread_db_info *info, > } > > static void > -detach_thread (ptid_t ptid) > -{ > - struct thread_info *thread_info; > - > - /* Don't delete the thread now, because it still reports as active > - until it has executed a few instructions after the event > - breakpoint - if we deleted it now, "info threads" would cause us > - to re-attach to it. Just mark it as having had a TD_DEATH > - event. This means that we won't delete it from our thread list > - until we notice that it's dead (via prune_threads), or until > - something re-uses its thread ID. We'll report the thread exit > - when the underlying LWP dies. */ > - thread_info = find_thread_ptid (ptid); > - gdb_assert (thread_info != NULL && thread_info->priv != NULL); > - thread_info->priv->dying = 1; > -} > - > -static void > thread_db_detach (struct target_ops *ops, const char *args, int from_tty) > { > struct target_ops *target_beneath = find_target_beneath (ops); > @@ -1366,21 +1095,7 @@ thread_db_detach (struct target_ops *ops, const char *args, int from_tty) > info = get_thread_db_info (ptid_get_pid (inferior_ptid)); > > if (info) > - { > - if (target_has_execution && thread_db_use_events ()) > - { > - disable_thread_event_reporting (info); > - > - /* Delete the old thread event breakpoints. Note that > - unlike when mourning, we can remove them here because > - there's still a live inferior to poke at. In any case, > - GDB will not try to insert anything in the inferior when > - removing a breakpoint. */ > - remove_thread_event_breakpoints (); > - } > - > - delete_thread_db_info (ptid_get_pid (inferior_ptid)); > - } > + delete_thread_db_info (ptid_get_pid (inferior_ptid)); > > target_beneath->to_detach (target_beneath, args, from_tty); > > @@ -1392,101 +1107,6 @@ thread_db_detach (struct target_ops *ops, const char *args, int from_tty) > unpush_target (&thread_db_ops); > } > > -/* Check if PID is currently stopped at the location of a thread event > - breakpoint location. If it is, read the event message and act upon > - the event. */ > - > -static void > -check_event (ptid_t ptid) > -{ > - struct regcache *regcache = get_thread_regcache (ptid); > - struct gdbarch *gdbarch = get_regcache_arch (regcache); > - td_event_msg_t msg; > - td_thrinfo_t ti; > - td_err_e err; > - CORE_ADDR stop_pc; > - int loop = 0; > - struct thread_db_info *info; > - > - info = get_thread_db_info (ptid_get_pid (ptid)); > - > - /* Bail out early if we're not at a thread event breakpoint. */ > - stop_pc = regcache_read_pc (regcache); > - if (!target_supports_stopped_by_sw_breakpoint ()) > - stop_pc -= gdbarch_decr_pc_after_break (gdbarch); > - > - if (stop_pc != info->td_create_bp_addr > - && stop_pc != info->td_death_bp_addr) > - return; > - > - /* Access an lwp we know is stopped. */ > - info->proc_handle.ptid = ptid; > - > - /* If we have only looked at the first thread before libpthread was > - initialized, we may not know its thread ID yet. Make sure we do > - before we add another thread to the list. */ > - if (!have_threads (ptid)) > - thread_db_find_new_threads_1 (ptid); > - > - /* If we are at a create breakpoint, we do not know what new lwp > - was created and cannot specifically locate the event message for it. > - We have to call td_ta_event_getmsg() to get > - the latest message. Since we have no way of correlating whether > - the event message we get back corresponds to our breakpoint, we must > - loop and read all event messages, processing them appropriately. > - This guarantees we will process the correct message before continuing > - from the breakpoint. > - > - Currently, death events are not enabled. If they are enabled, > - the death event can use the td_thr_event_getmsg() interface to > - get the message specifically for that lwp and avoid looping > - below. */ > - > - loop = 1; > - > - do > - { > - err = info->td_ta_event_getmsg_p (info->thread_agent, &msg); > - if (err != TD_OK) > - { > - if (err == TD_NOMSG) > - return; > - > - error (_("Cannot get thread event message: %s"), > - thread_db_err_str (err)); > - } > - > - err = info->td_thr_get_info_p (msg.th_p, &ti); > - if (err != TD_OK) > - error (_("Cannot get thread info: %s"), thread_db_err_str (err)); > - > - ptid = ptid_build (ptid_get_pid (ptid), ti.ti_lid, 0); > - > - switch (msg.event) > - { > - case TD_CREATE: > - /* Call attach_thread whether or not we already know about a > - thread with this thread ID. */ > - attach_thread (ptid, msg.th_p, &ti); > - > - break; > - > - case TD_DEATH: > - > - if (!in_thread_list (ptid)) > - error (_("Spurious thread death event.")); > - > - detach_thread (ptid); > - > - break; > - > - default: > - error (_("Spurious thread event.")); > - } > - } > - while (loop); > -} > - > static ptid_t > thread_db_wait (struct target_ops *ops, > ptid_t ptid, struct target_waitstatus *ourstatus, > @@ -1518,17 +1138,9 @@ thread_db_wait (struct target_ops *ops, > if (!thread_db_list) > unpush_target (&thread_db_ops); > > - /* Thread event breakpoints are deleted by > - update_breakpoints_after_exec. */ > - > return ptid; > } > > - if (ourstatus->kind == TARGET_WAITKIND_STOPPED > - && ourstatus->value.sig == GDB_SIGNAL_TRAP) > - /* Check for a thread event. */ > - check_event (ptid); > - > /* Fill in the thread's user-level thread id and status. */ > thread_from_lwp (ptid); > > @@ -1544,10 +1156,6 @@ thread_db_mourn_inferior (struct target_ops *ops) > > target_beneath->to_mourn_inferior (target_beneath); > > - /* Delete the old thread event breakpoints. Do this after mourning > - the inferior, so that we don't try to uninsert them. */ > - remove_thread_event_breakpoints (); > - > /* Detach thread_db target ops. */ > if (!thread_db_list) > unpush_target (ops); > @@ -1595,21 +1203,12 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data) > /* A thread ID of zero means that this is the main thread, but > glibc has not yet initialized thread-local storage and the > pthread library. We do not know what the thread's TID will > - be yet. Just enable event reporting and otherwise ignore > - it. */ > + be yet. */ > > /* In that case, we're not stopped in a fork syscall and don't > need this glibc bug workaround. */ > info->need_stale_parent_threads_check = 0; > > - if (target_has_execution && thread_db_use_events ()) > - { > - err = info->td_thr_event_enable_p (th_p, 1); > - if (err != TD_OK) > - error (_("Cannot enable thread event reporting for LWP %d: %s"), > - (int) ti.ti_lid, thread_db_err_str (err)); > - } > - > return 0; > } > > @@ -1627,24 +1226,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data) > ptid = ptid_build (info->pid, ti.ti_lid, 0); > tp = find_thread_ptid (ptid); > if (tp == NULL || tp->priv == NULL) > - { > - if (attach_thread (ptid, th_p, &ti)) > - cb_data->new_threads += 1; > - else > - /* Problem attaching this thread; perhaps it exited before we > - could attach it? > - This could mean that the thread list inside glibc itself is in > - inconsistent state, and libthread_db could go on looping forever > - (observed with glibc-2.3.6). To prevent that, terminate > - iteration: thread_db_find_new_threads_2 will retry. */ > - return 1; > - } > - else if (target_has_execution && !thread_db_use_events ()) > - { > - /* Need to update this if not using the libthread_db events > - (particularly, the TD_DEATH event). */ > - update_thread_state (tp->priv, &ti); > - } > + thread_from_lwp (ptid); > > return 0; > } > @@ -1663,7 +1245,7 @@ find_new_threads_once (struct thread_db_info *info, int iteration, > data.new_threads = 0; > > /* See comment in thread_db_update_thread_list. */ > - gdb_assert (!target_has_execution || thread_db_use_events ()); > + gdb_assert (!target_has_execution); > > TRY > { > @@ -1789,12 +1371,11 @@ thread_db_update_thread_list (struct target_ops *ops) > it. In the latter case, it's possible that a thread exits just > at the exact time that causes GDB to get stuck in an infinite > loop. To avoid pausing all threads whenever the core wants to > - refresh the thread list, if the kernel supports clone events > - (meaning we're always already attached to all LWPs), we use > - thread_from_lwp immediately when we see an LWP stop. That uses > - thread_db entry points that do not walk libpthread's thread list, > - so should be safe, as well as more efficient. */ > - if (target_has_execution && !thread_db_use_events ()) > + refresh the thread list, use thread_from_lwp immediately when we > + see an LWP stop. That uses thread_db entry points that do not > + walk libpthread's thread list, so should be safe, as well as > + more efficient. */ > + if (target_has_execution) > ops->beneath->to_update_thread_list (ops->beneath); > else > thread_db_update_thread_list_td_ta_thr_iter (ops); > Pushed in. (Without the dot at the end of the subject)