/* Machine independent support for Solaris /proc (process file system) for GDB.
- Copyright (C) 1999-2018 Free Software Foundation, Inc.
+ Copyright (C) 1999-2019 Free Software Foundation, Inc.
Written by Michael Snyder at Cygnus Solutions.
Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
#include "regcache.h"
#include "inf-child.h"
#include "nat/fork-inferior.h"
-#include "filestuff.h"
+#include "gdbarch.h"
#define _STRUCTURED_PROC 1 /* Should be done by configure script. */
#include <sys/procfs.h>
#include <sys/fault.h>
#include <sys/syscall.h>
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
#include <signal.h>
#include <ctype.h>
#include "gdb_bfd.h"
#include "auxv.h"
#include "procfs.h"
#include "observable.h"
-#include "common/scoped_fd.h"
+#include "gdbsupport/scoped_fd.h"
+#include "gdbsupport/pathstuff.h"
/* This module provides the interface between GDB and the
/proc file system, which is used on many versions of Unix
ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len) override;
- void pass_signals (int, unsigned char *) override;
+ void pass_signals (gdb::array_view<const unsigned char>) override;
void files_info () override;
bool thread_alive (ptid_t ptid) override;
- const char *pid_to_str (ptid_t) override;
+ std::string pid_to_str (ptid_t) override;
+
+ char *pid_to_exec_file (int pid) override;
thread_control_capabilities get_thread_control_capabilities () override
{ return tc_schedlock; }
bool info_proc (const char *, enum info_proc_what) override;
-#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+#if PR_MODEL_NATIVE == PR_MODEL_LP64
int auxv_parse (gdb_byte **readptr,
gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
override;
static procfs_target the_procfs_target;
-#if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+#if PR_MODEL_NATIVE == PR_MODEL_LP64
/* When GDB is built as 64-bit application on Solaris, the auxv data
is presented in 64-bit format. We need to provide a custom parser
to handle that. */
#define AS_PROC_NAME_FMT "/proc/%d/as"
#define MAP_PROC_NAME_FMT "/proc/%d/map"
#define STATUS_PROC_NAME_FMT "/proc/%d/status"
-#define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus")
+#define MAX_PROC_NAME_SIZE sizeof("/proc/999999/lwp/0123456789/lwpstatus")
typedef struct procinfo {
struct procinfo *next;
static procinfo *find_procinfo (int pid, int tid);
static procinfo *create_procinfo (int pid, int tid);
static void destroy_procinfo (procinfo *p);
-static void do_destroy_procinfo_cleanup (void *);
static void dead_procinfo (procinfo *p, const char *msg, int killp);
static int open_procinfo_files (procinfo *p, int which);
static void close_procinfo_files (procinfo *p);
-static sysset_t *sysset_t_alloc (procinfo *pi);
static int iterate_over_mappings
(procinfo *pi, find_memory_region_ftype child_func, void *data,
several. Here is some rationale:
There are several file descriptors that may need to be open
- for any given process or LWP. The ones we're intereted in are:
+ for any given process or LWP. The ones we're interested in are:
- control (ctl) write-only change the state
- status (status) read-only query the state
- address space (as) read/write access memory
{
procinfo *pi, *parent = NULL;
- if ((pi = find_procinfo (pid, tid)))
+ pi = find_procinfo (pid, tid);
+ if (pi != NULL)
return pi; /* Already exists, nothing to do. */
/* Find parent before doing malloc, to save having to cleanup. */
pi->pid = pid;
pi->tid = tid;
- pi->saved_entryset = sysset_t_alloc (pi);
- pi->saved_exitset = sysset_t_alloc (pi);
+ pi->saved_entryset = XNEW (sysset_t);
+ pi->saved_exitset = XNEW (sysset_t);
/* Chain into list. */
if (tid == 0)
{
- sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
+ xsnprintf (pi->pathname, sizeof (pi->pathname), MAIN_PROC_NAME_FMT, pid);
pi->next = procinfo_list;
procinfo_list = pi;
}
else
{
- sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid);
+ xsnprintf (pi->pathname, sizeof (pi->pathname), "/proc/%d/lwp/%d",
+ pid, tid);
pi->next = parent->thread_list;
parent->thread_list = pi;
}
}
}
-static void
-do_destroy_procinfo_cleanup (void *pi)
+/* A deleter that calls destroy_procinfo. */
+struct procinfo_deleter
{
- destroy_procinfo ((procinfo *) pi);
-}
+ void operator() (procinfo *pi) const
+ {
+ destroy_procinfo (pi);
+ }
+};
+
+typedef std::unique_ptr<procinfo, procinfo_deleter> procinfo_up;
enum { NOKILL, KILL };
char procfile[80];
if (pi->pathname)
- {
- print_sys_errmsg (pi->pathname, errno);
- }
+ print_sys_errmsg (pi->pathname, errno);
else
{
- sprintf (procfile, "process %d", pi->pid);
+ xsnprintf (procfile, sizeof (procfile), "process %d", pi->pid);
print_sys_errmsg (procfile, errno);
}
if (kill_p == KILL)
error ("%s", msg);
}
-/* Allocate and (partially) initialize a sysset_t struct. */
-
-static sysset_t *
-sysset_t_alloc (procinfo *pi)
-{
- return (sysset_t *) xmalloc (sizeof (sysset_t));
-}
-
/* =================== END, STRUCT PROCINFO "MODULE" =================== */
/* =================== /proc "MODULE" =================== */
static void
proc_warn (procinfo *pi, const char *func, int line)
{
- sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
+ xsnprintf (errmsg, sizeof (errmsg), "procfs: %s line %d, %s",
+ func, line, pi->pathname);
print_sys_errmsg (errmsg, errno);
}
static void
proc_error (procinfo *pi, const char *func, int line)
{
- sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
+ xsnprintf (errmsg, sizeof (errmsg), "procfs: %s line %d, %s",
+ func, line, pi->pathname);
perror_with_name (errmsg);
}
proc_get_status (procinfo *pi)
{
/* Status file descriptor is opened "lazily". */
- if (pi->status_fd == 0 &&
- open_procinfo_files (pi, FD_STATUS) == 0)
+ if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
{
pi->status_valid = 0;
return 0;
}
/* Reset inherit_on_fork flag. If the process forks a child while we
- are registered for events in the parent, then we will NOT recieve
+ are registered for events in the parent, then we will NOT receive
events from the child. Returns non-zero for success, zero for
failure. */
/* We might conceivably apply this operation to an LWP, and the
LWP's ctl file descriptor might not be open. */
- if (pi->ctl_fd == 0 &&
- open_procinfo_files (pi, FD_CTL) == 0)
+ if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
return 0;
else
{
procfs_ctl_t cmd = PCWSTOP;
+ set_sigint_trap ();
+
win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+
+ clear_sigint_trap ();
+
/* We been runnin' and we stopped -- need to update status. */
pi->status_valid = 0;
/* We will probably have to apply this operation to individual
threads, so make sure the control file descriptor is open. */
- if (pi->ctl_fd == 0 &&
- open_procinfo_files (pi, FD_CTL) == 0)
- {
- return 0;
- }
+ if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
+ return 0;
runflags = PRCFAULT; /* Always clear current fault. */
if (step)
if (pi->tid != 0)
pi = find_procinfo_or_die (pi->pid, 0);
- struct gdb_proc_ctl_pcsentry {
+ struct {
procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char sysset[sizeof (sysset_t)];
- } *argp;
- int argp_size = sizeof (struct gdb_proc_ctl_pcsentry);
-
- argp = (struct gdb_proc_ctl_pcsentry *) xmalloc (argp_size);
+ } arg;
- argp->cmd = PCSENTRY;
- memcpy (&argp->sysset, sysset, sizeof (sysset_t));
+ arg.cmd = PCSENTRY;
+ memcpy (&arg.sysset, sysset, sizeof (sysset_t));
- win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
- xfree (argp);
+ win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
/* The above operation renders the procinfo's cached pstatus
obsolete. */
procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char sysset[sizeof (sysset_t)];
- } *argp;
- int argp_size = sizeof (struct gdb_proc_ctl_pcsexit);
-
- argp = (struct gdb_proc_ctl_pcsexit *) xmalloc (argp_size);
+ } arg;
- argp->cmd = PCSEXIT;
- memcpy (&argp->sysset, sysset, sizeof (sysset_t));
+ arg.cmd = PCSEXIT;
+ memcpy (&arg.sysset, sysset, sizeof (sysset_t));
- win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
- xfree (argp);
+ win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
/* The above operation renders the procinfo's cached pstatus
obsolete. */
/* The pointer is just a type alias. */
get_last_target_status (&wait_ptid, &wait_status);
- if (ptid_equal (wait_ptid, inferior_ptid)
+ if (wait_ptid == inferior_ptid
&& wait_status.kind == TARGET_WAITKIND_STOPPED
&& wait_status.value.sig == gdb_signal_from_host (signo)
&& proc_get_status (pi)
return 0; /* proc_get_regs has already warned. */
if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
- {
- return 0;
- }
+ return 0;
else
{
struct {
return 0; /* proc_get_fpregs has already warned. */
if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
- {
- return 0;
- }
+ return 0;
else
{
struct {
/* We might conceivably apply this operation to an LWP, and the
LWP's ctl file descriptor might not be open. */
- if (pi->ctl_fd == 0 &&
- open_procinfo_files (pi, FD_CTL) == 0)
- {
- return 0;
- }
+ if (pi->ctl_fd == 0 && open_procinfo_files (pi, FD_CTL) == 0)
+ return 0;
else
{
procfs_ctl_t cmd[2];
matching ssh struct (LDT entry). */
static struct ssd *
-proc_get_LDT_entry (procinfo *pi, int key)
+proc_get_LDT_entry (procinfo *pi, int key) /* ARI: editCase function */
{
static struct ssd *ldt_entry = NULL;
char pathname[MAX_PROC_NAME_SIZE];
ldt_entry = XNEW (struct ssd);
/* Open the file descriptor for the LDT table. */
- sprintf (pathname, "/proc/%d/ldt", pi->pid);
+ xsnprintf (pathname, sizeof (pathname), "/proc/%d/ldt", pi->pid);
scoped_fd fd (open_with_retry (pathname, O_RDONLY));
if (fd.get () < 0)
{
while (read (fd.get (), ldt_entry, sizeof (struct ssd))
== sizeof (struct ssd))
{
- if (ldt_entry->sel == 0 &&
- ldt_entry->bo == 0 &&
- ldt_entry->acc1 == 0 &&
- ldt_entry->acc2 == 0)
+ if (ldt_entry->sel == 0
+ && ldt_entry->bo == 0
+ && ldt_entry->acc1 == 0
+ && ldt_entry->acc2 == 0)
break; /* end of table */
/* If key matches, return this entry. */
if (ldt_entry->sel == key)
/* Returns the pointer to the LDT entry of PTID. */
struct ssd *
-procfs_find_LDT_entry (ptid_t ptid)
+procfs_find_LDT_entry (ptid_t ptid) /* ARI: editCase function */
{
gdb_gregset_t *gregs;
int key;
procinfo *pi;
/* Find procinfo for the lwp. */
- if ((pi = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid))) == NULL)
+ pi = find_procinfo (ptid.pid (), ptid.lwp ());
+ if (pi == NULL)
{
warning (_("procfs_find_LDT_entry: could not find procinfo for %d:%ld."),
- ptid_get_pid (ptid), ptid_get_lwp (ptid));
+ ptid.pid (), ptid.lwp ());
return NULL;
}
/* get its general registers. */
- if ((gregs = proc_get_gregs (pi)) == NULL)
+ gregs = proc_get_gregs (pi);
+ if (gregs == NULL)
{
warning (_("procfs_find_LDT_entry: could not read gregs for %d:%ld."),
- ptid_get_pid (ptid), ptid_get_lwp (ptid));
+ ptid.pid (), ptid.lwp ());
return NULL;
}
/* Now extract the GS register's lower 16 bits. */
if (direntry->d_name[0] != '.') /* skip '.' and '..' */
{
lwpid = atoi (&direntry->d_name[0]);
- if ((thread = create_procinfo (pi->pid, lwpid)) == NULL)
+ thread = create_procinfo (pi->pid, lwpid);
+ if (thread == NULL)
proc_error (pi, "update_threads, create_procinfo", __LINE__);
}
pi->threads_valid = 1;
for (thread = pi->thread_list; thread != NULL; thread = next)
{
next = thread->next; /* In case thread is destroyed. */
- if ((retval = (*func) (pi, thread, ptr)) != 0)
+ retval = (*func) (pi, thread, ptr);
+ if (retval != 0)
break;
}
/* Register to trace the 'exit' system call (on entry). */
- traced_syscall_entries = sysset_t_alloc (pi);
+ traced_syscall_entries = XNEW (sysset_t);
premptyset (traced_syscall_entries);
praddset (traced_syscall_entries, SYS_exit);
praddset (traced_syscall_entries, SYS_lwp_exit);
names. On the SGI, for example, there is no SYS_exec, but there
*is* a SYS_execv. So, we try to account for that. */
- traced_syscall_exits = sysset_t_alloc (pi);
+ traced_syscall_exits = XNEW (sysset_t);
premptyset (traced_syscall_exits);
#ifdef SYS_exec
praddset (traced_syscall_exits, SYS_exec);
if (exec_file)
printf_filtered (_("Attaching to program `%s', %s\n"),
- exec_file, target_pid_to_str (pid_to_ptid (pid)));
+ exec_file, target_pid_to_str (ptid_t (pid)).c_str ());
else
printf_filtered (_("Attaching to %s\n"),
- target_pid_to_str (pid_to_ptid (pid)));
+ target_pid_to_str (ptid_t (pid)).c_str ());
fflush (stdout);
}
- inferior_ptid = do_attach (pid_to_ptid (pid));
+ inferior_ptid = do_attach (ptid_t (pid));
if (!target_is_pushed (this))
push_target (this);
}
void
procfs_target::detach (inferior *inf, int from_tty)
{
- int pid = ptid_get_pid (inferior_ptid);
+ int pid = inferior_ptid.pid ();
if (from_tty)
{
exec_file = "";
printf_filtered (_("Detaching from program: %s, %s\n"), exec_file,
- target_pid_to_str (pid_to_ptid (pid)));
- gdb_flush (gdb_stdout);
+ target_pid_to_str (ptid_t (pid)).c_str ());
}
do_detach ();
inferior_ptid = null_ptid;
- detach_inferior (pid);
+ detach_inferior (inf);
maybe_unpush_target ();
}
int fail;
int lwpid;
- if ((pi = create_procinfo (ptid_get_pid (ptid), 0)) == NULL)
+ pi = create_procinfo (ptid.pid (), 0);
+ if (pi == NULL)
perror (_("procfs: out of memory in 'attach'"));
if (!open_procinfo_files (pi, FD_CTL))
{
fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
- sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
- ptid_get_pid (ptid));
+ xsnprintf (errmsg, sizeof (errmsg),
+ "do_attach: couldn't open /proc file for process %d",
+ ptid.pid ());
dead_procinfo (pi, errmsg, NOKILL);
}
if (!proc_get_held_signals (pi, &pi->saved_sighold))
dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL);
- if ((fail = procfs_debug_inferior (pi)) != 0)
+ fail = procfs_debug_inferior (pi);
+ if (fail != 0)
dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL);
inf = current_inferior ();
create_procinfo (pi->pid, lwpid);
/* Add it to gdb's thread list. */
- ptid = ptid_build (pi->pid, lwpid, 0);
+ ptid = ptid_t (pi->pid, lwpid, 0);
add_thread (ptid);
return ptid;
procinfo *pi;
/* Find procinfo for the main process. */
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid),
+ pi = find_procinfo_or_die (inferior_ptid.pid (),
0); /* FIXME: threads */
if (!proc_set_traced_signals (pi, &pi->saved_sigset))
gdb_gregset_t *gregs;
procinfo *pi;
ptid_t ptid = regcache->ptid ();
- int pid = ptid_get_pid (ptid);
- int tid = ptid_get_lwp (ptid);
+ int pid = ptid.pid ();
+ int tid = ptid.lwp ();
struct gdbarch *gdbarch = regcache->arch ();
pi = find_procinfo_or_die (pid, tid);
if (pi == NULL)
error (_("procfs: fetch_registers failed to find procinfo for %s"),
- target_pid_to_str (ptid));
+ target_pid_to_str (ptid).c_str ());
gregs = proc_get_gregs (pi);
if (gregs == NULL)
gdb_gregset_t *gregs;
procinfo *pi;
ptid_t ptid = regcache->ptid ();
- int pid = ptid_get_pid (ptid);
- int tid = ptid_get_lwp (ptid);
+ int pid = ptid.pid ();
+ int tid = ptid.lwp ();
struct gdbarch *gdbarch = regcache->arch ();
pi = find_procinfo_or_die (pid, tid);
if (pi == NULL)
error (_("procfs: store_registers: failed to find procinfo for %s"),
- target_pid_to_str (ptid));
+ target_pid_to_str (ptid).c_str ());
gregs = proc_get_gregs (pi);
if (gregs == NULL)
retry++;
wstat = 0;
- retval = pid_to_ptid (-1);
+ retval = ptid_t (-1);
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
if (pi)
{
/* We must assume that the status is stale now... */
pi->status_valid = 0; /* re-read again, IMMEDIATELY... */
#endif
/* If child is not stopped, wait for it to stop. */
- if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) &&
- !proc_wait_for_stop (pi))
+ if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
+ && !proc_wait_for_stop (pi))
{
/* wait_for_stop failed: has the child terminated? */
if (errno == ENOENT)
wait_retval = ::wait (&wstat); /* "wait" for the child's exit. */
/* Wrong child? */
- if (wait_retval != ptid_get_pid (inferior_ptid))
+ if (wait_retval != inferior_ptid.pid ())
error (_("procfs: couldn't stop "
"process %d: wait returned %d."),
- ptid_get_pid (inferior_ptid), wait_retval);
+ inferior_ptid.pid (), wait_retval);
/* FIXME: might I not just use waitpid?
Or try find_procinfo to see if I know about this child? */
- retval = pid_to_ptid (wait_retval);
+ retval = ptid_t (wait_retval);
}
else if (errno == EINTR)
goto wait_again;
/* The 'pid' we will return to GDB is composed of
the process ID plus the lwp ID. */
- retval = ptid_build (pi->pid, proc_get_current_thread (pi), 0);
+ retval = ptid_t (pi->pid, proc_get_current_thread (pi), 0);
switch (why) {
case PR_SIGNALLED:
{
if (print_thread_events)
printf_unfiltered (_("[%s exited]\n"),
- target_pid_to_str (retval));
- delete_thread (retval);
+ target_pid_to_str (retval).c_str ());
+ delete_thread (find_thread_ptid (retval));
status->kind = TARGET_WAITKIND_SPURIOUS;
return retval;
}
/* If wait returns -1, that's what we return
to GDB. */
if (temp < 0)
- retval = pid_to_ptid (temp);
+ retval = ptid_t (temp);
}
}
else
long i, nsysargs, *sysargs;
- if ((nsysargs = proc_nsysarg (pi)) > 0 &&
- (sysargs = proc_sysargs (pi)) != NULL)
+ nsysargs = proc_nsysarg (pi);
+ sysargs = proc_sysargs (pi);
+
+ if (nsysargs > 0 && sysargs != NULL)
{
printf_filtered (_("%ld syscall arguments:\n"),
nsysargs);
if (!find_procinfo (pi->pid, temp_tid))
create_procinfo (pi->pid, temp_tid);
- temp_ptid = ptid_build (pi->pid, temp_tid, 0);
+ temp_ptid = ptid_t (pi->pid, temp_tid, 0);
/* If not in GDB's thread list, add it. */
if (!in_thread_list (temp_ptid))
add_thread (temp_ptid);
{
if (print_thread_events)
printf_unfiltered (_("[%s exited]\n"),
- target_pid_to_str (retval));
- delete_thread (retval);
+ target_pid_to_str (retval).c_str ());
+ delete_thread (find_thread_ptid (retval));
status->kind = TARGET_WAITKIND_SPURIOUS;
return retval;
}
long i, nsysargs, *sysargs;
- if ((nsysargs = proc_nsysarg (pi)) > 0 &&
- (sysargs = proc_sysargs (pi)) != NULL)
+ nsysargs = proc_nsysarg (pi);
+ sysargs = proc_sysargs (pi);
+
+ if (nsysargs > 0 && sysargs != NULL)
{
printf_filtered (_("%ld syscall arguments:\n"),
nsysargs);
create_procinfo (pi->pid, temp_tid);
/* If not in GDB's thread list, add it. */
- temp_ptid = ptid_build (pi->pid, temp_tid, 0);
+ temp_ptid = ptid_t (pi->pid, temp_tid, 0);
if (!in_thread_list (temp_ptid))
add_thread (temp_ptid);
wstat = (what << 8) | 0177;
break;
case PR_FAULTED:
- switch (what) {
- case FLTWATCH:
- wstat = (SIGTRAP << 8) | 0177;
- break;
- /* FIXME: use si_signo where possible. */
- case FLTPRIV:
- case FLTILL:
- wstat = (SIGILL << 8) | 0177;
- break;
- case FLTBPT:
- case FLTTRACE:
- wstat = (SIGTRAP << 8) | 0177;
- break;
- case FLTSTACK:
- case FLTACCESS:
- case FLTBOUNDS:
- wstat = (SIGSEGV << 8) | 0177;
- break;
- case FLTIOVF:
- case FLTIZDIV:
- case FLTFPE:
- wstat = (SIGFPE << 8) | 0177;
- break;
- case FLTPAGE: /* Recoverable page fault */
- default: /* FIXME: use si_signo if possible for
- fault. */
- retval = pid_to_ptid (-1);
- printf_filtered ("procfs:%d -- ", __LINE__);
- printf_filtered (_("child stopped for unknown reason:\n"));
- proc_prettyprint_why (why, what, 1);
- error (_("... giving up..."));
- break;
+ {
+ int signo = pi->prstatus.pr_lwp.pr_info.si_signo;
+ if (signo != 0)
+ wstat = (signo << 8) | 0177;
}
- break; /* case PR_FAULTED: */
+ break;
default: /* switch (why) unmatched */
printf_filtered ("procfs:%d -- ", __LINE__);
printf_filtered (_("child stopped for unknown reason:\n"));
}
/* Got this far without error: If retval isn't in the
threads database, add it. */
- if (ptid_get_pid (retval) > 0 &&
- !ptid_equal (retval, inferior_ptid) &&
- !in_thread_list (retval))
+ if (retval.pid () > 0
+ && retval != inferior_ptid
+ && !in_thread_list (retval))
{
/* We have a new thread. We need to add it both to
GDB's list and to our own. If we don't create a
procinfo, resume may be unhappy later. */
add_thread (retval);
- if (find_procinfo (ptid_get_pid (retval),
- ptid_get_lwp (retval)) == NULL)
- create_procinfo (ptid_get_pid (retval),
- ptid_get_lwp (retval));
+ if (find_procinfo (retval.pid (),
+ retval.lwp ()) == NULL)
+ create_procinfo (retval.pid (),
+ retval.lwp ());
}
}
else /* Flags do not indicate STOPPED. */
int nbytes;
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
- if (pi->as_fd == 0 &&
- open_procinfo_files (pi, FD_AS) == 0)
+ pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
+ if (pi->as_fd == 0 && open_procinfo_files (pi, FD_AS) == 0)
{
proc_warn (pi, "xfer_memory, open_proc_files", __LINE__);
return TARGET_XFER_E_IO;
File descriptors are also cached. As they are a limited resource,
we cannot hold onto them indefinitely. However, as they are
expensive to open, we don't want to throw them away
- indescriminately either. As a compromise, we will keep the file
+ indiscriminately either. As a compromise, we will keep the file
descriptors for the parent process, but discard any file
descriptors we may have accumulated for the threads.
#if 0
if (pi->gregs_dirty)
- if (parent == NULL ||
- proc_get_current_thread (parent) != pi->tid)
+ if (parent == NULL || proc_get_current_thread (parent) != pi->tid)
if (!proc_set_gregs (pi)) /* flush gregs cache */
proc_warn (pi, "target_resume, set_gregs",
__LINE__);
if (gdbarch_fp0_regnum (target_gdbarch ()) >= 0)
if (pi->fpregs_dirty)
- if (parent == NULL ||
- proc_get_current_thread (parent) != pi->tid)
+ if (parent == NULL || proc_get_current_thread (parent) != pi->tid)
if (!proc_set_fpregs (pi)) /* flush fpregs cache */
proc_warn (pi, "target_resume, set_fpregs",
__LINE__);
to proc_run_process (for use in the prrun struct by ioctl). */
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
/* First cut: ignore pid argument. */
errno = 0;
/* Convert signal to host numbering. */
- if (signo == 0 ||
- (signo == GDB_SIGNAL_STOP && pi->ignore_next_sigstop))
+ if (signo == 0 || (signo == GDB_SIGNAL_STOP && pi->ignore_next_sigstop))
native_signo = 0;
else
native_signo = gdb_signal_to_host (signo);
/* Void the process procinfo's caches. */
invalidate_cache (NULL, pi, NULL);
- if (ptid_get_pid (ptid) != -1)
+ if (ptid.pid () != -1)
{
/* Resume a specific thread, presumably suppressing the
others. */
- thread = find_procinfo (ptid_get_pid (ptid), ptid_get_lwp (ptid));
+ thread = find_procinfo (ptid.pid (), ptid.lwp ());
if (thread != NULL)
{
if (thread->tid != 0)
/* Set up to trace signals in the child process. */
void
-procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
+procfs_target::pass_signals (gdb::array_view<const unsigned char> pass_signals)
{
sigset_t signals;
- procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
int signo;
prfillset (&signals);
for (signo = 0; signo < NSIG; signo++)
{
int target_signo = gdb_signal_from_host (signo);
- if (target_signo < numsigs && pass_signals[target_signo])
+ if (target_signo < pass_signals.size () && pass_signals[target_signo])
prdelset (&signals, signo);
}
printf_filtered (_("\tUsing the running image of %s %s via /proc.\n"),
inf->attach_flag? "attached": "child",
- target_pid_to_str (inferior_ptid));
+ target_pid_to_str (inferior_ptid).c_str ());
}
/* Make it die. Wait for it to die. Clean up after it. Note: this
void
procfs_target::kill ()
{
- if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
+ if (inferior_ptid != null_ptid) /* ? */
{
/* Find procinfo for main process. */
- procinfo *pi = find_procinfo (ptid_get_pid (inferior_ptid), 0);
+ procinfo *pi = find_procinfo (inferior_ptid.pid (), 0);
if (pi)
unconditionally_kill_inferior (pi);
{
procinfo *pi;
- if (!ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid != null_ptid)
{
/* Find procinfo for main process. */
- pi = find_procinfo (ptid_get_pid (inferior_ptid), 0);
+ pi = find_procinfo (inferior_ptid.pid (), 0);
if (pi)
destroy_procinfo (pi);
}
procfs_init_inferior (struct target_ops *ops, int pid)
{
procinfo *pi;
- sigset_t signals;
int fail;
int lwpid;
if (!target_is_pushed (ops))
push_target (ops);
- if ((pi = create_procinfo (pid, 0)) == NULL)
+ pi = create_procinfo (pid, 0);
+ if (pi == NULL)
perror (_("procfs: out of memory in 'init_inferior'"));
if (!open_procinfo_files (pi, FD_CTL))
*/
/* If not stopped yet, wait for it to stop. */
- if (!(proc_flags (pi) & PR_STOPPED) &&
- !(proc_wait_for_stop (pi)))
+ if (!(proc_flags (pi) & PR_STOPPED) && !(proc_wait_for_stop (pi)))
dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL);
/* Save some of the /proc state to be restored if we detach. */
if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__);
- if ((fail = procfs_debug_inferior (pi)) != 0)
+ fail = procfs_debug_inferior (pi);
+ if (fail != 0)
proc_error (pi, "init_inferior (procfs_debug_inferior)", fail);
/* FIXME: logically, we should really be turning OFF run-on-last-close,
/* 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),
- ptid_build (pid, lwpid, 0));
+ thread_change_ptid (ptid_t (pid),
+ ptid_t (pid, lwpid, 0));
gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
}
procinfo *pi;
sysset_t *exitset;
- if ((pi = create_procinfo (getpid (), 0)) == NULL)
+ pi = create_procinfo (getpid (), 0);
+ if (pi == NULL)
perror_with_name (_("procfs: create_procinfo failed in child."));
if (open_procinfo_files (pi, FD_CTL) == 0)
names. On the SGI, for example, there is no SYS_exec, but there
*is* a SYS_execv. So, we try to account for that. */
- exitset = sysset_t_alloc (pi);
+ exitset = XNEW (sysset_t);
premptyset (exitset);
#ifdef SYS_exec
praddset (exitset, SYS_exec);
const std::string &allargs,
char **env, int from_tty)
{
- char *shell_file = getenv ("SHELL");
+ const char *shell_file = get_shell ();
char *tryname;
int pid;
- if (shell_file != NULL && strchr (shell_file, '/') == NULL)
+ if (strchr (shell_file, '/') == NULL)
{
/* We will be looking down the PATH to find shell_file. If we
/* We have something that executes now. We'll be running through
the shell at this point (if startup-with-shell is true), but the
pid shouldn't change. */
- add_thread_silent (pid_to_ptid (pid));
+ add_thread_silent (ptid_t (pid));
procfs_init_inferior (this, pid);
}
static int
procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
{
- ptid_t gdb_threadid = ptid_build (pi->pid, thread->tid, 0);
+ ptid_t gdb_threadid = ptid_t (pi->pid, thread->tid, 0);
- if (!in_thread_list (gdb_threadid) || is_exited (gdb_threadid))
+ thread_info *thr = find_thread_ptid (gdb_threadid);
+ if (thr == NULL || thr->state == THREAD_EXITED)
add_thread (gdb_threadid);
return 0;
prune_threads ();
/* Find procinfo for main process. */
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
proc_update_threads (pi);
proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
}
int proc, thread;
procinfo *pi;
- proc = ptid_get_pid (ptid);
- thread = ptid_get_lwp (ptid);
+ proc = ptid.pid ();
+ thread = ptid.lwp ();
/* If I don't know it, it ain't alive! */
- if ((pi = find_procinfo (proc, thread)) == NULL)
+ pi = find_procinfo (proc, thread);
+ if (pi == NULL)
return false;
/* If I can't get its status, it ain't alive!
return true;
}
-/* Convert PTID to a string. Returns the string in a static
- buffer. */
+/* Convert PTID to a string. */
-const char *
+std::string
procfs_target::pid_to_str (ptid_t ptid)
{
- static char buf[80];
-
- if (ptid_get_lwp (ptid) == 0)
- sprintf (buf, "process %d", ptid_get_pid (ptid));
+ if (ptid.lwp () == 0)
+ return string_printf ("process %d", ptid.pid ());
else
- sprintf (buf, "LWP %ld", ptid_get_lwp (ptid));
+ return string_printf ("LWP %ld", ptid.lwp ());
+}
+
+/* Accepts an integer PID; Returns a string representing a file that
+ can be opened to get the symbols for the child process. */
+
+char *
+procfs_target::pid_to_exec_file (int pid)
+{
+ static char buf[PATH_MAX];
+ char name[PATH_MAX];
+
+ /* Solaris 11 introduced /proc/<proc-id>/execname. */
+ xsnprintf (name, sizeof (name), "/proc/%d/execname", pid);
+ scoped_fd fd (gdb_open_cloexec (name, O_RDONLY, 0));
+ if (fd.get () < 0 || read (fd.get (), buf, PATH_MAX - 1) < 0)
+ {
+ /* If that fails, fall back to /proc/<proc-id>/path/a.out introduced in
+ Solaris 10. */
+ ssize_t len;
+
+ xsnprintf (name, sizeof (name), "/proc/%d/path/a.out", pid);
+ len = readlink (name, buf, PATH_MAX - 1);
+ if (len <= 0)
+ strcpy (buf, name);
+ else
+ buf[len] = '\0';
+ }
return buf;
}
int pflags = 0;
procinfo *pi;
- pi = find_procinfo_or_die (ptid_get_pid (ptid) == -1 ?
- ptid_get_pid (inferior_ptid) : ptid_get_pid (ptid),
+ pi = find_procinfo_or_die (ptid.pid () == -1 ?
+ inferior_ptid.pid () : ptid.pid (),
0);
/* Translate from GDB's flags to /proc's. */
{
procinfo *pi;
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
- {
- if (proc_why (pi) == PR_FAULTED)
- {
- if (proc_what (pi) == FLTWATCH)
- return true;
- }
- }
+ if (proc_why (pi) == PR_FAULTED)
+ if (proc_what (pi) == FLTWATCH)
+ return true;
return false;
}
{
procinfo *pi;
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
return proc_watchpoint_address (pi, addr);
}
{
if (!target_have_steppable_watchpoint
&& !gdbarch_have_nonsteppable_watchpoint (target_gdbarch ()))
- {
- /* When a hardware watchpoint fires off the PC will be left at
- the instruction following the one which caused the
- watchpoint. It will *NOT* be necessary for GDB to step over
- the watchpoint. */
- return procfs_set_watchpoint (inferior_ptid, addr, len, type, 1);
- }
+ /* When a hardware watchpoint fires off the PC will be left at
+ the instruction following the one which caused the
+ watchpoint. It will *NOT* be necessary for GDB to step over
+ the watchpoint. */
+ return procfs_set_watchpoint (inferior_ptid, addr, len, type, 1);
else
- {
- /* When a hardware watchpoint fires off the PC will be left at
- the instruction which caused the watchpoint. It will be
- necessary for GDB to step over the watchpoint. */
- return procfs_set_watchpoint (inferior_ptid, addr, len, type, 0);
- }
+ /* When a hardware watchpoint fires off the PC will be left at
+ the instruction which caused the watchpoint. It will be
+ necessary for GDB to step over the watchpoint. */
+ return procfs_set_watchpoint (inferior_ptid, addr, len, type, 0);
}
int
/* Get the number of mappings, allocate space,
and read the mappings into prmaps. */
/* Open map fd. */
- sprintf (pathname, "/proc/%d/map", pi->pid);
+ xsnprintf (pathname, sizeof (pathname), "/proc/%d/map", pi->pid);
scoped_fd map_fd (open (pathname, O_RDONLY));
if (map_fd.get () < 0)
proc_error (pi, "iterate_over_mappings (read)", __LINE__);
for (prmap = prmaps; nmap > 0; prmap++, nmap--)
- if ((funcstat = (*func) (prmap, child_func, data)) != 0)
- return funcstat;
+ {
+ funcstat = (*func) (prmap, child_func, data);
+ if (funcstat != 0)
+ return funcstat;
+ }
return 0;
}
int
procfs_target::find_memory_regions (find_memory_region_ftype func, void *data)
{
- procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
return iterate_over_mappings (pi, func, data,
find_memory_regions_callback);
bool
procfs_target::info_proc (const char *args, enum info_proc_what what)
{
- struct cleanup *old_chain;
procinfo *process = NULL;
procinfo *thread = NULL;
char *tmp = NULL;
error (_("Not supported on this target."));
}
- old_chain = make_cleanup (null_cleanup, 0);
gdb_argv built_argv (args);
for (char *arg : built_argv)
{
tid = strtoul (arg + 1, NULL, 10);
}
}
+
+ procinfo_up temporary_procinfo;
if (pid == 0)
- pid = ptid_get_pid (inferior_ptid);
+ pid = inferior_ptid.pid ();
if (pid == 0)
error (_("No current process: you must name one."));
else
/* No. So open a procinfo for it, but
remember to close it again when finished. */
process = create_procinfo (pid, 0);
- make_cleanup (do_destroy_procinfo_cleanup, process);
+ temporary_procinfo.reset (process);
if (!open_procinfo_files (process, FD_CTL))
proc_error (process, "info proc, open_procinfo_files", __LINE__);
}
}
if (mappings)
- {
- info_proc_mappings (process, 0);
- }
-
- do_cleanups (old_chain);
+ info_proc_mappings (process, 0);
return true;
}
{
procinfo *pi;
- if (ptid_get_pid (inferior_ptid) <= 0)
+ if (inferior_ptid.pid () <= 0)
error (_("you must be debugging a process to use this command."));
if (args == NULL || args[0] == 0)
error_no_arg (_("system call to trace"));
- pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
if (isdigit (args[0]))
{
const int syscallnum = atoi (args);
ptid_t
procfs_first_available (void)
{
- return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
+ return ptid_t (procinfo_list ? procinfo_list->pid : -1);
}
/* =================== GCORE .NOTE "MODULE" =================== */
gdb_fpregset_t fpregs;
unsigned long merged_pid;
- merged_pid = ptid_get_lwp (ptid) << 16 | ptid_get_pid (ptid);
+ merged_pid = ptid.lwp () << 16 | ptid.pid ();
/* This part is the old method for fetching registers.
It should be replaced by the newer one using regsets
if (pi != NULL)
{
- ptid_t ptid = ptid_build (pi->pid, thread->tid, 0);
+ ptid_t ptid = ptid_t (pi->pid, thread->tid, 0);
args->note_data = procfs_do_thread_registers (args->obfd, ptid,
args->note_data,
find_signalled_thread (struct thread_info *info, void *data)
{
if (info->suspend.stop_signal != GDB_SIGNAL_0
- && ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
+ && info->ptid.pid () == inferior_ptid.pid ())
return 1;
return 0;
char *
procfs_target::make_corefile_notes (bfd *obfd, int *note_size)
{
- struct cleanup *old_chain;
gdb_gregset_t gregs;
- gdb_fpregset_t fpregs;
char fname[16] = {'\0'};
char psargs[80] = {'\0'};
- procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
+ procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
char *note_data = NULL;
- char *inf_args;
+ const char *inf_args;
struct procfs_corefile_thread_data thread_args;
enum gdb_signal stop_signal;
psargs[sizeof (psargs) - 1] = 0;
inf_args = get_inferior_args ();
- if (inf_args && *inf_args &&
- strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs)))
+ if (inf_args && *inf_args
+ && (strlen (inf_args)
+ < ((int) sizeof (psargs) - (int) strlen (psargs))))
{
strncat (psargs, " ",
sizeof (psargs) - strlen (psargs));
fill_gregset (get_current_regcache (), &gregs, -1);
note_data = elfcore_write_pstatus (obfd, note_data, note_size,
- ptid_get_pid (inferior_ptid),
+ inferior_ptid.pid (),
stop_signal, &gregs);
thread_args.obfd = obfd;