2008-08-08 Pedro Alves * procfs.c (struct procinfo): Add main_proc member. (find_procinfo): Adjust for the main process having a tid member as well. (open_procinfo_files): Check for the main process with main_proc, instead of checking for tid being 0. (create_procinfo): If tid is 0, mark this proc as the main process. (destroy_procinfo, proc_get_status, proc_wait_for_stop) (proc_set_traced_signals, proc_set_traced_sysentry) (proc_set_traced_sysexit, proc_set_held_signals) (proc_get_pending_signals, proc_get_signal_actions) (proc_get_held_signals, proc_get_traced_signals) (proc_trace_signal, proc_ignore_signal, proc_get_traced_faults) (proc_get_traced_sysentry, proc_get_traced_sysexit) (proc_clear_current_fault, proc_set_current_signal) (proc_clear_current_signal, proc_get_fpregs, proc_set_fpregs) (proc_parent_pid, proc_get_nthreads, proc_get_current_thread) (proc_update_threads, proc_iterate_over_threads, procfs_attach): Check for the main process with main_proc, instead of checking for tid being 0. (procfs_fetch_registers, procfs_store_registers): Remove special handling of the main proc. (procfs_resume): Check for the main process with main_proc, instead of checking for tid being 0. (procfs_init_inferior): Set the tid member on the main process as well. Change the main thread ptid with thread_change_ptid. (procfs_notice_thread): Check for exited threads. * 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 | 132 +++++++++++++++++++++++++++---------------------------- gdb/sol-thread.c | 33 +++++++------ 2 files changed, 84 insertions(+), 81 deletions(-) Index: src/gdb/procfs.c =================================================================== --- src.orig/gdb/procfs.c 2008-08-07 22:53:44.000000000 +0100 +++ src/gdb/procfs.c 2008-08-07 22:53:58.000000000 +0100 @@ -426,6 +426,8 @@ typedef struct procinfo { int gregs_valid : 1; int fpregs_valid : 1; int threads_valid: 1; + + int main_proc: 1; /* is this lwp the main process? */ } procinfo; static char errmsg[128]; /* shared error msg buffer */ @@ -478,9 +480,13 @@ find_procinfo (int pid, int tid) calling find_procinfo, if the caller wants to find a new thread. */ - for (pi = pi->thread_list; pi; pi = pi->next) - if (pi->tid == tid) - break; + if (pi->tid == tid) + /* This is the main lwp, we're done. */ + ; + else + for (pi = pi->thread_list; pi; pi = pi->next) + if (pi->tid == tid) + break; } return pi; @@ -623,17 +629,17 @@ open_procinfo_files (procinfo *pi, int w strcpy (tmp, pi->pathname); switch (which) { /* which file descriptor to open? */ case FD_CTL: - if (pi->tid) - strcat (tmp, "/lwpctl"); - else + if (pi->main_proc) strcat (tmp, "/ctl"); + else + strcat (tmp, "/lwpctl"); fd = open_with_retry (tmp, O_WRONLY); if (fd <= 0) return 0; /* fail */ pi->ctl_fd = fd; break; case FD_AS: - if (pi->tid) + if (!pi->main_proc) return 0; /* there is no 'as' file descriptor for an lwp */ strcat (tmp, "/as"); fd = open_with_retry (tmp, O_RDWR); @@ -642,10 +648,10 @@ open_procinfo_files (procinfo *pi, int w pi->as_fd = fd; break; case FD_STATUS: - if (pi->tid) - strcat (tmp, "/lwpstatus"); - else + if (pi->main_proc) strcat (tmp, "/status"); + else + strcat (tmp, "/lwpstatus"); fd = open_with_retry (tmp, O_RDONLY); if (fd <= 0) return 0; /* fail */ @@ -674,7 +680,7 @@ open_procinfo_files (procinfo *pi, int w if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0) return 0; #else /* Sol 2.5, Irix, other? */ - if (pi->tid == 0) /* Master procinfo for the process */ + if (pi->main_proc) /* Master procinfo for the process */ { fd = open_with_retry (pi->pathname, O_RDWR); if (fd <= 0) @@ -732,6 +738,10 @@ create_procinfo (int pid, int tid) pi->pid = pid; pi->tid = tid; + /* We'll update the tid field later, and we need to remember this is + the main proc. */ + pi->main_proc = (pi->tid == 0); + #ifdef DYNAMIC_SYSCALLS load_syscalls (pi); #endif @@ -740,7 +750,7 @@ create_procinfo (int pid, int tid) pi->saved_exitset = sysset_t_alloc (pi); /* Chain into list. */ - if (tid == 0) + if (pi->main_proc) { sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid); pi->next = procinfo_list; @@ -818,7 +828,7 @@ destroy_procinfo (procinfo *pi) { procinfo *tmp; - if (pi->tid != 0) /* destroy a thread procinfo */ + if (!pi->main_proc) /* destroy a thread procinfo */ { tmp = find_procinfo (pi->pid, 0); /* find the parent process */ destroy_one_procinfo (&tmp->thread_list, pi); @@ -1162,7 +1172,7 @@ proc_get_status (procinfo *pi) { /* Sigh... I have to read a different data structure, depending on whether this is a main process or an LWP. */ - if (pi->tid) + if (!pi->main_proc) pi->status_valid = (read (pi->status_fd, (char *) &pi->prstatus.pr_lwp, sizeof (lwpstatus_t)) @@ -1187,7 +1197,7 @@ proc_get_status (procinfo *pi) } #else /* ioctl method */ #ifdef PIOCTSTATUS /* osf */ - if (pi->tid == 0) /* main process */ + if (pi->main_proc) { /* Just read the danged status. Now isn't that simple? */ pi->status_valid = @@ -1434,7 +1444,7 @@ proc_modify_flag (procinfo *pi, long fla * unnecessarily. */ - if (pi->pid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API /* Newest method: UnixWare and newer Solarii */ @@ -1713,7 +1723,7 @@ proc_wait_for_stop (procinfo *pi) * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -1830,7 +1840,7 @@ proc_set_traced_signals (procinfo *pi, g * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -1876,7 +1886,7 @@ proc_set_traced_faults (procinfo *pi, fl * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -1920,7 +1930,7 @@ proc_set_traced_sysentry (procinfo *pi, * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -1970,7 +1980,7 @@ proc_set_traced_sysexit (procinfo *pi, s * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2020,7 +2030,7 @@ proc_set_held_signals (procinfo *pi, gdb * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2063,7 +2073,7 @@ proc_get_pending_signals (procinfo *pi, * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); if (!pi->status_valid) @@ -2100,7 +2110,7 @@ proc_get_signal_actions (procinfo *pi, g * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); if (!pi->status_valid) @@ -2137,7 +2147,7 @@ proc_get_held_signals (procinfo *pi, gdb * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2183,7 +2193,7 @@ proc_get_traced_signals (procinfo *pi, g * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2225,7 +2235,7 @@ proc_trace_signal (procinfo *pi, int sig * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); if (pi) @@ -2259,7 +2269,7 @@ proc_ignore_signal (procinfo *pi, int si * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); if (pi) @@ -2293,7 +2303,7 @@ proc_get_traced_faults (procinfo *pi, fl * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2335,7 +2345,7 @@ proc_get_traced_sysentry (procinfo *pi, * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2408,7 +2418,7 @@ proc_get_traced_sysexit (procinfo *pi, s * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2481,7 +2491,7 @@ proc_clear_current_fault (procinfo *pi) * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2529,7 +2539,7 @@ proc_set_current_signal (procinfo *pi, i * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef PROCFS_DONT_PIOCSSIG_CURSIG @@ -2600,7 +2610,7 @@ proc_clear_current_signal (procinfo *pi) * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #ifdef NEW_PROC_API @@ -2692,13 +2702,13 @@ proc_get_fpregs (procinfo *pi) thread_fpregs.pr_count = 1; thread_fpregs.thread_1.tid = pi->tid; - if (pi->tid == 0 + if (pi->main_proc && ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0) { pi->fpregs_valid = 1; return &pi->fpregset; /* Got 'em now! */ } - else if (pi->tid != 0 + else if (!pi->main_proc && ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0) { memcpy (&pi->fpregset, &thread_fpregs.thread_1.pr_fpregs, @@ -2798,7 +2808,7 @@ proc_set_fpregs (procinfo *pi) win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg)); #else # ifdef PIOCTSFPREG - if (pi->tid == 0) + if (pi->main_proc) win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0); else { @@ -2882,7 +2892,7 @@ proc_parent_pid (procinfo *pi) * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); if (!pi->status_valid) @@ -3130,7 +3140,7 @@ proc_get_nthreads (procinfo *pi) * because the LWP procinfos do not get prstatus filled in. */ #ifdef NEW_PROC_API - if (pi->tid != 0) /* find the parent process procinfo */ + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); #endif return pi->prstatus.pr_nlwp; @@ -3171,7 +3181,7 @@ proc_get_current_thread (procinfo *pi) * find the parent process procinfo. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); if (!pi->status_valid) @@ -3255,7 +3265,7 @@ proc_update_threads (procinfo *pi) * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); @@ -3310,7 +3320,7 @@ proc_update_threads (procinfo *pi) * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); @@ -3360,7 +3370,7 @@ proc_update_threads (procinfo *pi) * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL); @@ -3434,7 +3444,7 @@ proc_iterate_over_threads (procinfo *pi, * replace it with one that makes sure the ctl_fd is open. */ - if (pi->tid != 0) + if (!pi->main_proc) pi = find_procinfo_or_die (pi->pid, 0); for (thread = pi->thread_list; thread != NULL; thread = next) @@ -3628,6 +3638,8 @@ procfs_attach (char *args, int from_tty) fflush (stdout); } inferior_ptid = do_attach (pid_to_ptid (pid)); + add_thread_silent (inferior_ptid); + push_target (&procfs_ops); } @@ -3784,14 +3796,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 +3855,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"), @@ -4621,7 +4619,7 @@ procfs_resume (ptid_t ptid, int step, en thread = find_procinfo (PIDGET (ptid), TIDGET (ptid)); if (thread != NULL) { - if (thread->tid != 0) + if (!thread->main_proc) { /* We're to resume a specific thread, and not the others. * Set the child process's PR_ASYNC flag. @@ -4951,9 +4949,11 @@ 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)); + /* The 'process ID' we return to GDB is composed of the actual + process ID plus the lwp ID. */ + pi->tid = proc_get_current_thread (pi); + thread_change_ptid (inferior_ptid, + MERGEPID (pi->pid, pi->tid)); /* Typically two, one trap to exec the shell, one to exec the program being debugged. Defined by "inferior.h". */ @@ -5212,7 +5212,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 +6105,7 @@ procfs_corefile_thread_callback (procinf { struct procfs_corefile_thread_data *args = data; - if (pi != NULL && thread->tid != 0) + if (pi != NULL && !thread->main_proc) { ptid_t saved_ptid = inferior_ptid; inferior_ptid = MERGEPID (pi->pid, thread->tid); Index: src/gdb/sol-thread.c =================================================================== --- src.orig/gdb/sol-thread.c 2008-08-07 22:53:42.000000000 +0100 +++ src/gdb/sol-thread.c 2008-08-07 22:53:58.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;