* [linux] fix stepping over fork in follow-child mode.
@ 2008-03-18 20:47 Pedro Alves
2008-03-18 23:48 ` Daniel Jacobowitz
0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2008-03-18 20:47 UTC (permalink / raw)
To: GDB Patches
[-- Attachment #1: Type: text/plain, Size: 971 bytes --]
Hi,
I noticed that issuing a next over a fork call, with
"follow-fork-mode child", wasn't working. The problem is that when we
update the breakpoints in the child to attach them to the current thread
if their thread their currently attached to doesn't exist anymore,
inferior_ptid doesn't hold the tid yet.
static int
linux_child_follow_fork (struct target_ops *ops, int follow_child)
(...)
inferior_ptid = ptid_build (child_pid, child_pid, 0);
/* Reinstall ourselves, since we might have been removed in
target_detach (which does other necessary cleanup). */
push_target (ops);
linux_nat_switch_fork (inferior_ptid);
check_for_thread_db ();
/* Reset breakpoints in the child as appropriate. */
follow_inferior_reset_breakpoints (); <- this would fail
}
The patch attached updates fork-child-threads.exp with a
test that would fail without the fix.
No regressions on x86_64-unknown-linux-gnu.
--
Pedro Alves
[-- Attachment #2: follow_fork_child_step_resume.diff --]
[-- Type: text/x-diff, Size: 2224 bytes --]
2008-03-18 Pedro Alves <pedro@codesourcery.com>
gdb/
* linux-nat.c (linux_child_follow_fork): Update inferior_ptid with
the thread id.
gdb/testsuite/
gdb.threads/fork-child-threads.exp: Add "next" test.
---
gdb/linux-nat.c | 9 +++++++++
gdb/testsuite/gdb.threads/fork-child-threads.exp | 1 +
2 files changed, 10 insertions(+)
Index: src/gdb/testsuite/gdb.threads/fork-child-threads.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.threads/fork-child-threads.exp 2008-03-18 18:31:12.000000000 +0000
+++ src/gdb/testsuite/gdb.threads/fork-child-threads.exp 2008-03-18 18:31:53.000000000 +0000
@@ -38,6 +38,7 @@ if ![runto_main] then {
gdb_test "set follow-fork-mode child"
gdb_breakpoint "start"
+gdb_test "next" ".*pthread_create \\(&thread, NULL, start, NULL\\);.*" "next over fork"
gdb_test "continue" "Breakpoint 2, start.*" "get to the spawned thread"
# Wrong:
Index: src/gdb/linux-nat.c
===================================================================
--- src.orig/gdb/linux-nat.c 2008-03-18 20:25:45.000000000 +0000
+++ src/gdb/linux-nat.c 2008-03-18 20:26:04.000000000 +0000
@@ -104,6 +104,8 @@ static LONGEST (*super_xfer_partial) (st
const gdb_byte *,
ULONGEST, LONGEST);
+static int find_thread_from_lwp (struct thread_info *thr, void *dummy);
+
static int debug_linux_nat;
static void
show_debug_linux_nat (struct ui_file *file, int from_tty,
@@ -460,6 +462,7 @@ linux_child_follow_fork (struct target_o
else
{
char child_pid_spelling[40];
+ struct thread_info *thr;
/* Needed to keep the breakpoint lists in sync. */
if (! has_vforked)
@@ -519,6 +522,12 @@ linux_child_follow_fork (struct target_o
linux_nat_switch_fork (inferior_ptid);
check_for_thread_db ();
+ /* Update inferior_ptid to include the thread id, so updating
+ step-resume breakpoints in the child works. */
+ thr = iterate_over_threads (find_thread_from_lwp, &inferior_ptid);
+ if (thr)
+ inferior_ptid = thr->ptid;
+
/* Reset breakpoints in the child as appropriate. */
follow_inferior_reset_breakpoints ();
}
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [linux] fix stepping over fork in follow-child mode. 2008-03-18 20:47 [linux] fix stepping over fork in follow-child mode Pedro Alves @ 2008-03-18 23:48 ` Daniel Jacobowitz [not found] ` <frqh16$7rk$1@ger.gmane.org> 2008-03-19 16:03 ` Daniel Jacobowitz 0 siblings, 2 replies; 9+ messages in thread From: Daniel Jacobowitz @ 2008-03-18 23:48 UTC (permalink / raw) To: Pedro Alves; +Cc: GDB Patches, Vladimir Prus On Tue, Mar 18, 2008 at 08:46:46PM +0000, Pedro Alves wrote: > Hi, > > I noticed that issuing a next over a fork call, with > "follow-fork-mode child", wasn't working. The problem is that when we > update the breakpoints in the child to attach them to the current thread > if their thread their currently attached to doesn't exist anymore, > inferior_ptid doesn't hold the tid yet. Here's an alternative fix. Vladimir, this is also the patch I was talking about earlier on IRC. Not tested or finished yet. The basic idea: we only use tids for two things. We display them to the user and we pass them to libthread_db. So the problematic Linux behavior in which the tid is not available immediately for the first thread (not until libpthread.so has initialized, to be precise) is not a problem if we remove the tid from the ptid_t. Instead, Linux now always puts zero there. This lets us delete a lot of code that was already more or less dead, save some operations, et cetera. NULL thread_info->private should never happen when libpthread.so's pthread_create is used to create new threads. That's where most of the FIXMEs are for this patch; they're in places where if linux-nat.c detects a newly cloned process, we don't have thread_info->private filled in. I think the right thing to do is to fill it in lazily by calling td_ta_map_lwp2thr et cetera, and to handle it being NULL for clones the thread manager doesn't know about. I can work on this some more tomorrow, but you wanted a preview :-) -- Daniel Jacobowitz CodeSourcery Index: gdbthread.h =================================================================== RCS file: /cvs/src/src/gdb/gdbthread.h,v retrieving revision 1.20 diff -u -p -r1.20 gdbthread.h --- gdbthread.h 15 Mar 2008 13:53:25 -0000 1.20 +++ gdbthread.h 18 Mar 2008 23:41:17 -0000 @@ -81,6 +81,10 @@ extern struct thread_info *add_thread (p about new thread. */ extern struct thread_info *add_thread_silent (ptid_t ptid); +/* Same as add_thread, and sets the private info. */ +extern struct thread_info *add_thread_with_info (ptid_t ptid, + struct private_thread_info *); + /* Delete an existing thread list entry. */ extern void delete_thread (ptid_t); Index: linux-thread-db.c =================================================================== RCS file: /cvs/src/src/gdb/linux-thread-db.c,v retrieving revision 1.37 diff -u -p -r1.37 linux-thread-db.c --- linux-thread-db.c 23 Jan 2008 11:26:28 -0000 1.37 +++ linux-thread-db.c 18 Mar 2008 23:41:18 -0000 @@ -126,10 +126,6 @@ static void detach_thread (ptid_t ptid, #define GET_PID(ptid) ptid_get_pid (ptid) #define GET_LWP(ptid) ptid_get_lwp (ptid) -#define GET_THREAD(ptid) ptid_get_tid (ptid) - -#define is_lwp(ptid) (GET_LWP (ptid) != 0) -#define is_thread(ptid) (GET_THREAD (ptid) != 0) #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0) \f @@ -143,11 +139,8 @@ struct private_thread_info unsigned int dying:1; /* Cached thread state. */ - unsigned int th_valid:1; - unsigned int ti_valid:1; - td_thrhandle_t th; - td_thrinfo_t ti; + thread_t tid; }; \f @@ -257,7 +250,7 @@ thread_get_info_callback (const td_thrha thread_db_err_str (err)); /* Fill the cache. */ - thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); + thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0); thread_info = find_thread_pid (thread_ptid); /* In the case of a zombie thread, don't continue. We don't want to @@ -266,13 +259,6 @@ thread_get_info_callback (const td_thrha { if (infop != NULL) *(struct thread_info **) infop = thread_info; - if (thread_info != NULL) - { - memcpy (&thread_info->private->th, thp, sizeof (*thp)); - thread_info->private->th_valid = 1; - memcpy (&thread_info->private->ti, &ti, sizeof (ti)); - thread_info->private->ti_valid = 1; - } return TD_THR_ZOMBIE; } @@ -284,39 +270,11 @@ thread_get_info_callback (const td_thrha gdb_assert (thread_info != NULL); } - memcpy (&thread_info->private->th, thp, sizeof (*thp)); - thread_info->private->th_valid = 1; - memcpy (&thread_info->private->ti, &ti, sizeof (ti)); - thread_info->private->ti_valid = 1; - if (infop != NULL) *(struct thread_info **) infop = thread_info; return 0; } - -/* Accessor functions for the thread_db information, with caching. */ - -static void -thread_db_map_id2thr (struct thread_info *thread_info, int fatal) -{ - td_err_e err; - - if (thread_info->private->th_valid) - return; - - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid), - &thread_info->private->th); - if (err != TD_OK) - { - if (fatal) - error (_("Cannot find thread %ld: %s"), - (long) GET_THREAD (thread_info->ptid), - thread_db_err_str (err)); - } - else - thread_info->private->th_valid = 1; -} \f /* Convert between user-level thread ids and LWP ids. */ @@ -328,11 +286,11 @@ thread_from_lwp (ptid_t ptid) struct thread_info *thread_info; ptid_t thread_ptid; + /* FIXME: Should this ever even happen? I don't think it + should reach here. */ if (GET_LWP (ptid) == 0) ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid)); - gdb_assert (is_lwp (ptid)); - err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th); if (err != TD_OK) error (_("Cannot find user-level thread for LWP %ld: %s"), @@ -352,16 +310,8 @@ thread_from_lwp (ptid_t ptid) && thread_info == NULL) return pid_to_ptid (-1); - gdb_assert (thread_info && thread_info->private->ti_valid); - - return ptid_build (GET_PID (ptid), GET_LWP (ptid), - thread_info->private->ti.ti_tid); -} - -static ptid_t -lwp_from_thread (ptid_t ptid) -{ - return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid)); + gdb_assert (ptid_get_tid (ptid) == 0); + return ptid; } \f @@ -672,6 +622,7 @@ static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p) { + struct private_thread_info *private; struct thread_info *tp; td_err_e err; @@ -705,10 +656,21 @@ attach_thread (ptid_t ptid, const td_thr if (lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0) return; + /* Construct the thread's private data. */ + private = xmalloc (sizeof (struct private_thread_info)); + memset (private, 0, sizeof (struct private_thread_info)); + + /* A thread ID of zero may mean the thread library has not initialized + yet. But we shouldn't even get here if that's the case. FIXME: + if we change GDB to always have at least one thread in the thread + list this will have to go somewhere else; maybe private == NULL + until the thread_db target claims it. */ + gdb_assert (ti_p->ti_tid != 0); + private->th = *th_p; + private->tid = ti_p->ti_tid; + /* Add the thread to GDB's thread list. */ - tp = add_thread (ptid); - tp->private = xmalloc (sizeof (struct private_thread_info)); - memset (tp->private, 0, sizeof (struct private_thread_info)); + tp = add_thread_with_info (ptid, private); /* Enable thread event reporting for this thread. */ err = td_thr_event_enable_p (th_p, 1); @@ -742,47 +704,12 @@ thread_db_detach (char *args, int from_t { disable_thread_event_reporting (); - /* There's no need to save & restore inferior_ptid here, since the - inferior is not supposed to survive this function call. */ - inferior_ptid = lwp_from_thread (inferior_ptid); - target_beneath->to_detach (args, from_tty); /* Should this be done by detach_command? */ target_mourn_inferior (); } -static int -clear_lwpid_callback (struct thread_info *thread, void *dummy) -{ - /* If we know that our thread implementation is 1-to-1, we could save - a certain amount of information; it's not clear how much, so we - are always conservative. */ - - thread->private->th_valid = 0; - thread->private->ti_valid = 0; - - return 0; -} - -static void -thread_db_resume (ptid_t ptid, int step, enum target_signal signo) -{ - struct cleanup *old_chain = save_inferior_ptid (); - - if (GET_PID (ptid) == -1) - inferior_ptid = lwp_from_thread (inferior_ptid); - else if (is_thread (ptid)) - ptid = lwp_from_thread (ptid); - - /* Clear cached data which may not be valid after the resume. */ - iterate_over_threads (clear_lwpid_callback, NULL); - - target_beneath->to_resume (ptid, step, signo); - - do_cleanups (old_chain); -} - /* 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. */ @@ -833,7 +760,7 @@ check_event (ptid_t ptid) if (err != TD_OK) error (_("Cannot get thread info: %s"), thread_db_err_str (err)); - ptid = ptid_build (GET_PID (ptid), ti.ti_lid, ti.ti_tid); + ptid = ptid_build (GET_PID (ptid), ti.ti_lid, 0); switch (msg.event) { @@ -865,9 +792,6 @@ thread_db_wait (ptid_t ptid, struct targ { extern ptid_t trap_ptid; - if (GET_PID (ptid) != -1 && is_thread (ptid)) - ptid = lwp_from_thread (ptid); - ptid = target_beneath->to_wait (ptid, ourstatus); if (ourstatus->kind == TARGET_WAITKIND_EXITED @@ -913,15 +837,6 @@ thread_db_wait (ptid_t ptid, struct targ } static void -thread_db_kill (void) -{ - /* There's no need to save & restore inferior_ptid here, since the - inferior isn't supposed to survive this function call. */ - inferior_ptid = lwp_from_thread (inferior_ptid); - target_beneath->to_kill (); -} - -static void thread_db_mourn_inferior (void) { /* Forget about the child's process ID. We shouldn't need it @@ -954,7 +869,7 @@ find_new_threads_callback (const td_thrh if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) return 0; /* A zombie -- ignore. */ - ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); + ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0); if (ti.ti_tid == 0) { @@ -994,18 +909,21 @@ thread_db_find_new_threads (void) static char * thread_db_pid_to_str (ptid_t ptid) { - if (is_thread (ptid)) + struct thread_info *thread_info = find_thread_pid (ptid); + + if (thread_info != NULL) { static char buf[64]; - struct thread_info *thread_info; + thread_t tid; + + /* FIXME: What will set ->private? */ + gdb_assert (thread_info->private != NULL); + /* FIXME: What will ensure tid_valid? */ + tid = thread_info->private->tid; thread_info = find_thread_pid (ptid); - if (thread_info == NULL) - snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld) (Missing)", - GET_THREAD (ptid), GET_LWP (ptid)); - else - snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)", - GET_THREAD (ptid), GET_LWP (ptid)); + snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)", + tid, GET_LWP (ptid)); return buf; } @@ -1028,16 +946,6 @@ thread_db_extra_thread_info (struct thre return NULL; } -/* Return 1 if this thread has the same LWP as the passed PTID. */ - -static int -same_ptid_callback (struct thread_info *thread, void *arg) -{ - ptid_t *ptid_p = arg; - - return GET_LWP (thread->ptid) == GET_LWP (*ptid_p); -} - /* Get the address of the thread local variable in load module LM which is stored at OFFSET within the thread local storage for thread PTID. */ @@ -1046,26 +954,19 @@ thread_db_get_thread_local_address (ptid CORE_ADDR lm, CORE_ADDR offset) { + struct thread_info *thread_info; + /* If we have not discovered any threads yet, check now. */ - if (!is_thread (ptid) && !have_threads ()) + if (!have_threads ()) thread_db_find_new_threads (); - /* Try to find a matching thread if we still have the LWP ID instead - of the thread ID. */ - if (!is_thread (ptid)) - { - struct thread_info *thread; - - thread = iterate_over_threads (same_ptid_callback, &ptid); - if (thread != NULL) - ptid = thread->ptid; - } + /* Find the matching thread. */ + thread_info = find_thread_pid (ptid); - if (is_thread (ptid)) + if (thread_info != NULL) { td_err_e err; void *address; - struct thread_info *thread_info; /* glibc doesn't provide the needed interface. */ if (!td_thr_tls_get_addr_p) @@ -1075,10 +976,8 @@ thread_db_get_thread_local_address (ptid /* Caller should have verified that lm != 0. */ gdb_assert (lm != 0); - /* Get info about the thread. */ - thread_info = find_thread_pid (ptid); - gdb_assert (thread_info); - thread_db_map_id2thr (thread_info, 1); + /* Something should already have arranged this... FIXME: right? */ + gdb_assert (thread_info->private); /* Finally, get the address of the variable. */ err = td_thr_tls_get_addr_p (&thread_info->private->th, @@ -1122,9 +1021,7 @@ init_thread_db_ops (void) thread_db_ops.to_longname = "multi-threaded child process."; thread_db_ops.to_doc = "Threads and pthreads support."; thread_db_ops.to_detach = thread_db_detach; - thread_db_ops.to_resume = thread_db_resume; thread_db_ops.to_wait = thread_db_wait; - thread_db_ops.to_kill = thread_db_kill; thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior; thread_db_ops.to_find_new_threads = thread_db_find_new_threads; thread_db_ops.to_pid_to_str = thread_db_pid_to_str; Index: thread.c =================================================================== RCS file: /cvs/src/src/gdb/thread.c,v retrieving revision 1.62 diff -u -p -r1.62 thread.c --- thread.c 15 Mar 2008 13:53:25 -0000 1.62 +++ thread.c 18 Mar 2008 23:41:18 -0000 @@ -132,10 +132,12 @@ add_thread_silent (ptid_t ptid) } struct thread_info * -add_thread (ptid_t ptid) +add_thread_with_info (ptid_t ptid, struct private_thread_info *private) { struct thread_info *result = add_thread_silent (ptid); + result->private = private; + if (print_thread_events) printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid)); @@ -144,6 +146,12 @@ add_thread (ptid_t ptid) return result; } +struct thread_info * +add_thread (ptid_t ptid) +{ + return add_thread_with_info (ptid, NULL); +} + void delete_thread (ptid_t ptid) { Index: testsuite/gdb.threads/fork-child-threads.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.threads/fork-child-threads.exp,v retrieving revision 1.1 diff -u -p -r1.1 fork-child-threads.exp --- testsuite/gdb.threads/fork-child-threads.exp 2 Jan 2008 13:36:38 -0000 1.1 +++ testsuite/gdb.threads/fork-child-threads.exp 18 Mar 2008 23:41:18 -0000 @@ -38,6 +38,10 @@ if ![runto_main] then { gdb_test "set follow-fork-mode child" gdb_breakpoint "start" + +# Make sure we can step over fork without losing our breakpoint. +gdb_test "next" ".*pthread_create \\(&thread, NULL, start, NULL\\);.*" "next over fork" + gdb_test "continue" "Breakpoint 2, start.*" "get to the spawned thread" # Wrong: ^ permalink raw reply [flat|nested] 9+ messages in thread
[parent not found: <frqh16$7rk$1@ger.gmane.org>]
* Re: [linux] fix stepping over fork in follow-child mode. [not found] ` <frqh16$7rk$1@ger.gmane.org> @ 2008-03-19 12:49 ` Daniel Jacobowitz 0 siblings, 0 replies; 9+ messages in thread From: Daniel Jacobowitz @ 2008-03-19 12:49 UTC (permalink / raw) To: Vladimir Prus; +Cc: gdb-patches On Wed, Mar 19, 2008 at 10:57:27AM +0300, Vladimir Prus wrote: > 1. Your patch seem to remove thread_db_resume, including this > bit of code in it: > > if (GET_PID (ptid) == -1) > inferior_ptid = lwp_from_thread (inferior_ptid); > else if (is_thread (ptid)) > ptid = lwp_from_thread (ptid); > > What was the code, and in particular the last line, trying to do, > and why we don't actually have to do this? This converts "ptid known by thread_db and the rest of gdb" to "ptid known by linux-nat". A ptid is (PID, LWP, TID). linux-thread-db.c's ptids used to look like (PID, 0, TID) and the above call converted it to (PID, LWP, 0). A few years ago, I changed linux-thread-db to use (PID, LWP, TID) - in other words to assume that each TID was permanently assigned to a single LWP. That simplified things a lot. This is not true on some platforms. On Solaris, for instance, you may end up with M light-weight processes, and N threads, with N > M. Each process grabs a thread to execute as its previous thread goes to sleep. So the LWP can change. > 2. It seems that some other modules use tid. In particular, > aix-thread.c makes use of the ptid_get_tid call. What to do about that? We're fixing a Linux-specific problem, caused by not knowing the tid right away - so there isn't a single TID for the entire life of the application. If other platforms have the same problem, they can fix it locally. I think having a thread at all times is something that we're going to have to do in platform-specific code :-( -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [linux] fix stepping over fork in follow-child mode. 2008-03-18 23:48 ` Daniel Jacobowitz [not found] ` <frqh16$7rk$1@ger.gmane.org> @ 2008-03-19 16:03 ` Daniel Jacobowitz 2008-03-19 19:22 ` Joel Brobecker 2008-03-19 22:19 ` Nick Roberts 1 sibling, 2 replies; 9+ messages in thread From: Daniel Jacobowitz @ 2008-03-19 16:03 UTC (permalink / raw) To: Pedro Alves, GDB Patches, Vladimir Prus On Tue, Mar 18, 2008 at 07:48:05PM -0400, Daniel Jacobowitz wrote: > Here's an alternative fix. Vladimir, this is also the patch I was > talking about earlier on IRC. Not tested or finished yet. Tested (x86_64-linux) and finished now. A nice side effect of this patch is that "break main; run" on a threaded program no longer displays the "[Switching to Thread ...]" message on GNU/Linux; this was an artifact of adding the TID to inferior_ptid. Any comments? Otherwise I'll commit this in a few days. Vladimir, this patch should allow you to add the initial thread to the thread list. The best place is probably linux_nat_attach and linux_nat_create_inferior. Then "info threads" will always work for the Linux native target. Similarly for remote if it doesn't already. I think we should fix this one target at a time, since changing it in the GDB core is likely to break other threading targets. -- Daniel Jacobowitz CodeSourcery 2008-03-19 Daniel Jacobowitz <dan@codesourcery.com> * gdbthread.h (add_thread_with_info): New. * linux-thread-db.c: Add some documentation. (GET_THREAD, is_lwp, is_thread): Delete. (struct private_thread_info): Remove th_valid and ti_valid. Replace ti with tid. (thread_get_info_callback): Do not add TID to the new ptid. Do not cache th or ti. (thread_db_map_id2thr, lwp_from_thread): Delete functions. (thread_from_lwp): Assert that the LWP is set. Do not add TID to the new PTID. (attach_thread): Handle an already-existing thread. Use add_thread_with_info. Cache the th and tid. (detach_thread): Verify that private was set. Remove verbose argument and printing. Update caller. (thread_db_detach): Do not adjust inferior_ptid. (clear_lwpid_callback, thread_db_resume, thread_db_kill): Delete. (check_event, find_new_threads_callback): Do not add TID to the new PTID. (thread_db_wait): Do not use lwp_from_thread. (thread_db_pid_to_str): Use the cached TID. (thread_db_extra_thread_info): Check that private is set. (same_ptid_callback): Delete. (thread_db_get_thread_local_address): Do not use it or check is_thread. Check that private is set. Assume that the thread handle is already cached. (init_thread_db_ops): Remove to_resume and to_kill. * thread.c (add_thread_with_info): New. (add_thread): Use it. * linux-nat.c (find_thread_from_lwp): Delete. (exit_lwp): Do not use it. Check print_thread_events. Print before deleting the thread. * inf-ttrace.c (inf_ttrace_wait): Use print_thread_events and printf_unfiltered for thread exits. * procfs.c (procfs_wait): Likewise. 2008-03-19 Pedro Alves <pedro@codesourcery.com> * gdb.threads/fork-child-threads.exp: Test next over fork. Index: gdbthread.h =================================================================== RCS file: /cvs/src/src/gdb/gdbthread.h,v retrieving revision 1.20 diff -u -p -r1.20 gdbthread.h --- gdbthread.h 15 Mar 2008 13:53:25 -0000 1.20 +++ gdbthread.h 19 Mar 2008 15:55:36 -0000 @@ -81,6 +81,10 @@ extern struct thread_info *add_thread (p about new thread. */ extern struct thread_info *add_thread_silent (ptid_t ptid); +/* Same as add_thread, and sets the private info. */ +extern struct thread_info *add_thread_with_info (ptid_t ptid, + struct private_thread_info *); + /* Delete an existing thread list entry. */ extern void delete_thread (ptid_t); Index: inf-ttrace.c =================================================================== RCS file: /cvs/src/src/gdb/inf-ttrace.c,v retrieving revision 1.27 diff -u -p -r1.27 inf-ttrace.c --- inf-ttrace.c 29 Jan 2008 21:11:24 -0000 1.27 +++ inf-ttrace.c 19 Mar 2008 15:55:36 -0000 @@ -964,7 +964,8 @@ inf_ttrace_wait (ptid_t ptid, struct tar break; case TTEVT_LWP_EXIT: - printf_filtered(_("[%s exited]\n"), target_pid_to_str (ptid)); + if (print_thread_events) + printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid)); ti = find_thread_pid (ptid); gdb_assert (ti != NULL); ((struct inf_ttrace_private_thread_info *)ti->private)->dying = 1; Index: linux-nat.c =================================================================== RCS file: /cvs/src/src/gdb/linux-nat.c,v retrieving revision 1.76 diff -u -p -r1.76 linux-nat.c --- linux-nat.c 17 Mar 2008 14:54:07 -0000 1.76 +++ linux-nat.c 19 Mar 2008 15:55:36 -0000 @@ -813,20 +813,6 @@ prune_lwps (void) p = &(*p)->next; } -/* Callback for iterate_over_threads that finds a thread corresponding - to the given LWP. */ - -static int -find_thread_from_lwp (struct thread_info *thr, void *dummy) -{ - ptid_t *ptid_p = dummy; - - if (GET_LWP (thr->ptid) && GET_LWP (thr->ptid) == GET_LWP (*ptid_p)) - return 1; - else - return 0; -} - /* Handle the exit of a single thread LP. */ static void @@ -834,32 +820,14 @@ exit_lwp (struct lwp_info *lp) { if (in_thread_list (lp->ptid)) { + if (print_thread_events) + printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (lp->ptid)); + /* Core GDB cannot deal with us deleting the current thread. */ if (!ptid_equal (lp->ptid, inferior_ptid)) delete_thread (lp->ptid); else record_dead_thread (lp->ptid); - printf_unfiltered (_("[%s exited]\n"), - target_pid_to_str (lp->ptid)); - } - else - { - /* Even if LP->PTID is not in the global GDB thread list, the - LWP may be - with an additional thread ID. We don't need - to print anything in this case; thread_db is in use and - already took care of that. But it didn't delete the thread - in order to handle zombies correctly. */ - - struct thread_info *thr; - - thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid); - if (thr) - { - if (!ptid_equal (thr->ptid, inferior_ptid)) - delete_thread (thr->ptid); - else - record_dead_thread (thr->ptid); - } } delete_lwp (lp->ptid); Index: linux-thread-db.c =================================================================== RCS file: /cvs/src/src/gdb/linux-thread-db.c,v retrieving revision 1.37 diff -u -p -r1.37 linux-thread-db.c --- linux-thread-db.c 23 Jan 2008 11:26:28 -0000 1.37 +++ linux-thread-db.c 19 Mar 2008 15:55:36 -0000 @@ -48,6 +48,32 @@ #define LIBTHREAD_DB_SO "libthread_db.so.1" #endif +/* GNU/Linux libthread_db support. + + libthread_db is a library, provided along with libpthread.so, which + exposes the internals of the thread library to a debugger. It + allows GDB to find existing threads, new threads as they are + created, thread IDs (usually, the result of pthread_self), and + thread-local variables. + + The libthread_db interface originates on Solaris, where it is + both more powerful and more complicated. This implementation + only works for LinuxThreads and NPTL, the two glibc threading + libraries. It assumes that each thread is permanently assigned + to a single light-weight process (LWP). + + libthread_db-specific information is stored in the "private" field + of struct thread_info. When the field is NULL we do not yet have + information about the new thread; this could be temporary (created, + but the thread library's data structures do not reflect it yet) + or permanent (created using clone instead of pthread_create). + + Process IDs managed by linux-thread-db.c match those used by + linux-nat.c: a common PID for all processes, an LWP ID for each + thread, and no TID. We save the TID in private. Keeping it out + of the ptid_t prevents thread IDs changing when libpthread is + loaded or unloaded. */ + /* If we're running on GNU/Linux, we must explicitly attach to any new threads. */ @@ -119,17 +145,13 @@ static CORE_ADDR td_death_bp_addr; static void thread_db_find_new_threads (void); static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p); -static void detach_thread (ptid_t ptid, int verbose); +static void detach_thread (ptid_t ptid); \f /* Building process ids. */ #define GET_PID(ptid) ptid_get_pid (ptid) #define GET_LWP(ptid) ptid_get_lwp (ptid) -#define GET_THREAD(ptid) ptid_get_tid (ptid) - -#define is_lwp(ptid) (GET_LWP (ptid) != 0) -#define is_thread(ptid) (GET_THREAD (ptid) != 0) #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0) \f @@ -143,11 +165,8 @@ struct private_thread_info unsigned int dying:1; /* Cached thread state. */ - unsigned int th_valid:1; - unsigned int ti_valid:1; - td_thrhandle_t th; - td_thrinfo_t ti; + thread_t tid; }; \f @@ -257,7 +276,7 @@ thread_get_info_callback (const td_thrha thread_db_err_str (err)); /* Fill the cache. */ - thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); + thread_ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0); thread_info = find_thread_pid (thread_ptid); /* In the case of a zombie thread, don't continue. We don't want to @@ -266,13 +285,6 @@ thread_get_info_callback (const td_thrha { if (infop != NULL) *(struct thread_info **) infop = thread_info; - if (thread_info != NULL) - { - memcpy (&thread_info->private->th, thp, sizeof (*thp)); - thread_info->private->th_valid = 1; - memcpy (&thread_info->private->ti, &ti, sizeof (ti)); - thread_info->private->ti_valid = 1; - } return TD_THR_ZOMBIE; } @@ -284,39 +296,11 @@ thread_get_info_callback (const td_thrha gdb_assert (thread_info != NULL); } - memcpy (&thread_info->private->th, thp, sizeof (*thp)); - thread_info->private->th_valid = 1; - memcpy (&thread_info->private->ti, &ti, sizeof (ti)); - thread_info->private->ti_valid = 1; - if (infop != NULL) *(struct thread_info **) infop = thread_info; return 0; } - -/* Accessor functions for the thread_db information, with caching. */ - -static void -thread_db_map_id2thr (struct thread_info *thread_info, int fatal) -{ - td_err_e err; - - if (thread_info->private->th_valid) - return; - - err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (thread_info->ptid), - &thread_info->private->th); - if (err != TD_OK) - { - if (fatal) - error (_("Cannot find thread %ld: %s"), - (long) GET_THREAD (thread_info->ptid), - thread_db_err_str (err)); - } - else - thread_info->private->th_valid = 1; -} \f /* Convert between user-level thread ids and LWP ids. */ @@ -328,10 +312,9 @@ thread_from_lwp (ptid_t ptid) struct thread_info *thread_info; ptid_t thread_ptid; - if (GET_LWP (ptid) == 0) - ptid = BUILD_LWP (GET_PID (ptid), GET_PID (ptid)); - - gdb_assert (is_lwp (ptid)); + /* This ptid comes from linux-nat.c, which should always fill in the + LWP. */ + gdb_assert (GET_LWP (ptid) != 0); err = td_ta_map_lwp2thr_p (thread_agent, GET_LWP (ptid), &th); if (err != TD_OK) @@ -352,16 +335,8 @@ thread_from_lwp (ptid_t ptid) && thread_info == NULL) return pid_to_ptid (-1); - gdb_assert (thread_info && thread_info->private->ti_valid); - - return ptid_build (GET_PID (ptid), GET_LWP (ptid), - thread_info->private->ti.ti_tid); -} - -static ptid_t -lwp_from_thread (ptid_t ptid) -{ - return BUILD_LWP (GET_LWP (ptid), GET_PID (ptid)); + gdb_assert (ptid_get_tid (ptid) == 0); + return ptid; } \f @@ -672,7 +647,8 @@ static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p, const td_thrinfo_t *ti_p) { - struct thread_info *tp; + struct private_thread_info *private; + struct thread_info *tp = NULL; td_err_e err; /* If we're being called after a TD_CREATE event, we may already @@ -690,10 +666,21 @@ attach_thread (ptid_t ptid, const td_thr tp = find_thread_pid (ptid); gdb_assert (tp != NULL); - if (!tp->private->dying) - return; + /* If tp->private 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->private != NULL) + { + if (!tp->private->dying) + return; - delete_thread (ptid); + delete_thread (ptid); + tp = NULL; + } } check_thread_signals (); @@ -702,13 +689,28 @@ attach_thread (ptid_t ptid, const td_thr return; /* A zombie thread -- do not attach. */ /* Under GNU/Linux, we have to attach to each and every thread. */ - if (lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0) + if (tp == NULL + && lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0) return; + /* Construct the thread's private data. */ + private = xmalloc (sizeof (struct private_thread_info)); + memset (private, 0, sizeof (struct private_thread_info)); + + /* A thread ID of zero may mean the thread library has not initialized + yet. But we shouldn't even get here if that's the case. FIXME: + if we change GDB to always have at least one thread in the thread + list this will have to go somewhere else; maybe private == NULL + until the thread_db target claims it. */ + gdb_assert (ti_p->ti_tid != 0); + private->th = *th_p; + private->tid = ti_p->ti_tid; + /* Add the thread to GDB's thread list. */ - tp = add_thread (ptid); - tp->private = xmalloc (sizeof (struct private_thread_info)); - memset (tp->private, 0, sizeof (struct private_thread_info)); + if (tp == NULL) + tp = add_thread_with_info (ptid, private); + else + tp->private = private; /* Enable thread event reporting for this thread. */ err = td_thr_event_enable_p (th_p, 1); @@ -718,22 +720,20 @@ attach_thread (ptid_t ptid, const td_thr } static void -detach_thread (ptid_t ptid, int verbose) +detach_thread (ptid_t ptid) { struct thread_info *thread_info; - if (verbose) - printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (ptid)); - /* 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. */ + something re-uses its thread ID. We'll report the thread exit + when the underlying LWP dies. */ thread_info = find_thread_pid (ptid); - gdb_assert (thread_info != NULL); + gdb_assert (thread_info != NULL && thread_info->private != NULL); thread_info->private->dying = 1; } @@ -742,47 +742,12 @@ thread_db_detach (char *args, int from_t { disable_thread_event_reporting (); - /* There's no need to save & restore inferior_ptid here, since the - inferior is not supposed to survive this function call. */ - inferior_ptid = lwp_from_thread (inferior_ptid); - target_beneath->to_detach (args, from_tty); /* Should this be done by detach_command? */ target_mourn_inferior (); } -static int -clear_lwpid_callback (struct thread_info *thread, void *dummy) -{ - /* If we know that our thread implementation is 1-to-1, we could save - a certain amount of information; it's not clear how much, so we - are always conservative. */ - - thread->private->th_valid = 0; - thread->private->ti_valid = 0; - - return 0; -} - -static void -thread_db_resume (ptid_t ptid, int step, enum target_signal signo) -{ - struct cleanup *old_chain = save_inferior_ptid (); - - if (GET_PID (ptid) == -1) - inferior_ptid = lwp_from_thread (inferior_ptid); - else if (is_thread (ptid)) - ptid = lwp_from_thread (ptid); - - /* Clear cached data which may not be valid after the resume. */ - iterate_over_threads (clear_lwpid_callback, NULL); - - target_beneath->to_resume (ptid, step, signo); - - do_cleanups (old_chain); -} - /* 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. */ @@ -833,7 +798,7 @@ check_event (ptid_t ptid) if (err != TD_OK) error (_("Cannot get thread info: %s"), thread_db_err_str (err)); - ptid = ptid_build (GET_PID (ptid), ti.ti_lid, ti.ti_tid); + ptid = ptid_build (GET_PID (ptid), ti.ti_lid, 0); switch (msg.event) { @@ -849,7 +814,7 @@ check_event (ptid_t ptid) if (!in_thread_list (ptid)) error (_("Spurious thread death event.")); - detach_thread (ptid, print_thread_events); + detach_thread (ptid); break; @@ -865,9 +830,6 @@ thread_db_wait (ptid_t ptid, struct targ { extern ptid_t trap_ptid; - if (GET_PID (ptid) != -1 && is_thread (ptid)) - ptid = lwp_from_thread (ptid); - ptid = target_beneath->to_wait (ptid, ourstatus); if (ourstatus->kind == TARGET_WAITKIND_EXITED @@ -913,15 +875,6 @@ thread_db_wait (ptid_t ptid, struct targ } static void -thread_db_kill (void) -{ - /* There's no need to save & restore inferior_ptid here, since the - inferior isn't supposed to survive this function call. */ - inferior_ptid = lwp_from_thread (inferior_ptid); - target_beneath->to_kill (); -} - -static void thread_db_mourn_inferior (void) { /* Forget about the child's process ID. We shouldn't need it @@ -954,7 +907,7 @@ find_new_threads_callback (const td_thrh if (ti.ti_state == TD_THR_UNKNOWN || ti.ti_state == TD_THR_ZOMBIE) return 0; /* A zombie -- ignore. */ - ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, ti.ti_tid); + ptid = ptid_build (GET_PID (inferior_ptid), ti.ti_lid, 0); if (ti.ti_tid == 0) { @@ -994,18 +947,17 @@ thread_db_find_new_threads (void) static char * thread_db_pid_to_str (ptid_t ptid) { - if (is_thread (ptid)) + struct thread_info *thread_info = find_thread_pid (ptid); + + if (thread_info != NULL && thread_info->private != NULL) { static char buf[64]; - struct thread_info *thread_info; + thread_t tid; + tid = thread_info->private->tid; thread_info = find_thread_pid (ptid); - if (thread_info == NULL) - snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld) (Missing)", - GET_THREAD (ptid), GET_LWP (ptid)); - else - snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)", - GET_THREAD (ptid), GET_LWP (ptid)); + snprintf (buf, sizeof (buf), "Thread 0x%lx (LWP %ld)", + tid, GET_LWP (ptid)); return buf; } @@ -1022,22 +974,15 @@ thread_db_pid_to_str (ptid_t ptid) static char * thread_db_extra_thread_info (struct thread_info *info) { + if (info->private == NULL) + return NULL; + if (info->private->dying) return "Exiting"; return NULL; } -/* Return 1 if this thread has the same LWP as the passed PTID. */ - -static int -same_ptid_callback (struct thread_info *thread, void *arg) -{ - ptid_t *ptid_p = arg; - - return GET_LWP (thread->ptid) == GET_LWP (*ptid_p); -} - /* Get the address of the thread local variable in load module LM which is stored at OFFSET within the thread local storage for thread PTID. */ @@ -1046,26 +991,19 @@ thread_db_get_thread_local_address (ptid CORE_ADDR lm, CORE_ADDR offset) { + struct thread_info *thread_info; + /* If we have not discovered any threads yet, check now. */ - if (!is_thread (ptid) && !have_threads ()) + if (!have_threads ()) thread_db_find_new_threads (); - /* Try to find a matching thread if we still have the LWP ID instead - of the thread ID. */ - if (!is_thread (ptid)) - { - struct thread_info *thread; - - thread = iterate_over_threads (same_ptid_callback, &ptid); - if (thread != NULL) - ptid = thread->ptid; - } + /* Find the matching thread. */ + thread_info = find_thread_pid (ptid); - if (is_thread (ptid)) + if (thread_info != NULL && thread_info->private != NULL) { td_err_e err; void *address; - struct thread_info *thread_info; /* glibc doesn't provide the needed interface. */ if (!td_thr_tls_get_addr_p) @@ -1075,11 +1013,6 @@ thread_db_get_thread_local_address (ptid /* Caller should have verified that lm != 0. */ gdb_assert (lm != 0); - /* Get info about the thread. */ - thread_info = find_thread_pid (ptid); - gdb_assert (thread_info); - thread_db_map_id2thr (thread_info, 1); - /* Finally, get the address of the variable. */ err = td_thr_tls_get_addr_p (&thread_info->private->th, (void *)(size_t) lm, @@ -1122,9 +1055,7 @@ init_thread_db_ops (void) thread_db_ops.to_longname = "multi-threaded child process."; thread_db_ops.to_doc = "Threads and pthreads support."; thread_db_ops.to_detach = thread_db_detach; - thread_db_ops.to_resume = thread_db_resume; thread_db_ops.to_wait = thread_db_wait; - thread_db_ops.to_kill = thread_db_kill; thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior; thread_db_ops.to_find_new_threads = thread_db_find_new_threads; thread_db_ops.to_pid_to_str = thread_db_pid_to_str; Index: procfs.c =================================================================== RCS file: /cvs/src/src/gdb/procfs.c,v retrieving revision 1.86 diff -u -p -r1.86 procfs.c --- procfs.c 12 Mar 2008 20:00:21 -0000 1.86 +++ procfs.c 19 Mar 2008 15:55:37 -0000 @@ -4034,8 +4034,9 @@ wait_again: case PR_SYSENTRY: if (syscall_is_lwp_exit (pi, what)) { - printf_filtered (_("[%s exited]\n"), - target_pid_to_str (retval)); + if (print_thread_events) + printf_unfiltered (_("[%s exited]\n"), + target_pid_to_str (retval)); delete_thread (retval); status->kind = TARGET_WAITKIND_SPURIOUS; return retval; @@ -4165,8 +4166,9 @@ wait_again: } else if (syscall_is_lwp_exit (pi, what)) { - printf_filtered (_("[%s exited]\n"), - target_pid_to_str (retval)); + if (print_thread_events) + printf_unfiltered (_("[%s exited]\n"), + target_pid_to_str (retval)); delete_thread (retval); status->kind = TARGET_WAITKIND_SPURIOUS; return retval; Index: thread.c =================================================================== RCS file: /cvs/src/src/gdb/thread.c,v retrieving revision 1.63 diff -u -p -r1.63 thread.c --- thread.c 17 Mar 2008 18:41:29 -0000 1.63 +++ thread.c 19 Mar 2008 15:55:37 -0000 @@ -132,10 +132,12 @@ add_thread_silent (ptid_t ptid) } struct thread_info * -add_thread (ptid_t ptid) +add_thread_with_info (ptid_t ptid, struct private_thread_info *private) { struct thread_info *result = add_thread_silent (ptid); + result->private = private; + if (print_thread_events) printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid)); @@ -144,6 +146,12 @@ add_thread (ptid_t ptid) return result; } +struct thread_info * +add_thread (ptid_t ptid) +{ + return add_thread_with_info (ptid, NULL); +} + void delete_thread (ptid_t ptid) { Index: testsuite/gdb.threads/fork-child-threads.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.threads/fork-child-threads.exp,v retrieving revision 1.1 diff -u -p -r1.1 fork-child-threads.exp --- testsuite/gdb.threads/fork-child-threads.exp 2 Jan 2008 13:36:38 -0000 1.1 +++ testsuite/gdb.threads/fork-child-threads.exp 19 Mar 2008 15:55:37 -0000 @@ -38,6 +38,10 @@ if ![runto_main] then { gdb_test "set follow-fork-mode child" gdb_breakpoint "start" + +# Make sure we can step over fork without losing our breakpoint. +gdb_test "next" ".*pthread_create \\(&thread, NULL, start, NULL\\);.*" "next over fork" + gdb_test "continue" "Breakpoint 2, start.*" "get to the spawned thread" # Wrong: ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [linux] fix stepping over fork in follow-child mode. 2008-03-19 16:03 ` Daniel Jacobowitz @ 2008-03-19 19:22 ` Joel Brobecker 2008-03-19 19:27 ` Daniel Jacobowitz 2008-03-19 22:19 ` Nick Roberts 1 sibling, 1 reply; 9+ messages in thread From: Joel Brobecker @ 2008-03-19 19:22 UTC (permalink / raw) To: gdb-patches Hi Daniel, > > Here's an alternative fix. Vladimir, this is also the patch I was > > talking about earlier on IRC. Not tested or finished yet. > > Any comments? Otherwise I'll commit this in a few days. I'm really amazed at the amount of simplification this brings. Never having looked at thread support on Linux, I had no idea... I only have one very minor question: Why is the thread exit notification now conditional on print_thread_events? I did notice that you changed the few printf_filtered of such events into printf_unfiltered the same way we did for the new thread events, which is nice :). Thanks, -- Joel ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [linux] fix stepping over fork in follow-child mode. 2008-03-19 19:22 ` Joel Brobecker @ 2008-03-19 19:27 ` Daniel Jacobowitz 0 siblings, 0 replies; 9+ messages in thread From: Daniel Jacobowitz @ 2008-03-19 19:27 UTC (permalink / raw) To: Joel Brobecker; +Cc: gdb-patches On Wed, Mar 19, 2008 at 12:22:37PM -0700, Joel Brobecker wrote: > I only have one very minor question: Why is the thread exit notification > now conditional on print_thread_events? I did notice that you changed > the few printf_filtered of such events into printf_unfiltered the same > way we did for the new thread events, which is nice :). It already was for Linux - the code in linux-nat.c didn't used to trigger, and I deleted a use of print_thread_events in linux-thread-db.c. I think the AIX / procfs ones were simply an oversight. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [linux] fix stepping over fork in follow-child mode. 2008-03-19 16:03 ` Daniel Jacobowitz 2008-03-19 19:22 ` Joel Brobecker @ 2008-03-19 22:19 ` Nick Roberts 2008-03-19 22:47 ` Daniel Jacobowitz 1 sibling, 1 reply; 9+ messages in thread From: Nick Roberts @ 2008-03-19 22:19 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: Pedro Alves, GDB Patches, Vladimir Prus > /* Building process ids. */ > > #define GET_PID(ptid) ptid_get_pid (ptid) > #define GET_LWP(ptid) ptid_get_lwp (ptid) > -#define GET_THREAD(ptid) ptid_get_tid (ptid) > - > -#define is_lwp(ptid) (GET_LWP (ptid) != 0) > -#define is_thread(ptid) (GET_THREAD (ptid) != 0) > > #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0) Why not just put all these in linux-nat.h so there are not duplications in linux-nat.c? -- Nick http://www.inet.net.nz/~nickrob ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [linux] fix stepping over fork in follow-child mode. 2008-03-19 22:19 ` Nick Roberts @ 2008-03-19 22:47 ` Daniel Jacobowitz 2008-03-21 15:45 ` Daniel Jacobowitz 0 siblings, 1 reply; 9+ messages in thread From: Daniel Jacobowitz @ 2008-03-19 22:47 UTC (permalink / raw) To: Nick Roberts; +Cc: Pedro Alves, GDB Patches, Vladimir Prus On Thu, Mar 20, 2008 at 10:18:40AM +1200, Nick Roberts wrote: > > /* Building process ids. */ > > > > #define GET_PID(ptid) ptid_get_pid (ptid) > > #define GET_LWP(ptid) ptid_get_lwp (ptid) > > -#define GET_THREAD(ptid) ptid_get_tid (ptid) > > - > > -#define is_lwp(ptid) (GET_LWP (ptid) != 0) > > -#define is_thread(ptid) (GET_THREAD (ptid) != 0) > > > > #define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0) > > Why not just put all these in linux-nat.h so there are not duplications in > linux-nat.c? No particular reason; I just left them where they were. I believe they were added to a lot of files when ptid_t was introduced. May as well move them, I'll do that. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [linux] fix stepping over fork in follow-child mode. 2008-03-19 22:47 ` Daniel Jacobowitz @ 2008-03-21 15:45 ` Daniel Jacobowitz 0 siblings, 0 replies; 9+ messages in thread From: Daniel Jacobowitz @ 2008-03-21 15:45 UTC (permalink / raw) To: gdb-patches; +Cc: Nick Roberts, Pedro Alves, Vladimir Prus On Wed, Mar 19, 2008 at 06:46:53PM -0400, Daniel Jacobowitz wrote: > No particular reason; I just left them where they were. I believe > they were added to a lot of files when ptid_t was introduced. May as > well move them, I'll do that. Committed with that change. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-03-21 15:45 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-18 20:47 [linux] fix stepping over fork in follow-child mode Pedro Alves
2008-03-18 23:48 ` Daniel Jacobowitz
[not found] ` <frqh16$7rk$1@ger.gmane.org>
2008-03-19 12:49 ` Daniel Jacobowitz
2008-03-19 16:03 ` Daniel Jacobowitz
2008-03-19 19:22 ` Joel Brobecker
2008-03-19 19:27 ` Daniel Jacobowitz
2008-03-19 22:19 ` Nick Roberts
2008-03-19 22:47 ` Daniel Jacobowitz
2008-03-21 15:45 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox