From: Antoine Tremblay <antoine.tremblay@ericsson.com>
To: <gdb-patches@sourceware.org>
Subject: Re: [PATCH v2] Remove support for thread events without PTRACE_EVENT_CLONE in GDB.
Date: Thu, 10 Dec 2015 15:49:00 -0000 [thread overview]
Message-ID: <56699F0E.3020301@ericsson.com> (raw)
In-Reply-To: <1449760930-23203-1-git-send-email-antoine.tremblay@ericsson.com>
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) <td_create_bp_addr>: Remove.
> <td_death_bp_addr>: Likewise.
> <td_ta_event_addr_p>: Likewise.
> <td_ta_set_event_p>: Likewise.
> <td_ta_clear_event_p>: Likewise.
> <td_ta_event_getmsg_p>: Likewise.
> <td_thr_event_enable_p>: 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);
> -\f
> -
> /* 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;
> }
> }
> -\f
> -/* 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;
> -}
>
> -\f
> /* 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)
next prev parent reply other threads:[~2015-12-10 15:49 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-10 15:22 Antoine Tremblay
2015-12-10 15:35 ` Pedro Alves
2015-12-10 15:49 ` Antoine Tremblay [this message]
2015-12-10 17:45 ` Pedro Alves
2015-12-10 17:57 ` Antoine Tremblay
2015-12-10 18:00 ` Pedro Alves
2015-12-10 18:08 ` Antoine Tremblay
2015-12-10 18:16 ` Pedro Alves
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56699F0E.3020301@ericsson.com \
--to=antoine.tremblay@ericsson.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox