/* Machine independent support for SVR4 /proc (process file system) for GDB.
- Copyright (C) 1991 Free Software Foundation, Inc.
+ Copyright 1991, 1992 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support.
This file is part of GDB.
#include <sys/procfs.h>
#include <fcntl.h>
#include <errno.h>
+#include <string.h>
#include "inferior.h"
#include "target.h"
-#include "signame.h"
+#include "command.h"
#define MAX_SYSCALLS 256 /* Maximum number of syscalls for table */
#ifndef PROC_NAME_FMT
-#define PROC_NAME_FMT "/proc/%d"
+#define PROC_NAME_FMT "/proc/%05d"
#endif
#if 1 /* FIXME: Gross and ugly hack to resolve coredep.c global */
int fd; /* File descriptor for /proc entry */
char *pathname; /* Pathname to /proc entry */
int was_stopped; /* Nonzero if was stopped prior to attach */
+ int nopass_next_sigstop; /* Don't pass a sigstop on next resume */
prrun_t prrun; /* Control state when it is run */
prstatus_t prstatus; /* Current process status info */
gregset_t gregset; /* General register set */
#endif
#if defined (PR_ISSYS)
PR_ISSYS, "PR_ISSYS", "Is a system process",
+#endif
+#if defined (PR_STEP)
+ PR_STEP, "PR_STEP", "Process has single step pending",
+#endif
+#if defined (PR_KLC)
+ PR_KLC, "PR_KLC", "Kill-on-last-close is in effect",
+#endif
+#if defined (PR_ASYNC)
+ PR_ASYNC, "PR_ASYNC", "Asynchronous stop is in effect",
+#endif
+#if defined (PR_PCOMPAT)
+ PR_PCOMPAT, "PR_PCOMPAT", "Ptrace compatibility mode in effect",
#endif
0, NULL, NULL
};
#endif
#if defined (PR_JOBCONTROL)
PR_JOBCONTROL, "PR_JOBCONTROL", "Default job control stop signal action",
+#endif
+#if defined (PR_SUSPENDED)
+ PR_SUSPENDED, "PR_SUSPENDED", "Process suspended",
#endif
0, NULL, NULL
};
0, 0, NULL, NULL
};
-/* Translation table for errno values. See intro(2) in most UNIX systems
- Programmers Reference Manuals.
-
- Note that some systems provide a function (strerror) that returns the
- error message string, or a global variable that is the base address of the
- array of character pointers. Perhaps we should try to make use of these
- provided strings if they are present, but at least this is more portable.
- (FIXME?) */
-
-static struct trans errno_table[] =
-{
-#if defined (EPERM)
- EPERM, "EPERM", "Not super-user",
-#endif
-#if defined (ENOENT)
- ENOENT, "ENOENT", "No such file or directory",
-#endif
-#if defined (ESRCH)
- ESRCH, "ESRCH", "No such process",
-#endif
-#if defined (EINTR)
- EINTR, "EINTR", "Interrupted system call",
-#endif
-#if defined (EIO)
- EIO, "EIO", "I/O error",
-#endif
-#if defined (ENXIO)
- ENXIO, "ENXIO", "No such device or address",
-#endif
-#if defined (E2BIG)
- E2BIG, "E2BIG", "Arg list too long",
-#endif
-#if defined (ENOEXEC)
- ENOEXEC, "ENOEXEC", "Exec format error",
-#endif
-#if defined (EBADF)
- EBADF, "EBADF", "Bad file number",
-#endif
-#if defined (ECHILD)
- ECHILD, "ECHILD", "No child process",
-#endif
-#if defined (EAGAIN)
- EAGAIN, "EAGAIN", "No more processes",
-#endif
-#if defined (ENOMEM)
- ENOMEM, "ENOMEM", "Not enough space",
-#endif
-#if defined (EACCES)
- EACCES, "EACCES", "Permission denied",
-#endif
-#if defined (EFAULT)
- EFAULT, "EFAULT", "Bad address",
-#endif
-#if defined (ENOTBLK)
- ENOTBLK, "ENOTBLK", "Block device required",
-#endif
-#if defined (EBUSY)
- EBUSY, "EBUSY", "Device busy",
-#endif
-#if defined (EEXIST)
- EEXIST, "EEXIST", "File exists",
-#endif
-#if defined (EXDEV)
- EXDEV, "EXDEV", "Cross-device link",
-#endif
-#if defined (ENODEV)
- ENODEV, "ENODEV", "No such device",
-#endif
-#if defined (ENOTDIR)
- ENOTDIR, "ENOTDIR", "Not a directory",
-#endif
-#if defined (EISDIR)
- EISDIR, "EISDIR", "Is a directory",
-#endif
-#if defined (EINVAL)
- EINVAL, "EINVAL", "Invalid argument",
-#endif
-#if defined (ENFILE)
- ENFILE, "ENFILE", "File table overflow",
-#endif
-#if defined (EMFILE)
- EMFILE, "EMFILE", "Too many open files",
-#endif
-#if defined (ENOTTY)
- ENOTTY, "ENOTTY", "Not a typewriter",
-#endif
-#if defined (ETXTBSY)
- ETXTBSY, "ETXTBSY", "Text file busy",
-#endif
-#if defined (EFBIG)
- EFBIG, "EFBIG", "File too large",
-#endif
-#if defined (ENOSPC)
- ENOSPC, "ENOSPC", "No space left on device",
-#endif
-#if defined (ESPIPE)
- ESPIPE, "ESPIPE", "Illegal seek",
-#endif
-#if defined (EROFS)
- EROFS, "EROFS", "Read only file system",
-#endif
-#if defined (EMLINK)
- EMLINK, "EMLINK", "Too many links",
-#endif
-#if defined (EPIPE)
- EPIPE, "EPIPE", "Broken pipe",
-#endif
-#if defined (EDOM)
- EDOM, "EDOM", "Math argument out of domain of func",
-#endif
-#if defined (ERANGE)
- ERANGE, "ERANGE", "Math result not representable",
-#endif
-#if defined (ENOMSG)
- ENOMSG, "ENOMSG", "No message of desired type",
-#endif
-#if defined (EIDRM)
- EIDRM, "EIDRM", "Identifier removed",
-#endif
-#if defined (ECHRNG)
- ECHRNG, "ECHRNG", "Channel number out of range",
-#endif
-#if defined (EL2NSYNC)
- EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized",
-#endif
-#if defined (EL3HLT)
- EL3HLT, "EL3HLT", "Level 3 halted",
-#endif
-#if defined (EL3RST)
- EL3RST, "EL3RST", "Level 3 reset",
-#endif
-#if defined (ELNRNG)
- ELNRNG, "ELNRNG", "Link number out of range",
-#endif
-#if defined (EUNATCH)
- EUNATCH, "EUNATCH", "Protocol driver not attached",
-#endif
-#if defined (ENOCSI)
- ENOCSI, "ENOCSI", "No CSI structure available",
-#endif
-#if defined (EL2HLT)
- EL2HLT, "EL2HLT", "Level 2 halted",
-#endif
-#if defined (EDEADLK)
- EDEADLK, "EDEADLK", "Deadlock condition",
-#endif
-#if defined (ENOLCK)
- ENOLCK, "ENOLCK", "No record locks available",
-#endif
-#if defined (EBADE)
- EBADE, "EBADE", "Invalid exchange",
-#endif
-#if defined (EBADR)
- EBADR, "EBADR", "Invalid request descriptor",
-#endif
-#if defined (EXFULL)
- EXFULL, "EXFULL", "Exchange full",
-#endif
-#if defined (ENOANO)
- ENOANO, "ENOANO", "No anode",
-#endif
-#if defined (EBADRQC)
- EBADRQC, "EBADRQC", "Invalid request code",
-#endif
-#if defined (EBADSLT)
- EBADSLT, "EBADSLT", "Invalid slot",
-#endif
-#if defined (EDEADLOCK)
- EDEADLOCK, "EDEADLOCK", "File locking deadlock error",
-#endif
-#if defined (EBFONT)
- EBFONT, "EBFONT", "Bad font file fmt",
-#endif
-#if defined (ENOSTR)
- ENOSTR, "ENOSTR", "Device not a stream",
-#endif
-#if defined (ENODATA)
- ENODATA, "ENODATA", "No data available",
-#endif
-#if defined (ETIME)
- ETIME, "ETIME", "Timer expired",
-#endif
-#if defined (ENOSR)
- ENOSR, "ENOSR", "Out of streams resources",
-#endif
-#if defined (ENONET)
- ENONET, "ENONET", "Machine is not on the network",
-#endif
-#if defined (ENOPKG)
- ENOPKG, "ENOPKG", "Package not installed",
-#endif
-#if defined (EREMOTE)
- EREMOTE, "EREMOTE", "Object is remote",
-#endif
-#if defined (ENOLINK)
- ENOLINK, "ENOLINK", "Link has been severed",
-#endif
-#if defined (EADV)
- EADV, "EADV", "Advertise error",
-#endif
-#if defined (ESRMNT)
- ESRMNT, "ESRMNT", "Srmount error",
-#endif
-#if defined (ECOMM)
- ECOMM, "ECOMM", "Communication error on send",
-#endif
-#if defined (EPROTO)
- EPROTO, "EPROTO", "Protocol error",
-#endif
-#if defined (EMULTIHOP)
- EMULTIHOP, "EMULTIHOP", "Multihop attempted",
-#endif
-#if defined (EDOTDOT)
- EDOTDOT, "EDOTDOT", "RFS specific error",
-#endif
-#if defined (EBADMSG)
- EBADMSG, "EBADMSG", "Not a data message",
-#endif
-#if defined (ENAMETOOLONG)
- ENAMETOOLONG, "ENAMETOOLONG", "File name too long",
-#endif
-#if defined (EOVERFLOW)
- EOVERFLOW, "EOVERFLOW", "Value too large for defined data type",
-#endif
-#if defined (ENOTUNIQ)
- ENOTUNIQ, "ENOTUNIQ", "Name not unique on network",
-#endif
-#if defined (EBADFD)
- EBADFD, "EBADFD", "File descriptor in bad state",
-#endif
-#if defined (EREMCHG)
- EREMCHG, "EREMCHG", "Remote address changed",
-#endif
-#if defined (ELIBACC)
- ELIBACC, "ELIBACC", "Cannot access a needed shared library",
-#endif
-#if defined (ELIBBAD)
- ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library",
-#endif
-#if defined (ELIBSCN)
- ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted",
-#endif
-#if defined (ELIBMAX)
- ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries",
-#endif
-#if defined (ELIBEXEC)
- ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly",
-#endif
-#if defined (EILSEQ)
- EILSEQ, "EILSEQ", "Illegal byte sequence",
-#endif
-#if defined (ENOSYS)
- ENOSYS, "ENOSYS", "Operation not applicable",
-#endif
-#if defined (ELOOP)
- ELOOP, "ELOOP", "Too many symbolic links encountered",
-#endif
-#if defined (ERESTART)
- ERESTART, "ERESTART", "Interrupted system call should be restarted",
-#endif
-#if defined (ESTRPIPE)
- ESTRPIPE, "ESTRPIPE", "Streams pipe error",
-#endif
-#if defined (ENOTEMPTY)
- ENOTEMPTY, "ENOTEMPTY", "Directory not empty",
-#endif
-#if defined (EUSERS)
- EUSERS, "EUSERS", "Too many users",
-#endif
-#if defined (ENOTSOCK)
- ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket",
-#endif
-#if defined (EDESTADDRREQ)
- EDESTADDRREQ, "EDESTADDRREQ", "Destination address required",
-#endif
-#if defined (EMSGSIZE)
- EMSGSIZE, "EMSGSIZE", "Message too long",
-#endif
-#if defined (EPROTOTYPE)
- EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket",
-#endif
-#if defined (ENOPROTOOPT)
- ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available",
-#endif
-#if defined (EPROTONOSUPPORT)
- EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported",
-#endif
-#if defined (ESOCKTNOSUPPORT)
- ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported",
-#endif
-#if defined (EOPNOTSUPP)
- EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint ",
-#endif
-#if defined (EPFNOSUPPORT)
- EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported",
-#endif
-#if defined (EAFNOSUPPORT)
- EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol",
-#endif
-#if defined (EADDRINUSE)
- EADDRINUSE, "EADDRINUSE", "Address already in use",
-#endif
-#if defined (EADDRNOTAVAIL)
- EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address",
-#endif
-#if defined (ENETDOWN)
- ENETDOWN, "ENETDOWN", "Network is down",
-#endif
-#if defined (ENETUNREACH)
- ENETUNREACH, "ENETUNREACH", "Network is unreachable",
-#endif
-#if defined (ENETRESET)
- ENETRESET, "ENETRESET", "Network dropped connection because of reset",
-#endif
-#if defined (ECONNABORTED)
- ECONNABORTED, "ECONNABORTED", "Software caused connection abort",
-#endif
-#if defined (ECONNRESET)
- ECONNRESET, "ECONNRESET", "Connection reset by peer",
-#endif
-#if defined (ENOBUFS)
- ENOBUFS, "ENOBUFS", "No buffer space available",
-#endif
-#if defined (EISCONN)
- EISCONN, "EISCONN", "Transport endpoint is already connected",
-#endif
-#if defined (ENOTCONN)
- ENOTCONN, "ENOTCONN", "Transport endpoint is not connected",
-#endif
-#if defined (ESHUTDOWN)
- ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown",
-#endif
-#if defined (ETOOMANYREFS)
- ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice",
-#endif
-#if defined (ETIMEDOUT)
- ETIMEDOUT, "ETIMEDOUT", "Connection timed out",
-#endif
-#if defined (ECONNREFUSED)
- ECONNREFUSED, "ECONNREFUSED", "Connection refused",
-#endif
-#if defined (EHOSTDOWN)
- EHOSTDOWN, "EHOSTDOWN", "Host is down",
-#endif
-#if defined (EHOSTUNREACH)
- EHOSTUNREACH, "EHOSTUNREACH", "No route to host",
-#endif
-#if defined (EWOULDBLOCK)
- EWOULDBLOCK, "EWOULDBLOCK", "Operation already in progress",
-#endif
-#if defined (EINPROGRESS)
- EINPROGRESS, "EINPROGRESS", "Operation now in progress",
-#endif
-#if defined (ESTALE)
- ESTALE, "ESTALE", "Stale NFS file handle",
-#endif
-#if defined (EUCLEAN)
- EUCLEAN, "EUCLEAN", "Structure needs cleaning",
-#endif
-#if defined (ENOTNAM)
- ENOTNAM, "ENOTNAM", "Not a XENIX named type file",
-#endif
-#if defined (ENAVAIL)
- ENAVAIL, "ENAVAIL", "No XENIX semaphores available",
-#endif
-#if defined (EISNAM)
- EISNAM, "EISNAM", "Is a named type file",
-#endif
-#if defined (EREMOTEIO)
- EREMOTEIO, "EREMOTEIO", "Remote I/O error",
-#endif
- 0, NULL, NULL
-};
-
static char *syscall_table[MAX_SYSCALLS];
/* Prototypes for local functions */
static char *
signalname PARAMS ((int));
+static char *
+errnoname PARAMS ((int));
+
static int
proc_address_to_fd PARAMS ((CORE_ADDR, int));
static int
-open_proc_file PARAMS ((int, struct procinfo *));
+open_proc_file PARAMS ((int, struct procinfo *, int));
static void
close_proc_file PARAMS ((struct procinfo *));
free (locbuf);
}
locbuf = xmalloc (strlen (prefix) + 16);
- (void) sprintf (locbuf, "%s %u", prefix, val);
+ sprintf (locbuf, "%s %u", prefix, val);
name = locbuf;
}
return (name);
}
if (name == NULL)
{
- (void) sprintf (locbuf, "sigcode %u", sip -> si_signo);
+ sprintf (locbuf, "sigcode %u", sip -> si_signo);
name = locbuf;
}
return (name);
}
else
{
- (void) sprintf (locbuf, "syscall %u", syscallnum);
+ sprintf (locbuf, "syscall %u", syscallnum);
rtnval = locbuf;
}
return (rtnval);
static void
init_syscall_table ()
{
- int syscallnum;
-
#if defined (SYS_exit)
syscall_table[SYS_exit] = "exit";
#endif
SYNOPSIS
- int ptrace (int request, int pid, int arg3, int arg4)
+ int ptrace (int request, int pid, PTRACE_ARG3_TYPE arg3, int arg4)
DESCRIPTION
ptrace (request, pid, arg3, arg4)
int request;
int pid;
- int arg3;
+ PTRACE_ARG3_TYPE arg3;
int arg4;
{
error ("internal error - there is a call to ptrace() somewhere");
int signo;
signo = SIGKILL;
- (void) ioctl (pi.fd, PIOCKILL, &signo);
+ ioctl (pi.fd, PIOCKILL, &signo);
close_proc_file (&pi);
wait ((int *) 0);
}
{
if (regno != -1)
{
- (void) ioctl (pi.fd, PIOCGREG, &pi.gregset);
+ ioctl (pi.fd, PIOCGREG, &pi.gregset);
}
fill_gregset (&pi.gregset, regno);
- (void) ioctl (pi.fd, PIOCSREG, &pi.gregset);
+ ioctl (pi.fd, PIOCSREG, &pi.gregset);
#if defined (FP0_REGNUM)
if (regno != -1)
{
- (void) ioctl (pi.fd, PIOCGFPREG, &pi.fpregset);
+ ioctl (pi.fd, PIOCGFPREG, &pi.fpregset);
}
fill_fpregset (&pi.fpregset, regno);
- (void) ioctl (pi.fd, PIOCSFPREG, &pi.fpregset);
+ ioctl (pi.fd, PIOCSFPREG, &pi.fpregset);
#endif /* FP0_REGNUM */
inferior_proc_init (pid)
int pid;
{
- if (!open_proc_file (pid, &pi))
+ if (!open_proc_file (pid, &pi, O_RDWR))
{
proc_init_failed ("can't open process file");
}
else
{
- (void) memset ((char *) &pi.prrun, 0, sizeof (pi.prrun));
+ memset ((char *) &pi.prrun, 0, sizeof (pi.prrun));
prfillset (&pi.prrun.pr_trace);
proc_signal_handling_change ();
prfillset (&pi.prrun.pr_fault);
auto char procname[32];
int fd;
- (void) sprintf (procname, PROC_NAME_FMT, getpid ());
+ sprintf (procname, PROC_NAME_FMT, getpid ());
if ((fd = open (procname, O_RDWR)) < 0)
{
perror (procname);
/* Turn off inherit-on-fork flag so that all grand-children of gdb
start with tracing flags cleared. */
-#ifdef PIOCRFORK /* Standard SVR4 */
- (void) ioctl (fd, PIOCRFORK, NULL);
-#else
-#ifdef PIOCRESET /* iris (for example) */
+#if defined (PIOCRESET) /* New method */
{
long pr_flags;
pr_flags = PR_FORK;
- (void) ioctl (fd, PIOCRESET, &pr_flags);
+ ioctl (fd, PIOCRESET, &pr_flags);
+ }
+#else
+#if defined (PIOCRFORK) /* Original method */
+ ioctl (fd, PIOCRFORK, NULL);
+#endif
+#endif
+
+ /* Turn on run-on-last-close flag so that this process will not hang
+ if GDB goes away for some reason. */
+
+#if defined (PIOCSET) /* New method */
+ {
+ long pr_flags;
+ pr_flags = PR_RLC;
+ (void) ioctl (fd, PIOCSET, &pr_flags);
}
+#else
+#if defined (PIOCSRLC) /* Original method */
+ (void) ioctl (fd, PIOCSRLC, 0);
#endif
#endif
}
int funcstat = 0;
struct prmap *prmaps;
struct prmap *prmap;
- CORE_ADDR baseaddr = 0;
if (pi.valid && (ioctl (pi.fd, PIOCNMAP, &nmap) == 0))
{
The option of stopping at attach time is specific to the /proc
versions of gdb. Versions using ptrace force the attachee
- to stop.
+ to stop. (I have changed this version to do so, too. All you
+ have to do is "continue" to make it go on. -- gnu@cygnus.com)
*/
attach (pid)
int pid;
{
- if (!open_proc_file (pid, &pi))
+ int result;
+
+ if (!open_proc_file (pid, &pi, O_RDWR))
{
perror_with_name (pi.pathname);
/* NOTREACHED */
else
{
pi.was_stopped = 0;
- if (query ("Process is currently running, stop it? "))
+ if (1 || query ("Process is currently running, stop it? "))
{
+ /* Make it run again when we close it. */
+#if defined (PIOCSET) /* New method */
+ {
+ long pr_flags;
+ pr_flags = PR_RLC;
+ result = ioctl (pi.fd, PIOCSET, &pr_flags);
+ }
+#else
+#if defined (PIOCSRLC) /* Original method */
+ result = ioctl (pi.fd, PIOCSRLC, 0);
+#endif
+#endif
+ if (result < 0)
+ {
+ print_sys_errmsg (pi.pathname, errno);
+ close_proc_file (&pi);
+ error ("PIOCSRLC or PIOCSET failed");
+ }
if (ioctl (pi.fd, PIOCSTOP, &pi.prstatus) < 0)
{
print_sys_errmsg (pi.pathname, errno);
close_proc_file (&pi);
error ("PIOCSTOP failed");
}
+ pi.nopass_next_sigstop = 1;
+ }
+ else
+ {
+ printf ("Ok, gdb will wait for process %u to stop.\n", pid);
}
}
-
+
/* Remember some things about the inferior that we will, or might, change
so that we can restore them when we detach. */
- (void) ioctl (pi.fd, PIOCGTRACE, &pi.saved_trace);
- (void) ioctl (pi.fd, PIOCGHOLD, &pi.saved_sighold);
- (void) ioctl (pi.fd, PIOCGFAULT, &pi.saved_fltset);
- (void) ioctl (pi.fd, PIOCGENTRY, &pi.saved_entryset);
- (void) ioctl (pi.fd, PIOCGEXIT, &pi.saved_exitset);
+ ioctl (pi.fd, PIOCGTRACE, &pi.saved_trace);
+ ioctl (pi.fd, PIOCGHOLD, &pi.saved_sighold);
+ ioctl (pi.fd, PIOCGFAULT, &pi.saved_fltset);
+ ioctl (pi.fd, PIOCGENTRY, &pi.saved_entryset);
+ ioctl (pi.fd, PIOCGEXIT, &pi.saved_exitset);
/* Set up trace and fault sets, as gdb expects them. */
- (void) memset (&pi.prrun, 0, sizeof (pi.prrun));
+ memset (&pi.prrun, 0, sizeof (pi.prrun));
prfillset (&pi.prrun.pr_trace);
proc_signal_handling_change ();
prfillset (&pi.prrun.pr_fault);
detach (signal)
int signal;
{
+ int result;
+
if (signal)
{
set_proc_siginfo (&pi, signal);
if (signal || !pi.was_stopped ||
query ("Was stopped when attached, make it runnable again? "))
{
- (void) memset (&pi.prrun, 0, sizeof (pi.prrun));
- pi.prrun.pr_flags = PRCFAULT;
- if (ioctl (pi.fd, PIOCRUN, &pi.prrun))
+ /* Clear any fault that might have stopped it. */
+ if (ioctl (pi.fd, PIOCCFAULT, 0))
+ {
+ print_sys_errmsg (pi.pathname, errno);
+ printf ("PIOCCFAULT failed.\n");
+ }
+
+ /* Make it run again when we close it. */
+#if defined (PIOCSET) /* New method */
+ {
+ long pr_flags;
+ pr_flags = PR_RLC;
+ result = ioctl (pi.fd, PIOCSET, &pr_flags);
+ }
+#else
+#if defined (PIOCSRLC) /* Original method */
+ result = ioctl (pi.fd, PIOCSRLC, 0);
+#endif
+#endif
+ if (result)
{
print_sys_errmsg (pi.pathname, errno);
- printf ("PIOCRUN failed.\n");
+ printf ("PIOCSRLC or PIOCSET failed.\n");
}
}
}
}
else
{
- (void) memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
+ memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
sip = &newsiginfo;
sip -> si_signo = signo;
sip -> si_code = 0;
to be current. One case where this might be necessary is if the
user explicitly changes the PC value that gdb considers to be
current. FIXME: Investigate if this is necessary or not.
+
+ When attaching to a child process, if we forced it to stop with
+ a PIOCSTOP, then we will have set the nopass_next_sigstop flag.
+ Upon resuming the first time after such a stop, we explicitly
+ inhibit sending it another SIGSTOP, which would be the normal
+ result of default signal handling. One potential drawback to
+ this is that we will also ignore any attempt to by the user
+ to explicitly continue after the attach with a SIGSTOP. Ultimately
+ this problem should be dealt with by making the routines that
+ deal with the inferior a little smarter, and possibly even allow
+ an inferior to continue running at the same time as gdb. (FIXME?)
*/
void
int signo;
{
errno = 0;
- pi.prrun.pr_flags = PRSVADDR | PRSTRACE | PRSFAULT | PRCFAULT;
+ pi.prrun.pr_flags = PRSTRACE | PRSFAULT | PRCFAULT;
+
+#ifdef PRSVADDR_BROKEN
+/* Can't do this under Solaris running on a Sparc, as there seems to be no
+ place to put nPC. In fact, if you use this, nPC seems to be set to some
+ random garbage. We have to rely on the fact that PC and nPC have been
+ written previously via PIOCSREG during a register flush. */
+
pi.prrun.pr_vaddr = (caddr_t) *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)];
- if (signo)
+ pi.prrun.pr_flags != PRSVADDR;
+#endif
+
+ if (signo && !(signo == SIGSTOP && pi.nopass_next_sigstop))
{
set_proc_siginfo (&pi, signo);
}
{
pi.prrun.pr_flags |= PRCSIG;
}
+ pi.nopass_next_sigstop = 0;
if (step)
{
pi.prrun.pr_flags |= PRSTEP;
}
else
{
- (void) memcpy ((char *) &pi.gregset, core_reg_sect,
- sizeof (pi.gregset));
+ memcpy ((char *) &pi.gregset, core_reg_sect, sizeof (pi.gregset));
supply_gregset (&pi.gregset);
}
}
}
else
{
- (void) memcpy ((char *) &pi.fpregset, core_reg_sect,
- sizeof (pi.fpregset));
+ memcpy ((char *) &pi.fpregset, core_reg_sect, sizeof (pi.fpregset));
#if defined (FP0_REGNUM)
supply_fpregset (&pi.fpregset);
#endif
char *why;
{
print_sys_errmsg (pi.pathname, errno);
- (void) kill (pi.pid, SIGKILL);
+ kill (pi.pid, SIGKILL);
close_proc_file (&pi);
error (why);
/* NOTREACHED */
pip -> pid = 0;
if (pip -> valid)
{
- (void) close (pip -> fd);
+ close (pip -> fd);
}
pip -> fd = -1;
if (pip -> pathname)
SYNOPSIS
- static int open_proc_file (pid, struct procinfo *pip)
+ static int open_proc_file (int pid, struct procinfo *pip, int mode)
DESCRIPTION
- Given a process id, close the existing open /proc entry (if any)
- and open one for the new process id. Once it is open, then
- mark the local process information structure as valid, which
- guarantees that the pid, fd, and pathname fields match an open
- /proc entry. Returns zero if the open fails, nonzero otherwise.
+ Given a process id and a mode, close the existing open /proc
+ entry (if any) and open one for the new process id, in the
+ specified mode. Once it is open, then mark the local process
+ information structure as valid, which guarantees that the pid,
+ fd, and pathname fields match an open /proc entry. Returns
+ zero if the open fails, nonzero otherwise.
Note that the pathname is left intact, even when the open fails,
so that callers can use it to construct meaningful error messages
*/
static int
-open_proc_file (pid, pip)
+open_proc_file (pid, pip, mode)
int pid;
struct procinfo *pip;
+ int mode;
{
- pip -> valid = 0;
+ pip -> valid = 0; /* FIXME, what is this? ?! */
if (pip -> valid)
{
- (void) close (pip -> fd);
+ close (pip -> fd);
}
if (pip -> pathname == NULL)
{
pip -> pathname = xmalloc (32);
}
sprintf (pip -> pathname, PROC_NAME_FMT, pid);
- if ((pip -> fd = open (pip -> pathname, O_RDWR)) >= 0)
+ if ((pip -> fd = open (pip -> pathname, mode)) >= 0)
{
pip -> valid = 1;
pip -> pid = pid;
mappingflags (flags)
long flags;
{
- static char asciiflags[7];
+ static char asciiflags[8];
- strcpy (asciiflags, "------");
- if (flags & MA_STACK) asciiflags[0] = 's';
- if (flags & MA_BREAK) asciiflags[1] = 'b';
- if (flags & MA_SHARED) asciiflags[2] = 's';
- if (flags & MA_READ) asciiflags[3] = 'r';
- if (flags & MA_WRITE) asciiflags[4] = 'w';
- if (flags & MA_EXEC) asciiflags[5] = 'x';
+ strcpy (asciiflags, "-------");
+#if defined (MA_PHYS)
+ if (flags & MA_PHYS) asciiflags[0] = 'd';
+#endif
+ if (flags & MA_STACK) asciiflags[1] = 's';
+ if (flags & MA_BREAK) asciiflags[2] = 'b';
+ if (flags & MA_SHARED) asciiflags[3] = 's';
+ if (flags & MA_READ) asciiflags[4] = 'r';
+ if (flags & MA_WRITE) asciiflags[5] = 'w';
+ if (flags & MA_EXEC) asciiflags[6] = 'x';
return (asciiflags);
}
else
{
printf_filtered ("\t%-16s %s.\n", signalname (what),
- sys_siglist[what]);
+ safe_strsignal (what));
}
break;
case PR_SYSENTRY:
printf_filtered ("%s ", signalname (sip -> si_signo));
if (sip -> si_errno > 0)
{
- printf_filtered ("%s ", lookupname (errno_table,
- sip -> si_errno, "errno"));
+ printf_filtered ("%s ", errnoname (sip -> si_errno));
}
if (sip -> si_code <= 0)
{
{
printf_filtered ("\n\n");
printf_filtered ("\t%-16s %s.\n", signalname (sip -> si_signo),
- sys_siglist[sip -> si_signo]);
+ safe_strsignal (sip -> si_signo));
if (sip -> si_errno > 0)
{
printf_filtered ("\t%-16s %s.\n",
- lookupname (errno_table,
- sip -> si_errno, "errno"),
- lookupdesc (errno_table, sip -> si_errno));
+ errnoname (sip -> si_errno),
+ safe_strerror (sip -> si_errno));
}
if (sip -> si_code <= 0)
{
signalname (signo)
int signo;
{
- char *abbrev;
+ char *name;
static char locbuf[32];
- abbrev = sig_abbrev (signo);
- if (abbrev == NULL)
+ name = strsigno (signo);
+ if (name == NULL)
+ {
+ sprintf (locbuf, "Signal %d", signo);
+ }
+ else
+ {
+ sprintf (locbuf, "%s (%d)", name, signo);
+ }
+ return (locbuf);
+}
+
+static char *
+errnoname (errnum)
+ int errnum;
+{
+ char *name;
+ static char locbuf[32];
+
+ name = strerrno (errnum);
+ if (name == NULL)
{
- sprintf (locbuf, "signal %d", signo);
+ sprintf (locbuf, "Errno %d", errnum);
}
else
{
- sprintf (locbuf, "SIG%s (%d)", abbrev, signo);
+ sprintf (locbuf, "%s (%d)", name, errnum);
}
return (locbuf);
}
printf_filtered ("%-8s ",
prismember (&pip -> prstatus.pr_sigpend, signo)
? "yes" : "no");
- printf_filtered (" %s\n", sys_siglist[signo]);
+ printf_filtered (" %s\n", safe_strsignal (signo));
}
printf_filtered ("\n");
}
if (!summary)
{
printf_filtered ("Mapped address spaces:\n\n");
- printf_filtered ("\t%10s %10s %10s %10s %6s\n",
+ printf_filtered ("\t%10s %10s %10s %10s %7s\n",
"Start Addr",
" End Addr",
" Size",
{
for (prmap = prmaps; prmap -> pr_size; ++prmap)
{
- printf_filtered ("\t%#10x %#10x %#10x %#10x %6s\n",
+ printf_filtered ("\t%#10x %#10x %#10x %#10x %7s\n",
prmap -> pr_vaddr,
prmap -> pr_vaddr + prmap -> pr_size - 1,
prmap -> pr_size,
struct procinfo pii;
struct procinfo *pip;
struct cleanup *old_chain;
- char *nexttok;
char **argv;
int argsize;
int summary = 1;
{
pid = pii.pid;
pip = &pii;
- (void) memset (&pii, 0, sizeof (pii));
- if (!open_proc_file (pid, pip))
+ memset (&pii, 0, sizeof (pii));
+ if (!open_proc_file (pid, pip, O_RDONLY))
{
perror_with_name (pip -> pathname);
/* NOTREACHED */