/* Solaris threads debugging interface.
- Copyright (C) 1996-2005, 2007-2012 Free Software Foundation, Inc.
+ Copyright (C) 1996-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "target.h"
#include "inferior.h"
#include <fcntl.h>
-#include "gdb_stat.h"
+#include <sys/stat.h>
#include <dlfcn.h>
#include "gdbcmd.h"
#include "gdbcore.h"
#include "solib.h"
#include "symfile.h"
#include "observer.h"
-#include "gdb_string.h"
+#include <string.h>
#include "procfs.h"
struct target_ops sol_thread_ops;
-extern char *procfs_pid_to_str (struct target_ops *ops, ptid_t ptid);
-
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
/* Default definitions: These must be defined in tm.h if they are to
be shared with a process module such as procfs. */
-#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)
-#define BUILD_THREAD(tid, pid) ptid_build (pid, 0, tid)
-
/* Pointers to routines from libthread_db resolved by dlopen(). */
static void (*p_td_log)(const int on_off);
if (td_err_table[i].num == errcode)
return td_err_table[i].str;
- sprintf (buf, "Unknown libthread_db error code: %d", errcode);
+ xsnprintf (buf, sizeof (buf), "Unknown libthread_db error code: %d",
+ errcode);
return buf;
}
if (td_thr_state_table[i].num == statecode)
return td_thr_state_table[i].str;
- sprintf (buf, "Unknown libthread_db state code: %d", statecode);
+ xsnprintf (buf, sizeof (buf), "Unknown libthread_db state code: %d",
+ statecode);
return buf;
}
td_thrhandle_t th;
td_err_e val;
- if (is_lwp (thread_id))
+ if (ptid_lwp_p (thread_id))
return thread_id; /* It's already an LWP ID. */
/* It's a thread. Convert to LWP. */
- val = p_td_ta_map_id2thr (main_ta, GET_THREAD (thread_id), &th);
+ val = p_td_ta_map_id2thr (main_ta, ptid_get_tid (thread_id), &th);
if (val == TD_NOTHR)
return pid_to_ptid (-1); /* Thread must have terminated. */
else if (val != TD_OK)
td_state_string (ti.ti_state));
}
- return BUILD_LWP (ti.ti_lid, PIDGET (thread_id));
+ return ptid_build (ptid_get_pid (thread_id), ti.ti_lid, 0);
}
/* Convert an LWP ID into a POSIX or Solaris thread ID. If LWP_ID
td_thrhandle_t th;
td_err_e val;
- if (is_thread (lwp))
+ if (ptid_tid_p (lwp))
return lwp; /* It's already a thread ID. */
/* It's an LWP. Convert it to a thread ID. */
if (!target_thread_alive (lwp))
return pid_to_ptid (-1); /* Must be a defunct LPW. */
- val = p_td_ta_map_lwp2thr (main_ta, GET_LWP (lwp), &th);
+ val = p_td_ta_map_lwp2thr (main_ta, ptid_get_lwp (lwp), &th);
if (val == TD_NOTHR)
return pid_to_ptid (-1); /* Thread must have terminated. */
else if (val != TD_OK)
else if (val != TD_OK)
error (_("lwp_to_thread: td_thr_get_info: %s."), td_err_string (val));
- return BUILD_THREAD (ti.ti_tid, PIDGET (lwp));
+ return ptid_build (ptid_get_pid (lwp), 0 , ti.ti_tid);
}
\f
program was started via the normal ptrace (PTRACE_TRACEME). */
static void
-sol_thread_detach (struct target_ops *ops, char *args, int from_tty)
+sol_thread_detach (struct target_ops *ops, const char *args, int from_tty)
{
struct target_ops *beneath = find_target_beneath (ops);
sol_thread_active = 0;
- inferior_ptid = pid_to_ptid (PIDGET (main_ph.ptid));
+ inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
unpush_target (ops);
beneath->to_detach (beneath, args, from_tty);
}
static void
sol_thread_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum target_signal signo)
+ ptid_t ptid, int step, enum gdb_signal signo)
{
struct cleanup *old_chain;
struct target_ops *beneath = find_target_beneath (ops);
old_chain = save_inferior_ptid ();
- inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
- if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
+ if (ptid_get_pid (inferior_ptid) == -1)
inferior_ptid = procfs_first_available ();
- if (PIDGET (ptid) != -1)
+ if (ptid_get_pid (ptid) != -1)
{
ptid_t save_ptid = ptid;
ptid = thread_to_lwp (ptid, -2);
- if (PIDGET (ptid) == -2) /* Inactive thread. */
+ if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
error (_("This version of Solaris can't start inactive threads."));
- if (info_verbose && PIDGET (ptid) == -1)
+ if (info_verbose && ptid_get_pid (ptid) == -1)
warning (_("Specified thread %ld seems to have terminated"),
- GET_THREAD (save_ptid));
+ ptid_get_tid (save_ptid));
}
beneath->to_resume (beneath, ptid, step, signo);
save_ptid = inferior_ptid;
old_chain = save_inferior_ptid ();
- inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
- if (PIDGET (inferior_ptid) == -1)
+ inferior_ptid = thread_to_lwp (inferior_ptid, ptid_get_pid (main_ph.ptid));
+ if (ptid_get_pid (inferior_ptid) == -1)
inferior_ptid = procfs_first_available ();
- if (PIDGET (ptid) != -1)
+ if (ptid_get_pid (ptid) != -1)
{
ptid_t save_ptid = ptid;
ptid = thread_to_lwp (ptid, -2);
- if (PIDGET (ptid) == -2) /* Inactive thread. */
+ if (ptid_get_pid (ptid) == -2) /* Inactive thread. */
error (_("This version of Solaris can't start inactive threads."));
- if (info_verbose && PIDGET (ptid) == -1)
+ if (info_verbose && ptid_get_pid (ptid) == -1)
warning (_("Specified thread %ld seems to have terminated"),
- GET_THREAD (save_ptid));
+ ptid_get_tid (save_ptid));
}
rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
{
/* Map the LWP of interest back to the appropriate thread ID. */
rtnval = lwp_to_thread (rtnval);
- if (PIDGET (rtnval) == -1)
+ if (ptid_get_pid (rtnval) == -1)
rtnval = save_ptid;
/* See if we have a new thread. */
- if (is_thread (rtnval)
+ if (ptid_tid_p (rtnval)
&& !ptid_equal (rtnval, save_ptid)
&& (!in_thread_list (rtnval)
|| is_exited (rtnval)))
gdb_fpregset_t *fpregset_p = &fpregset;
struct target_ops *beneath = find_target_beneath (ops);
-#if 0
- int xregsize;
- caddr_t xregset;
-#endif
-
- if (!is_thread (inferior_ptid))
+ if (!ptid_tid_p (inferior_ptid))
{
/* It's an LWP; pass the request on to the layer beneath. */
beneath->to_fetch_registers (beneath, regcache, regnum);
}
/* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
- thread = GET_THREAD (inferior_ptid);
+ thread = ptid_get_tid (inferior_ptid);
if (thread == 0)
error (_("sol_thread_fetch_registers: thread == 0"));
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. */
- val = td_thr_getxregsize (&thandle, &xregsize);
- if (val != TD_OK && val != TD_NOXREGS)
- error (_("sol_thread_fetch_registers: td_thr_getxregsize %s"),
- td_err_string (val));
-
- if (val == TD_OK)
- {
- xregset = alloca (xregsize);
- val = td_thr_getxregs (&thandle, xregset);
- if (val != TD_OK)
- error (_("sol_thread_fetch_registers: td_thr_getxregs %s"),
- td_err_string (val));
- }
-#endif
}
static void
td_err_e val;
prgregset_t gregset;
prfpregset_t fpregset;
-#if 0
- int xregsize;
- caddr_t xregset;
-#endif
- if (!is_thread (inferior_ptid))
+ if (!ptid_tid_p (inferior_ptid))
{
struct target_ops *beneath = find_target_beneath (ops);
}
/* Solaris thread: convert INFERIOR_PTID into a td_thrhandle_t. */
- thread = GET_THREAD (inferior_ptid);
+ thread = ptid_get_tid (inferior_ptid);
val = p_td_ta_map_id2thr (main_ta, thread, &thandle);
if (val != TD_OK)
/* Restore new register value. */
regcache_raw_supply (regcache, regnum, old_value);
-
-#if 0
- /* FIXME: libthread_db doesn't seem to handle this right. */
- val = td_thr_getxregsize (&thandle, &xregsize);
- if (val != TD_OK && val != TD_NOXREGS)
- error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
- td_err_string (val));
-
- if (val == TD_OK)
- {
- xregset = alloca (xregsize);
- val = td_thr_getxregs (&thandle, xregset);
- if (val != TD_OK)
- error (_("sol_thread_store_registers: td_thr_getxregs %s"),
- td_err_string (val));
- }
-#endif
}
fill_gregset (regcache, (gdb_gregset_t *) &gregset, regnum);
if (val != TD_OK)
error (_("sol_thread_store_registers: td_thr_setfpregs %s"),
td_err_string (val));
-
-#if 0
- /* FIXME: libthread_db doesn't seem to handle this right. */
- val = td_thr_getxregsize (&thandle, &xregsize);
- if (val != TD_OK && val != TD_NOXREGS)
- error (_("sol_thread_store_registers: td_thr_getxregsize %s"),
- td_err_string (val));
-
- /* ??? Should probably do something about writing the xregs here,
- but what are they? */
-#endif
}
/* Perform partial transfers on OBJECT. See target_read_partial and
old_chain = save_inferior_ptid ();
- if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
+ if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
{
/* It's either a thread or an LWP that isn't alive. Any live
LWP will do so use the first available.
td_err_e err;
ptid_t ptid;
+ /* Don't attempt to use thread_db for remote targets. */
+ if (!(target_can_run (¤t_target) || core_bfd))
+ return;
+
/* Do nothing if we couldn't load libthread_db.so.1. */
if (p_td_ta_new == NULL)
return;
main_ph.ptid = inferior_ptid; /* Save for xfer_memory. */
ptid = lwp_to_thread (inferior_ptid);
- if (PIDGET (ptid) != -1)
+ if (ptid_get_pid (ptid) != -1)
inferior_ptid = ptid;
target_find_new_threads ();
static int
sol_thread_alive (struct target_ops *ops, ptid_t ptid)
{
- if (is_thread (ptid))
+ if (ptid_tid_p (ptid))
{
/* It's a (user-level) thread. */
td_err_e val;
td_thrhandle_t th;
int pid;
- pid = GET_THREAD (ptid);
+ pid = ptid_get_tid (ptid);
if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
return 0; /* Thread not found. */
if ((val = p_td_thr_validate (&th)) != TD_OK)
static ps_err_e
rw_common (int dowrite, const struct ps_prochandle *ph, gdb_ps_addr_t addr,
- char *buf, int size)
+ gdb_byte *buf, int size)
{
int ret;
struct cleanup *old_chain;
old_chain = save_inferior_ptid ();
- if (is_thread (inferior_ptid) || !target_thread_alive (inferior_ptid))
+ if (ptid_tid_p (inferior_ptid) || !target_thread_alive (inferior_ptid))
{
/* It's either a thread or an LWP that isn't alive. Any live
LWP will do so use the first available.
#endif
if (dowrite)
- ret = target_write_memory (addr, buf, size);
+ ret = target_write_memory (addr, (gdb_byte *) buf, size);
else
- ret = target_read_memory (addr, buf, size);
+ ret = target_read_memory (addr, (gdb_byte *) buf, size);
do_cleanups (old_chain);
ps_pdwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
gdb_ps_write_buf_t buf, gdb_ps_size_t size)
{
- return rw_common (1, ph, addr, (char *) buf, size);
+ return rw_common (1, ph, addr, (gdb_byte *) buf, size);
}
/* Copies SIZE bytes from target process .text segment to debugger memory. */
ps_ptwrite (gdb_ps_prochandle_t ph, gdb_ps_addr_t addr,
gdb_ps_write_buf_t buf, gdb_ps_size_t size)
{
- return rw_common (1, ph, addr, (char *) buf, size);
+ return rw_common (1, ph, addr, (gdb_byte *) buf, size);
}
/* Get general-purpose registers for LWP. */
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
- regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
+ regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
target_fetch_registers (regcache, -1);
fill_gregset (regcache, (gdb_gregset_t *) gregset, -1);
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
- regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
+ regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
supply_gregset (regcache, (const gdb_gregset_t *) gregset);
target_store_registers (regcache, -1);
ps_err_e
ps_lgetxregsize (gdb_ps_prochandle_t ph, lwpid_t lwpid, int *xregsize)
{
-#if 0
- int lwp_fd;
- int regsize;
- ps_err_e val;
-
- val = get_lwp_fd (ph, lwpid, &lwp_fd);
- if (val != PS_OK)
- return val;
-
- if (ioctl (lwp_fd, PIOCGXREGSIZE, ®size))
- {
- if (errno == EINVAL)
- return PS_NOFREGS; /* XXX Wrong code, but this is the closest
- thing in proc_service.h */
-
- print_sys_errmsg ("ps_lgetxregsize (): PIOCGXREGSIZE", errno);
- return PS_ERR;
- }
-#endif
-
return PS_OK;
}
ps_err_e
ps_lgetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
{
-#if 0
- int lwp_fd;
- ps_err_e val;
-
- val = get_lwp_fd (ph, lwpid, &lwp_fd);
- if (val != PS_OK)
- return val;
-
- if (ioctl (lwp_fd, PIOCGXREG, xregset))
- {
- print_sys_errmsg ("ps_lgetxregs (): PIOCGXREG", errno);
- return PS_ERR;
- }
-#endif
-
return PS_OK;
}
ps_err_e
ps_lsetxregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, caddr_t xregset)
{
-#if 0
- int lwp_fd;
- ps_err_e val;
-
- val = get_lwp_fd (ph, lwpid, &lwp_fd);
- if (val != PS_OK)
- return val;
-
- if (ioctl (lwp_fd, PIOCSXREG, xregset))
- {
- print_sys_errmsg ("ps_lsetxregs (): PIOCSXREG", errno);
- return PS_ERR;
- }
-#endif
-
return PS_OK;
}
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
- regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
+ regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
target_fetch_registers (regcache, -1);
fill_fpregset (regcache, (gdb_fpregset_t *) fpregset, -1);
old_chain = save_inferior_ptid ();
- inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid));
- regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch);
+ inferior_ptid = ptid_build (ptid_get_pid (inferior_ptid), lwpid, 0);
+ regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset);
target_store_registers (regcache, -1);
struct ssd *pldt)
{
/* NOTE: only used on Solaris, therefore OK to refer to procfs.c. */
- extern struct ssd *procfs_find_LDT_entry (ptid_t);
struct ssd *ret;
/* FIXME: can't I get the process ID from the prochandle or
something? */
- if (PIDGET (inferior_ptid) <= 0 || lwpid <= 0)
+ if (ptid_get_pid (inferior_ptid) <= 0 || lwpid <= 0)
return PS_BADLID;
- ret = procfs_find_LDT_entry (BUILD_LWP (lwpid, PIDGET (inferior_ptid)));
+ ret = procfs_find_LDT_entry (ptid_build (ptid_get_pid (inferior_ptid),
+ lwpid, 0));
if (ret)
{
memcpy (pldt, ret, sizeof (struct ssd));
/* Convert PTID to printable form. */
-char *
+static char *
solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
static char buf[100];
- if (is_thread (ptid))
+ if (ptid_tid_p (ptid))
{
ptid_t lwp;
lwp = thread_to_lwp (ptid, -2);
- if (PIDGET (lwp) == -1)
- sprintf (buf, "Thread %ld (defunct)", GET_THREAD (ptid));
- else if (PIDGET (lwp) != -2)
- sprintf (buf, "Thread %ld (LWP %ld)",
- GET_THREAD (ptid), GET_LWP (lwp));
+ if (ptid_get_pid (lwp) == -1)
+ xsnprintf (buf, sizeof (buf), "Thread %ld (defunct)",
+ ptid_get_tid (ptid));
+ else if (ptid_get_pid (lwp) != -2)
+ xsnprintf (buf, sizeof (buf), "Thread %ld (LWP %ld)",
+ ptid_get_tid (ptid), ptid_get_lwp (lwp));
else
- sprintf (buf, "Thread %ld ", GET_THREAD (ptid));
+ xsnprintf (buf, sizeof (buf), "Thread %ld ",
+ ptid_get_tid (ptid));
}
- else if (GET_LWP (ptid) != 0)
- sprintf (buf, "LWP %ld ", GET_LWP (ptid));
+ else if (ptid_get_lwp (ptid) != 0)
+ xsnprintf (buf, sizeof (buf), "LWP %ld ", ptid_get_lwp (ptid));
else
- sprintf (buf, "process %d ", PIDGET (ptid));
+ xsnprintf (buf, sizeof (buf), "process %d ", ptid_get_pid (ptid));
return buf;
}
if (retval != TD_OK)
return -1;
- ptid = BUILD_THREAD (ti.ti_tid, PIDGET (inferior_ptid));
+ ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, ti.ti_tid);
if (!in_thread_list (ptid) || is_exited (ptid))
add_thread (ptid);
/* Print thr_create start function. */
if (ti.ti_startfunc != 0)
{
- struct minimal_symbol *msym;
- msym = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
- if (msym)
- printf_filtered (" startfunc: %s\n",
- SYMBOL_PRINT_NAME (msym));
- else
- printf_filtered (" startfunc: %s\n",
- paddress (target_gdbarch, ti.ti_startfunc));
+ const struct bound_minimal_symbol msym
+ = lookup_minimal_symbol_by_pc (ti.ti_startfunc);
+
+ printf_filtered (" startfunc=%s",
+ msym.minsym
+ ? SYMBOL_PRINT_NAME (msym.minsym)
+ : paddress (target_gdbarch (), ti.ti_startfunc));
}
/* If thread is asleep, print function that went to sleep. */
if (ti.ti_state == TD_THR_SLEEP)
{
- struct minimal_symbol *msym;
- msym = lookup_minimal_symbol_by_pc (ti.ti_pc);
- if (msym)
- printf_filtered (" - Sleep func: %s\n",
- SYMBOL_PRINT_NAME (msym));
- else
- printf_filtered (" - Sleep func: %s\n",
- paddress (target_gdbarch, ti.ti_startfunc));
+ const struct bound_minimal_symbol msym
+ = lookup_minimal_symbol_by_pc (ti.ti_pc);
+
+ printf_filtered (" sleepfunc=%s",
+ msym.minsym
+ ? SYMBOL_PRINT_NAME (msym.minsym)
+ : paddress (target_gdbarch (), ti.ti_pc));
}
- /* Wrap up line, if necessary. */
- if (ti.ti_state != TD_THR_SLEEP && ti.ti_startfunc == 0)
- printf_filtered ("\n"); /* don't you hate counting newlines? */
+ printf_filtered ("\n");
}
else
warning (_("info sol-thread: failed to get info for thread."));
sol_thread_ops.to_magic = OPS_MAGIC;
}
+/* Silence -Wmissing-prototypes. */
+extern void _initialize_sol_thread (void);
+
void
_initialize_sol_thread (void)
{
resolve (td_thr_getgregs);
resolve (td_thr_setgregs);
- add_target (&sol_thread_ops);
+ complete_target_initialization (&sol_thread_ops);
add_cmd ("sol-threads", class_maintenance, info_solthreads,
_("Show info on Solaris user threads."), &maintenanceinfolist);