/* Solaris threads debugging interface.
Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007 Free Software Foundation, Inc.
+ 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GDB.
extern int procfs_suppress_run;
extern struct target_ops procfs_ops; /* target vector for procfs.c */
extern struct target_ops core_ops; /* target vector for corelow.c */
-extern char *procfs_pid_to_str (ptid_t ptid);
+extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
/* 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(). */
for the trace-trap that results from attaching. */
static void
-sol_thread_attach (char *args, int from_tty)
+sol_thread_attach (struct target_ops *ops, char *args, int from_tty)
{
- procfs_ops.to_attach (args, from_tty);
+ sol_thread_active = 0;
+ procfs_ops.to_attach (&procfs_ops, args, from_tty);
/* Must get symbols from shared libraries before libthread_db can run! */
solib_add (NULL, from_tty, (struct target_ops *) 0, auto_solib_add);
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
program was started via the normal ptrace (PTRACE_TRACEME). */
static void
-sol_thread_detach (char *args, int from_tty)
+sol_thread_detach (struct target_ops *ops, 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);
+ procfs_ops.to_detach (&procfs_ops, args, from_tty);
}
/* Resume execution of process PTID. If STEP is nozero, then just
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
-sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+sol_thread_wait (struct target_ops *ops,
+ ptid_t ptid, struct target_waitstatus *ourstatus)
{
ptid_t rtnval;
ptid_t save_ptid;
GET_THREAD (save_ptid));
}
- rtnval = procfs_ops.to_wait (ptid, ourstatus);
+ rtnval = procfs_ops.to_wait (&procfs_ops, ptid, ourstatus);
if (ourstatus->kind != TARGET_WAITKIND_EXITED)
{
/* See if we have a new thread. */
if (is_thread (rtnval)
&& !ptid_equal (rtnval, save_ptid)
- && !in_thread_list (rtnval))
- {
- printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
- add_thread (rtnval);
- }
+ && (!in_thread_list (rtnval)
+ || is_exited (rtnval)))
+ add_thread (rtnval);
}
/* During process initialization, we may get here without the thread
td_err_e val;
prgregset_t gregset;
prfpregset_t fpregset;
+ gdb_gregset_t *gregset_p = &gregset;
+ gdb_fpregset_t *fpregset_p = &fpregset;
+
#if 0
int xregsize;
caddr_t xregset;
calling the td routines because the td routines call ps_lget*
which affect the values stored in the registers array. */
- supply_gregset (regcache, (const gdb_gregset_t *) &gregset);
- supply_fpregset (regcache, (const gdb_fpregset_t *) &fpregset);
+ supply_gregset (regcache, (const gdb_gregset_t *) gregset_p);
+ supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
#if 0
/* FIXME: libthread_db doesn't seem to handle this right. */
/* Fork an inferior process, and start debugging it with /proc. */
static void
-sol_thread_create_inferior (char *exec_file, char *allargs, char **env,
- int from_tty)
+sol_thread_create_inferior (struct target_ops *ops, char *exec_file,
+ char *allargs, char **env, int from_tty)
{
- procfs_ops.to_create_inferior (exec_file, allargs, env, from_tty);
+ sol_thread_active = 0;
+ procfs_ops.to_create_inferior (&procfs_ops, 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);
}
}
/* Clean up after the inferior dies. */
static void
-sol_thread_mourn_inferior (void)
+sol_thread_mourn_inferior (struct target_ops *ops)
{
+ sol_thread_active = 0;
unpush_target (&sol_thread_ops);
- procfs_ops.to_mourn_inferior ();
+ procfs_ops.to_mourn_inferior (&procfs_ops);
}
/* Mark our target-struct as eligible for stray "run" and "attach"
}
static void
-sol_thread_stop (void)
+sol_thread_stop (ptid_t ptid)
{
- procfs_ops.to_stop ();
+ procfs_ops.to_stop (ptid);
}
\f
/* These routines implement the lower half of the thread_db interface,
}
#endif /* PR_MODEL_LP64 */
-#ifdef TM_I386SOL2_H
+#if (defined(__i386__) || defined(__x86_64__)) && defined (sun)
-/* Reads the local descriptor table of a LWP. */
+/* Reads the local descriptor table of a LWP.
+
+ This function is necessary on x86-solaris only. Without it, the loading
+ of libthread_db would fail because of ps_lgetLDT being undefined. */
ps_err_e
ps_lgetLDT (gdb_ps_prochandle_t ph, lwpid_t lwpid,
/* LDT not found. */
return PS_ERR;
}
-#endif /* TM_I386SOL2_H */
+#endif
\f
/* Convert PTID to printable form. */
char *
-solaris_pid_to_str (ptid_t ptid)
+solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
static char buf[100];
/* In case init failed to resolve the libthread_db library. */
if (!procfs_suppress_run)
- return procfs_pid_to_str (ptid);
+ return procfs_pid_to_str (&procfs_ops, ptid);
if (is_thread (ptid))
{
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;
}
static void
-sol_core_detach (char *args, int from_tty)
+sol_core_detach (struct target_ops *ops, char *args, int from_tty)
{
unpush_target (&core_ops);
- orig_core_ops.to_detach (args, from_tty);
+ orig_core_ops.to_detach (&orig_core_ops, args, from_tty);
}
static void
msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
if (msym)
printf_filtered (" startfunc: %s\n",
- DEPRECATED_SYMBOL_NAME (msym));
+ SYMBOL_PRINT_NAME (msym));
else
printf_filtered (" startfunc: 0x%s\n", paddr (ti.ti_startfunc));
}
msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
if (msym)
printf_filtered (" - Sleep func: %s\n",
- DEPRECATED_SYMBOL_NAME (msym));
+ SYMBOL_PRINT_NAME (msym));
else
printf_filtered (" - Sleep func: 0x%s\n", paddr (ti.ti_startfunc));
}
add_cmd ("sol-threads", class_maintenance, info_solthreads,
_("Show info on Solaris user threads."), &maintenanceinfolist);
+ /* FIXME: This code takes errant advantage of the order in which
+ initialization routines are run. _initialize_corelow must run before
+ this one otherwise orig_core_ops will still contain zeros and the work
+ of init_sol_core_ops will be undone. */
memcpy (&orig_core_ops, &core_ops, sizeof (struct target_ops));
memcpy (&core_ops, &sol_core_ops, sizeof (struct target_ops));
add_target (&core_ops);