From: Pedro Alves <pedro@codesourcery.com>
To: Daniel Jacobowitz <drow@false.org>
Cc: gdb-patches@sourceware.org
Subject: Re: [5/7] procfs (solaris, iris, osf, unixware, aix5)
Date: Fri, 15 Aug 2008 19:19:00 -0000 [thread overview]
Message-ID: <200808152019.16390.pedro@codesourcery.com> (raw)
In-Reply-To: <20080815173731.GA16904@caradoc.them.org>
[-- Attachment #1: Type: text/plain, Size: 2168 bytes --]
On Friday 15 August 2008 18:37:31, Daniel Jacobowitz wrote:
> On Fri, Aug 08, 2008 at 02:37:57AM +0100, Pedro Alves wrote:
> > This patch adjusts the procfs target, so that it registers the main
> > thread in GDB's thread table.
>
> This looks OK to me (took me a couple of tries to convince myself it
> was right, but I'm convinced now).
I'm sorry to had convinced you wrong. :-(
I noticed that before, when we went multi-threaded, we would keep
the main process listed with proc->tid == 0, and we would just
create a new procinfo for the main lwp, which is a little
redundant, but indeed simplifies things.
procfs_wait:
/* In addition, it's possible that this is the first
* new thread we've seen, in which case we may not
* have created entries for inferior_ptid yet.
*/
if (TIDGET (inferior_ptid) != 0)
{
if (!in_thread_list (inferior_ptid))
add_thread (inferior_ptid);
if (find_procinfo (PIDGET (inferior_ptid),
TIDGET (inferior_ptid)) == NULL)
create_procinfo (PIDGET (inferior_ptid),
TIDGET (inferior_ptid));
}
If I instead do that right on target_create_inferior and target_attach,
we're done -- there's always a thread, and there's always a procinfo for
it too.
You asked me on IRC if the main lwp is also available in
the /proc tree, and although I somehow missed it, indeed it is there.
Here, 5642 is a single-threaded app:
pedro@opensolaris:~/orlando/gdb/baseline/build-solaris/gdb$ ls /proc/5642/lwp/
1
Here, 5613 is a multi-threaded app:
pedro@opensolaris:~/orlando/gdb/baseline/build-solaris/gdb$ ls /proc/5613/lwp/
1 2 3
We still have to use the main process procinfo entry, to get at
/proc/<pid>/map /proc/<pid>/as, because as expected, those are
not found under the lwp/1 directory:
pedro@opensolaris:~/orlando/gdb/baseline/build-solaris/gdb$ ls /proc/5613/lwp/1/
lwpctl lwpsinfo lwpstatus lwpusage templates xregs
My previous path had broken creating core dumps in multi-threaded apps,
as iterating over thread procinfo's would miss the main process.
Please find attached a new patch. This one's much simpler.
Only procfs.c changed.
--
Pedro Alves
[-- Attachment #2: 005-procfs_always_a_thread.diff --]
[-- Type: text/x-diff, Size: 10159 bytes --]
2008-08-15 Pedro Alves <pedro@codesourcery.com>
* procfs.c (to_attach): Create a procinfo for the current lwp.
Add it to gdb's thread list.
(procfs_fetch_registers, procfs_store_registers): Assume there's
always an lwp.
(procfs_wait): And add the main thread here.
(procfs_init_inferior): Create a procinfo for the main lwp here.
Change main thread's ptid with thread_change_ptid.
(procfs_notice_thread): Check for exited threads.
(procfs_corefile_thread_callback): Remote check for the main
process.
(procfs_make_note_section): Assume there is always a thread.
* sol-thread.c (sol_thread_attach): Clear sol_thread_active before
attaching. Change the main thread ptid with thread_change_ptid.
(sol_thread_detach): Clear sol_thread_active.
(sol_thread_wait): Check for exited threads.
(sol_thread_create_inferior): Clear sol_thread_active before
creating a new inferior. Change the main thread ptid with
thread_change_ptid.
(sol_thread_mourn_inferior): Clear sol_thread_active.
(sol_find_new_threads_callback): Check for exited threads.
---
gdb/procfs.c | 77 +++++++++++++++++++++----------------------------------
gdb/sol-thread.c | 33 ++++++++++++-----------
2 files changed, 48 insertions(+), 62 deletions(-)
Index: src/gdb/procfs.c
===================================================================
--- src.orig/gdb/procfs.c 2008-08-15 18:30:05.000000000 +0100
+++ src/gdb/procfs.c 2008-08-15 19:32:41.000000000 +0100
@@ -3664,6 +3664,7 @@ do_attach (ptid_t ptid)
{
procinfo *pi;
int fail;
+ int lwpid;
if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL)
perror (_("procfs: out of memory in 'attach'"));
@@ -3713,7 +3714,16 @@ do_attach (ptid_t ptid)
/* Let GDB know that the inferior was attached. */
attach_flag = 1;
- return MERGEPID (pi->pid, proc_get_current_thread (pi));
+
+ /* Create a procinfo for the current lwp. */
+ lwpid = proc_get_current_thread (pi);
+ create_procinfo (pi->pid, lwpid);
+
+ /* Add it to gdb's thread list. */
+ ptid = MERGEPID (pi->pid, lwpid);
+ add_thread (ptid);
+
+ return ptid;
}
static void
@@ -3784,14 +3794,7 @@ procfs_fetch_registers (struct regcache
int tid = TIDGET (inferior_ptid);
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- /* First look up procinfo for the main process. */
- pi = find_procinfo_or_die (pid, 0);
-
- /* If the event thread is not the same as GDB's requested thread
- (ie. inferior_ptid), then look up procinfo for the requested
- thread. */
- if (tid != 0 && tid != proc_get_current_thread (pi))
- pi = find_procinfo_or_die (pid, tid);
+ pi = find_procinfo_or_die (pid, tid);
if (pi == NULL)
error (_("procfs: fetch_registers failed to find procinfo for %s"),
@@ -3850,14 +3853,7 @@ procfs_store_registers (struct regcache
int tid = TIDGET (inferior_ptid);
struct gdbarch *gdbarch = get_regcache_arch (regcache);
- /* First find procinfo for main process. */
- pi = find_procinfo_or_die (pid, 0);
-
- /* If the event thread is not the same as GDB's requested thread
- (ie. inferior_ptid), then look up procinfo for the requested
- thread. */
- if (tid != 0 && tid != proc_get_current_thread (pi))
- pi = find_procinfo_or_die (pid, tid);
+ pi = find_procinfo_or_die (pid, tid);
if (pi == NULL)
error (_("procfs: store_registers: failed to find procinfo for %s"),
@@ -4350,20 +4346,6 @@ wait_again:
add_thread (retval);
if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
create_procinfo (PIDGET (retval), TIDGET (retval));
-
- /* In addition, it's possible that this is the first
- * new thread we've seen, in which case we may not
- * have created entries for inferior_ptid yet.
- */
- if (TIDGET (inferior_ptid) != 0)
- {
- if (!in_thread_list (inferior_ptid))
- add_thread (inferior_ptid);
- if (find_procinfo (PIDGET (inferior_ptid),
- TIDGET (inferior_ptid)) == NULL)
- create_procinfo (PIDGET (inferior_ptid),
- TIDGET (inferior_ptid));
- }
}
}
else /* flags do not indicate STOPPED */
@@ -4891,6 +4873,7 @@ procfs_init_inferior (int pid)
procinfo *pi;
gdb_sigset_t signals;
int fail;
+ int lwpid;
/* This routine called on the parent side (GDB side)
after GDB forks the inferior. */
@@ -4951,9 +4934,17 @@ procfs_init_inferior (int pid)
if (!proc_set_run_on_last_close (pi))
proc_error (pi, "init_inferior, set_RLC", __LINE__);
- /* The 'process ID' we return to GDB is composed of
- the actual process ID plus the lwp ID. */
- inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi));
+ /* We now have have access to the lwpid of the main thread/lwp. */
+ lwpid = proc_get_current_thread (pi);
+
+ /* Create a procinfo for the main lwp. */
+ create_procinfo (pid, lwpid);
+
+ /* We already have a main thread registered in the thread table at
+ this point, but it didn't have any lwp info yet. Notify the core
+ about it. This changes inferior_ptid as well. */
+ thread_change_ptid (pid_to_ptid (pid),
+ MERGEPID (pid, lwpid));
/* Typically two, one trap to exec the shell, one to exec the
program being debugged. Defined by "inferior.h". */
@@ -5212,7 +5203,7 @@ procfs_notice_thread (procinfo *pi, proc
{
ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid);
- if (!in_thread_list (gdb_threadid))
+ if (!in_thread_list (gdb_threadid) || is_exited (gdb_threadid))
add_thread (gdb_threadid);
return 0;
@@ -6105,7 +6096,7 @@ procfs_corefile_thread_callback (procinf
{
struct procfs_corefile_thread_data *args = data;
- if (pi != NULL && thread->tid != 0)
+ if (pi != NULL)
{
ptid_t saved_ptid = inferior_ptid;
inferior_ptid = MERGEPID (pi->pid, thread->tid);
@@ -6167,17 +6158,9 @@ procfs_make_note_section (bfd *obfd, int
thread_args.note_size = note_size;
proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
- if (thread_args.note_data == note_data)
- {
- /* iterate_over_threads didn't come up with any threads;
- just use inferior_ptid. */
- note_data = procfs_do_thread_registers (obfd, inferior_ptid,
- note_data, note_size);
- }
- else
- {
- note_data = thread_args.note_data;
- }
+ /* There should be always at least one thread. */
+ gdb_assert (thread_args.note_data != note_data);
+ note_data = thread_args.note_data;
auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
NULL, &auxv);
Index: src/gdb/sol-thread.c
===================================================================
--- src.orig/gdb/sol-thread.c 2008-08-15 18:30:05.000000000 +0100
+++ src/gdb/sol-thread.c 2008-08-15 19:53:22.000000000 +0100
@@ -253,7 +253,7 @@ td_state_string (td_thr_state_e statecod
/* Convert a POSIX or Solaris thread ID into a LWP ID. If THREAD_ID
doesn't exist, that's an error. If it's an inactive thread, return
- DEFAULT_LPW.
+ DEFAULT_LWP.
NOTE: This function probably shouldn't call error(). */
@@ -350,6 +350,7 @@ sol_thread_open (char *arg, int from_tty
static void
sol_thread_attach (char *args, int from_tty)
{
+ sol_thread_active = 0;
procfs_ops.to_attach (args, from_tty);
/* Must get symbols from shared libraries before libthread_db can run! */
@@ -357,14 +358,13 @@ sol_thread_attach (char *args, int from_
if (sol_thread_active)
{
+ ptid_t ptid;
printf_filtered ("sol-thread active.\n");
main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
push_target (&sol_thread_ops);
- inferior_ptid = lwp_to_thread (inferior_ptid);
- if (PIDGET (inferior_ptid) == -1)
- inferior_ptid = main_ph.ptid;
- else
- add_thread (inferior_ptid);
+ ptid = lwp_to_thread (inferior_ptid);
+ if (PIDGET (ptid) != -1)
+ thread_change_ptid (inferior_ptid, ptid);
}
/* FIXME: Might want to iterate over all the threads and register
@@ -381,6 +381,7 @@ sol_thread_attach (char *args, int from_
static void
sol_thread_detach (char *args, int from_tty)
{
+ sol_thread_active = 0;
inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
unpush_target (&sol_thread_ops);
procfs_ops.to_detach (args, from_tty);
@@ -419,7 +420,7 @@ sol_thread_resume (ptid_t ptid, int step
do_cleanups (old_chain);
}
-/* Wait for any threads to stop. We may have to convert PIID from a
+/* Wait for any threads to stop. We may have to convert PTID from a
thread ID to an LWP ID, and vice versa on the way out. */
static ptid_t
@@ -460,7 +461,8 @@ sol_thread_wait (ptid_t ptid, struct tar
/* See if we have a new thread. */
if (is_thread (rtnval)
&& !ptid_equal (rtnval, save_ptid)
- && !in_thread_list (rtnval))
+ && (!in_thread_list (rtnval)
+ || is_exited (rtnval)))
add_thread (rtnval);
}
@@ -754,21 +756,21 @@ static void
sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
int from_tty)
{
+ sol_thread_active = 0;
procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
if (sol_thread_active && !ptid_equal (inferior_ptid, null_ptid))
{
+ ptid_t ptid;
+
/* Save for xfer_memory. */
main_ph.ptid = inferior_ptid;
push_target (&sol_thread_ops);
- inferior_ptid = lwp_to_thread (inferior_ptid);
- if (PIDGET (inferior_ptid) == -1)
- inferior_ptid = main_ph.ptid;
-
- if (!in_thread_list (inferior_ptid))
- add_thread (inferior_ptid);
+ ptid = lwp_to_thread (inferior_ptid);
+ if (PIDGET (ptid) != -1)
+ thread_change_ptid (inferior_ptid, ptid);
}
}
@@ -822,6 +824,7 @@ sol_thread_new_objfile (struct objfile *
static void
sol_thread_mourn_inferior (void)
{
+ sol_thread_active = 0;
unpush_target (&sol_thread_ops);
procfs_ops.to_mourn_inferior ();
}
@@ -1366,7 +1369,7 @@ sol_find_new_threads_callback (const td_
return -1;
ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
- if (!in_thread_list (ptid))
+ if (!in_thread_list (ptid) || is_exited (ptid))
add_thread (ptid);
return 0;
next prev parent reply other threads:[~2008-08-15 19:19 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-08 1:37 Pedro Alves
2008-08-15 17:38 ` Daniel Jacobowitz
2008-08-15 19:19 ` Pedro Alves [this message]
2008-08-16 20:13 ` Daniel Jacobowitz
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=200808152019.16390.pedro@codesourcery.com \
--to=pedro@codesourcery.com \
--cc=drow@false.org \
--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