aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorFred Fish <fnf@specifix.com>1992-04-01 19:46:14 +0000
committerFred Fish <fnf@specifix.com>1992-04-01 19:46:14 +0000
commitcc221e76d677199b674aa81b9b69597ed3b4da83 (patch)
treed64cd5fa334ab959f2c126d654252dd3deab8d23 /gdb
parent6b80138803cbc1a623bf0df050cf2bfd23df5baa (diff)
downloadgdb-cc221e76d677199b674aa81b9b69597ed3b4da83.zip
gdb-cc221e76d677199b674aa81b9b69597ed3b4da83.tar.gz
gdb-cc221e76d677199b674aa81b9b69597ed3b4da83.tar.bz2
Many changes to procfs.c, mostly to expand the "info proc" command and to
fix a couple of small bugs. Changes to other files mostly to fix minor things pointed out by the SGI compiler. See ChangeLog for complete details.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog67
-rw-r--r--gdb/inferior.h177
-rw-r--r--gdb/infrun.c35
-rw-r--r--gdb/procfs.c1956
-rw-r--r--gdb/xm-irix4.h18
-rw-r--r--gdb/xm-sysv4.h12
6 files changed, 2140 insertions, 125 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e942081..a25d9d3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,70 @@
+Wed Apr 1 11:39:52 1992 Fred Fish (fnf@cygnus.com)
+
+ * breakpoint.h (bpdisp, bptype): Remove trailing comma.
+ * symtab.h (current_source_symtab): Make extern
+ * symtab.h (current_source_line): Make extern
+ * inferior.h: Move all procfs.c prototypes to one place, add
+ prototype for proc_signal_handling_change. Add prototypes for
+ signal_stop_state, signal_print_state, and signal_pass_state.
+ * inferior.h (stop_soon_quietly): Make extern
+ * inferior.h (attach_flag): Make extern
+ * infrun.c (NOTICE_SIGNAL_HANDLING_CHANGE): Default is null.
+ * infrun.c (signal_stop_state, signal_print_state,
+ signal_pass_state): New functions to query specific signal
+ handling flags.
+ * infrun.c (handle_command): Minor error message change, add
+ NOTICE_SIGNAL_HANDLING_CHANGE.
+ * procfs.c (open_proc_file): Remove iris specific reset of
+ inherit-on-fork flag, moved to proc_set_exec_trap().
+ * procfs.c (proc_set_exec_trap): Add SVR4 and iris code
+ to reset inherit-on-fork flag, bash comment to GNU form.
+ * procfs.c (proc_base_address, set_proc_siginfo,
+ fetch_core_registers): Conform to code style.
+ * procfs.c (signame.h): Include.
+ * procfs.c (MAX_SYSCALLS, syscall_table[], init_syscalltable(),
+ syscallname(), info_proc_syscalls()): New macros, tables, and
+ functions to organize and report system call information.
+ * procfs.c (saved_fltset, saved_trace, saved_sighold,
+ saved_exitset, saved_entryset): Add to procinfo struct.
+ * procfs.c (struct trans): Add.
+ * procfs.c (pr_flag_table, pr_why_table, faults_table,
+ siginfo_table, errno_table): Tables to translate numeric values
+ to symbolic names and short descriptions.
+ * procfs.c (signalname, info_proc_signals): Add function and
+ prototype.
+ * procfs.c (proc_info): Now info_proc.
+ * procfs.c (proc_info_address_map): Now info_proc_mappings.
+ * procfs.c (info_proc_flags, info_proc_stop, info_proc_siginfo,
+ info_proc_faults, lookupname, lookupdesc, sigcodename,
+ sigcodedesc): New functions.
+ * procfs.c (proc_signal_handling_change): New function to set
+ the trace flags based on the state of gdb's signal handling flags.
+ * procfs.c (inferior_proc_init): Call proc_signal_handling_change
+ and remove code to do PIOCSTRACE ioctl.
+ * procfs.c (attach, detach): Preserve and restore process flags
+ using saved_* fields in procinfo struct.
+ * procfs.c (attach): Call proc_signal_handling_change.
+ * procfs.c (info_proc): Major rework to expand "info proc" cmd.
+ * procfs.c (proc_desc): Update for latest changes.
+ * xm-irix4.h (CREATE_INFERIOR_HOOK): Protect by USE_PROC_FS.
+ * xm-irix4.h (NOTICE_SIGNAL_HANDLING_CHANGE): Add definition.
+ * xm-sysv4.h (NOTICE_SIGNAL_HANDLING_CHANGE): Add definition.
+
+Tue Mar 31 18:38:28 1992 Fred Fish (fnf@cygnus.com)
+
+ * procfs.c (set_proc_siginfo): Add prototype and new function.
+ * procfs.c (detach, child_resume): Call set_proc_siginfo to set
+ up inferior siginfo struct.
+ * elfread.c (elf_symfile_read): Compute the relocation amount
+ by subtracting off the address of the ".text" section.
+ * solib.c: Add pointer to ".text" section to so_list struct.
+ * solib.c (solib_map_sections): Initialize pointer to ".text"
+ section in so_list struct.
+ * solib.c (symbol_add_stub): Pass base address of ".text"
+ section to symbol_file_add, rather than the load address of
+ the shared library. On SunOS they are the same. On SVR4 they
+ are not.
+
Tue Mar 31 17:48:15 1992 Stu Grossman (grossman at cygnus.com)
* mipsread.c (parse_procedure): PDR.isym should get pointer to
diff --git a/gdb/inferior.h b/gdb/inferior.h
index eed848c..ce92228 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -1,6 +1,6 @@
/* Variables that describe the inferior process running under GDB:
Where it is, why it stopped, and how to step it.
- Copyright (C) 1986, 1989 Free Software Foundation, Inc.
+ Copyright 1986, 1989, 1992 Free Software Foundation, Inc.
This file is part of GDB.
@@ -18,6 +18,12 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+#if !defined (INFERIOR_H)
+#define INFERIOR_H 1
+
+/* For symtab_and_line */
+#include "symtab.h"
+
/* For bpstat. */
#include "breakpoint.h"
@@ -57,7 +63,11 @@ struct inferior_status {
int proceed_to_finish;
};
-void save_inferior_status (), restore_inferior_status ();
+extern void
+save_inferior_status PARAMS ((struct inferior_status *, int));
+
+extern void
+restore_inferior_status PARAMS ((struct inferior_status *));
/* File name for default use for standard in/out in the inferior. */
@@ -71,29 +81,142 @@ extern int inferior_pid;
extern char registers[];
-extern void clear_proceed_status ();
-extern void start_inferior ();
-extern void proceed ();
-extern void kill_inferior ();
-extern void kill_inferior_fast ();
-extern void generic_mourn_inferior ();
-extern void terminal_ours ();
-extern void detach ();
-extern void run_stack_dummy ();
-extern CORE_ADDR read_pc ();
-extern void write_pc ();
-extern void wait_for_inferior ();
-extern void init_wait_for_inferior ();
-extern void close_exec_file ();
-extern void reopen_exec_file ();
+extern void
+clear_proceed_status PARAMS ((void));
+
+extern void
+proceed PARAMS ((CORE_ADDR, int, int));
+
+extern void
+kill_inferior PARAMS ((void));
+
+extern void
+kill_inferior_fast PARAMS ((void));
+
+extern void
+generic_mourn_inferior PARAMS ((void));
+
+extern void
+terminal_ours PARAMS ((void));
+
+extern void
+run_stack_dummy PARAMS ((CORE_ADDR, char [REGISTER_BYTES]));
+
+extern CORE_ADDR
+read_pc PARAMS ((void));
+
+extern void
+write_pc PARAMS ((CORE_ADDR));
+
+extern void
+wait_for_inferior PARAMS ((void));
+
+extern void
+init_wait_for_inferior PARAMS ((void));
+
+extern void
+close_exec_file PARAMS ((void));
+
+extern void
+reopen_exec_file PARAMS ((void));
+
+/* From misc files */
+
+extern void
+store_inferior_registers PARAMS ((int));
+
+extern void
+fetch_inferior_registers PARAMS ((int));
+
+extern void
+solib_create_inferior_hook PARAMS ((void));
+
+extern void
+child_mourn_inferior PARAMS ((void));
+
+extern void
+child_terminal_info PARAMS ((char *, int));
+
+extern void
+term_info PARAMS ((char *, int));
+
+extern void
+terminal_ours_for_output PARAMS ((void));
+
+extern void
+terminal_inferior PARAMS ((void));
+
+extern void
+terminal_init_inferior PARAMS ((void));
+
+/* From infptrace.c or procfs.c */
+
+extern int
+attach PARAMS ((int));
+
+void
+detach PARAMS ((int));
+
+extern void
+child_resume PARAMS ((int, int));
+
+/* From procfs.c */
+
+#ifdef USE_PROC_FS
+
+extern int
+proc_iterate_over_mappings PARAMS ((int (*) (int, CORE_ADDR)));
+
+extern int
+proc_wait PARAMS ((int *));
+
+extern void
+inferior_proc_init PARAMS ((int));
+
+extern void
+proc_signal_handling_change PARAMS ((void));
+
+extern void
+proc_set_exec_trap PARAMS ((void));
-/* From infcmd.c */
-void attach_command (
-#ifdef __STDC__
- char *arg, int from_tty
#endif
- );
-
+
+/* From inflow.c */
+
+extern void
+new_tty_prefork PARAMS ((char *));
+
+/* From infrun.c */
+
+extern void
+start_remote PARAMS ((void));
+
+extern void
+child_create_inferior PARAMS ((char *, char *, char **));
+
+extern void
+child_attach PARAMS ((char *, int));
+
+extern void
+normal_stop PARAMS ((void));
+
+extern int
+signal_stop_state PARAMS ((int));
+
+extern int
+signal_print_state PARAMS ((int));
+
+extern int
+signal_pass_state PARAMS ((int));
+
+/* From infcmd.c */
+
+extern void
+tty_command PARAMS ((char *, int));
+
+extern void
+attach_command PARAMS ((char *, int));
+
/* Last signal that the inferior received (why it stopped). */
extern int stop_signal;
@@ -157,7 +280,7 @@ extern int step_multi;
when running in the shell before the child program has been exec'd;
and when running some kinds of remote stuff (FIXME?). */
-int stop_soon_quietly;
+extern int stop_soon_quietly;
/* Nonzero if proceed is being used for a "finish" command or a similar
situation when stop_registers should be saved. */
@@ -179,7 +302,7 @@ extern int pc_changed;
/* Nonzero if the child process in inferior_pid was attached rather
than forked. */
-int attach_flag;
+extern int attach_flag;
/* Possible values for CALL_DUMMY_LOCATION. */
#define ON_STACK 1
@@ -195,11 +318,13 @@ int attach_flag;
subtracted out. */
#if !defined (PC_IN_CALL_DUMMY)
#if CALL_DUMMY_LOCATION == BEFORE_TEXT_END
+extern CORE_ADDR text_end;
#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \
((pc) >= text_end - CALL_DUMMY_LENGTH \
&& (pc) < text_end + DECR_PC_AFTER_BREAK)
#else /* Not before text_end. */
#if CALL_DUMMY_LOCATION == AFTER_TEXT_END
+extern CORE_ADDR text_end;
#define PC_IN_CALL_DUMMY(pc, sp, frame_address) \
((pc) >= text_end \
&& (pc) < text_end + CALL_DUMMY_LENGTH + DECR_PC_AFTER_BREAK)
@@ -209,3 +334,5 @@ int attach_flag;
#endif /* On stack. */
#endif /* Not before text_end. */
#endif /* No PC_IN_CALL_DUMMY. */
+
+#endif /* !defined (INFERIOR_H) */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 9bd4d3e..98e7227 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -158,6 +158,9 @@ resume_cleanups PARAMS ((int));
extern char **environ;
+extern int sys_nerr;
+extern char *sys_errlist[];
+
extern struct target_ops child_ops; /* In inftarg.c */
/* Sigtramp is a routine that the kernel calls (which then calls the
@@ -198,6 +201,12 @@ extern struct target_ops child_ops; /* In inftarg.c */
#define IN_SOLIB_TRAMPOLINE(pc,name) 0
#endif
+/* Notify other parts of gdb that might care that signal handling may
+ have changed for one or more signals. */
+#ifndef NOTICE_SIGNAL_HANDLING_CHANGE
+#define NOTICE_SIGNAL_HANDLING_CHANGE /* No actions */
+#endif
+
#ifdef TDESC
#include "tdesc.h"
int safe_to_init_tdesc_context = 0;
@@ -466,8 +475,6 @@ child_create_inferior (exec_file, allargs, env)
{
int pid;
char *shell_command;
- extern int sys_nerr;
- extern char *sys_errlist[];
char *shell_file;
static char default_shell_file[] = SHELL_FILE;
int len;
@@ -1128,7 +1135,7 @@ wait_for_inferior ()
#if 0
if (* step_frame_address == 0
|| (step_frame_address == stop_frame_address))
-#endif 0
+#endif
{
remove_step_breakpoint ();
step_resume_break_address = 0;
@@ -1579,6 +1586,24 @@ remove_step_breakpoint ()
step_resume_break_shadow);
}
+int signal_stop_state (signo)
+ int signo;
+{
+ return ((signo >= 0 && signo < NSIG) ? signal_stop[signo] : 0);
+}
+
+int signal_print_state (signo)
+ int signo;
+{
+ return ((signo >= 0 && signo < NSIG) ? signal_print[signo] : 0);
+}
+
+int signal_pass_state (signo)
+ int signo;
+{
+ return ((signo >= 0 && signo < NSIG) ? signal_program[signo] : 0);
+}
+
static void
sig_print_header ()
{
@@ -1688,7 +1713,7 @@ handle_command (args, from_tty)
/* Not a number and not a recognized flag word => complain. */
else
{
- error ("Unrecognized flag word: \"%s\".", p);
+ error ("Unrecognized or ambiguous flag word: \"%s\".", p);
}
/* Find start of next word. */
@@ -1696,6 +1721,8 @@ handle_command (args, from_tty)
while (*p == ' ' || *p == '\t') p++;
}
+ NOTICE_SIGNAL_HANDLING_CHANGE;
+
if (from_tty)
{
/* Show the results. */
diff --git a/gdb/procfs.c b/gdb/procfs.c
index dc5ae10..407c65f 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -43,6 +43,9 @@ regardless of whether or not the actual target has floating point hardware.
#include "inferior.h"
#include "target.h"
+#include "signame.h"
+
+#define MAX_SYSCALLS 256 /* Maximum number of syscalls for table */
#ifndef PROC_NAME_FMT
#define PROC_NAME_FMT "/proc/%d"
@@ -52,6 +55,13 @@ regardless of whether or not the actual target has floating point hardware.
CORE_ADDR kernel_u_addr;
#endif
+#ifdef BROKEN_SIGINFO_H /* Workaround broken SGS <sys/siginfo.h> */
+#undef si_pid
+#define si_pid _data._proc.pid
+#undef si_uid
+#define si_uid _data._proc._pdata._kill.uid
+#endif /* BROKEN_SIGINFO_H */
+
/* All access to the inferior, either one started by gdb or one that has
been attached to, is controlled by an instance of a procinfo structure,
defined below. Since gdb currently only handles one inferior at a time,
@@ -75,15 +85,633 @@ struct procinfo {
sigset_t trace; /* Current traced signal set */
sysset_t exitset; /* Current traced system call exit set */
sysset_t entryset; /* Current traced system call entry set */
+ fltset_t saved_fltset; /* Saved traced hardware fault set */
+ sigset_t saved_trace; /* Saved traced signal set */
+ sigset_t saved_sighold; /* Saved held signal set */
+ sysset_t saved_exitset; /* Saved traced system call exit set */
+ sysset_t saved_entryset; /* Saved traced system call entry set */
};
static struct procinfo pi; /* Inferior's process information */
+/* Much of the information used in the /proc interface, particularly for
+ printing status information, is kept as tables of structures of the
+ following form. These tables can be used to map numeric values to
+ their symbolic names and to a string that describes their specific use. */
+
+struct trans {
+ int value; /* The numeric value */
+ char *name; /* The equivalent symbolic value */
+ char *desc; /* Short description of value */
+};
+
+/* Translate bits in the pr_flags member of the prstatus structure, into the
+ names and desc information. */
+
+static struct trans pr_flag_table[] =
+{
+#if defined (PR_STOPPED)
+ PR_STOPPED, "PR_STOPPED", "Process is stopped",
+#endif
+#if defined (PR_ISTOP)
+ PR_ISTOP, "PR_ISTOP", "Stopped on an event of interest",
+#endif
+#if defined (PR_DSTOP)
+ PR_DSTOP, "PR_DSTOP", "A stop directive is in effect",
+#endif
+#if defined (PR_ASLEEP)
+ PR_ASLEEP, "PR_ASLEEP", "Sleeping in an interruptible system call",
+#endif
+#if defined (PR_FORK)
+ PR_FORK, "PR_FORK", "Inherit-on-fork is in effect",
+#endif
+#if defined (PR_RLC)
+ PR_RLC, "PR_RLC", "Run-on-last-close is in effect",
+#endif
+#if defined (PR_PTRACE)
+ PR_PTRACE, "PR_PTRACE", "Process is being controlled by ptrace",
+#endif
+#if defined (PR_PCINVAL)
+ PR_PCINVAL, "PR_PCINVAL", "PC refers to an invalid virtual address",
+#endif
+#if defined (PR_ISSYS)
+ PR_ISSYS, "PR_ISSYS", "Is a system process",
+#endif
+ 0, NULL, NULL
+};
+
+/* Translate values in the pr_why field of the prstatus struct. */
+
+static struct trans pr_why_table[] =
+{
+#if defined (PR_REQUESTED)
+ PR_REQUESTED, "PR_REQUESTED", "Directed to stop via PIOCSTOP/PIOCWSTOP",
+#endif
+#if defined (PR_SIGNALLED)
+ PR_SIGNALLED, "PR_SIGNALLED", "Receipt of a traced signal",
+#endif
+#if defined (PR_FAULTED)
+ PR_FAULTED, "PR_FAULTED", "Incurred a traced hardware fault",
+#endif
+#if defined (PR_SYSENTRY)
+ PR_SYSENTRY, "PR_SYSENTRY", "Entry to a traced system call",
+#endif
+#if defined (PR_SYSEXIT)
+ PR_SYSEXIT, "PR_SYSEXIT", "Exit from a traced system call",
+#endif
+#if defined (PR_JOBCONTROL)
+ PR_JOBCONTROL, "PR_JOBCONTROL", "Default job control stop signal action",
+#endif
+ 0, NULL, NULL
+};
+
+/* Hardware fault translation table. */
+
+static struct trans faults_table[] =
+{
+#if defined (FLTILL)
+ FLTILL, "FLTILL", "Illegal instruction",
+#endif
+#if defined (FLTPRIV)
+ FLTPRIV, "FLTPRIV", "Privileged instruction",
+#endif
+#if defined (FLTBPT)
+ FLTBPT, "FLTBPT", "Breakpoint trap",
+#endif
+#if defined (FLTTRACE)
+ FLTTRACE, "FLTTRACE", "Trace trap",
+#endif
+#if defined (FLTACCESS)
+ FLTACCESS, "FLTACCESS", "Memory access fault",
+#endif
+#if defined (FLTBOUNDS)
+ FLTBOUNDS, "FLTBOUNDS", "Memory bounds violation",
+#endif
+#if defined (FLTIOVF)
+ FLTIOVF, "FLTIOVF", "Integer overflow",
+#endif
+#if defined (FLTIZDIV)
+ FLTIZDIV, "FLTIZDIV", "Integer zero divide",
+#endif
+#if defined (FLTFPE)
+ FLTFPE, "FLTFPE", "Floating-point exception",
+#endif
+#if defined (FLTSTACK)
+ FLTSTACK, "FLTSTACK", "Unrecoverable stack fault",
+#endif
+#if defined (FLTPAGE)
+ FLTPAGE, "FLTPAGE", "Recoverable page fault",
+#endif
+ 0, NULL, NULL
+};
+
+/* Translation table for signal generation information. See UNIX System
+ V Release 4 Programmer's Reference Manual, siginfo(5). */
+
+static struct sigcode {
+ int signo;
+ int code;
+ char *codename;
+ char *desc;
+} siginfo_table[] = {
+#if defined (SIGILL) && defined (ILL_ILLOPC)
+ SIGILL, ILL_ILLOPC, "ILL_ILLOPC", "Illegal opcode",
+#endif
+#if defined (SIGILL) && defined (ILL_ILLOPN)
+ SIGILL, ILL_ILLOPN, "ILL_ILLOPN", "Illegal operand",
+#endif
+#if defined (SIGILL) && defined (ILL_ILLADR)
+ SIGILL, ILL_ILLADR, "ILL_ILLADR", "Illegal addressing mode",
+#endif
+#if defined (SIGILL) && defined (ILL_ILLTRP)
+ SIGILL, ILL_ILLTRP, "ILL_ILLTRP", "Illegal trap",
+#endif
+#if defined (SIGILL) && defined (ILL_PRVOPC)
+ SIGILL, ILL_PRVOPC, "ILL_PRVOPC", "Privileged opcode",
+#endif
+#if defined (SIGILL) && defined (ILL_PRVREG)
+ SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register",
+#endif
+#if defined (SIGILL) && defined (ILL_COPROC)
+ SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error",
+#endif
+#if defined (SIGILL) && defined (ILL_BADSTK)
+ SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error",
+#endif
+#if defined (SIGFPE) && defined (FPE_INTDIV)
+ SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero",
+#endif
+#if defined (SIGFPE) && defined (FPE_INTOVF)
+ SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow",
+#endif
+#if defined (SIGFPE) && defined (FPE_FLTDIV)
+ SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating point divide by zero",
+#endif
+#if defined (SIGFPE) && defined (FPE_FLTOVF)
+ SIGFPE, FPE_FLTOVF, "FPE_FLTOVF", "Floating point overflow",
+#endif
+#if defined (SIGFPE) && defined (FPE_FLTUND)
+ SIGFPE, FPE_FLTUND, "FPE_FLTUND", "Floating point underflow",
+#endif
+#if defined (SIGFPE) && defined (FPE_FLTRES)
+ SIGFPE, FPE_FLTRES, "FPE_FLTRES", "Floating point inexact result",
+#endif
+#if defined (SIGFPE) && defined (FPE_FLTINV)
+ SIGFPE, FPE_FLTINV, "FPE_FLTINV", "Invalid floating point operation",
+#endif
+#if defined (SIGFPE) && defined (FPE_FLTSUB)
+ SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range",
+#endif
+#if defined (SIGSEGV) && defined (SEGV_MAPERR)
+ SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object",
+#endif
+#if defined (SIGSEGV) && defined (SEGV_ACCERR)
+ SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for object",
+#endif
+#if defined (SIGBUS) && defined (BUS_ADRALN)
+ SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment",
+#endif
+#if defined (SIGBUS) && defined (BUS_ADRERR)
+ SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Non-existent physical address",
+#endif
+#if defined (SIGBUS) && defined (BUS_OBJERR)
+ SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object specific hardware error",
+#endif
+#if defined (SIGTRAP) && defined (TRAP_BRKPT)
+ SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint",
+#endif
+#if defined (SIGTRAP) && defined (TRAP_TRACE)
+ SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap",
+#endif
+#if defined (SIGCLD) && defined (CLD_EXITED)
+ SIGCLD, CLD_EXITED, "CLD_EXITED", "Child has exited",
+#endif
+#if defined (SIGCLD) && defined (CLD_KILLED)
+ SIGCLD, CLD_KILLED, "CLD_KILLED", "Child was killed",
+#endif
+#if defined (SIGCLD) && defined (CLD_DUMPED)
+ SIGCLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally",
+#endif
+#if defined (SIGCLD) && defined (CLD_TRAPPED)
+ SIGCLD, CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped",
+#endif
+#if defined (SIGCLD) && defined (CLD_STOPPED)
+ SIGCLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped",
+#endif
+#if defined (SIGCLD) && defined (CLD_CONTINUED)
+ SIGCLD, CLD_CONTINUED, "CLD_CONTINUED", "Stopped child had continued",
+#endif
+#if defined (SIGPOLL) && defined (POLL_IN)
+ SIGPOLL, POLL_IN, "POLL_IN", "Input input available",
+#endif
+#if defined (SIGPOLL) && defined (POLL_OUT)
+ SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available",
+#endif
+#if defined (SIGPOLL) && defined (POLL_MSG)
+ SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available",
+#endif
+#if defined (SIGPOLL) && defined (POLL_ERR)
+ SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error",
+#endif
+#if defined (SIGPOLL) && defined (POLL_PRI)
+ SIGPOLL, POLL_PRI, "POLL_PRI", "High priority input available",
+#endif
+#if defined (SIGPOLL) && defined (POLL_HUP)
+ SIGPOLL, POLL_HUP, "POLL_HUP", "Device disconnected",
+#endif
+ 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 void
set_proc_siginfo PARAMS ((struct procinfo *, int));
+static void
+init_syscall_table PARAMS ((void));
+
+static char *
+syscallname PARAMS ((int));
+
+static char *
+signalname PARAMS ((int));
+
static int
proc_address_to_fd PARAMS ((CORE_ADDR, int));
@@ -100,14 +728,38 @@ static void
proc_init_failed PARAMS ((char *));
static void
-proc_info PARAMS ((char *, int));
+info_proc PARAMS ((char *, int));
+
+static void
+info_proc_flags PARAMS ((struct procinfo *, int));
+
+static void
+info_proc_stop PARAMS ((struct procinfo *, int));
+
+static void
+info_proc_siginfo PARAMS ((struct procinfo *, int));
+
+static void
+info_proc_syscalls PARAMS ((struct procinfo *, int));
+
+static void
+info_proc_mappings PARAMS ((struct procinfo *, int));
static void
-proc_info_address_map PARAMS ((struct procinfo *, int));
+info_proc_signals PARAMS ((struct procinfo *, int));
+
+static void
+info_proc_faults PARAMS ((struct procinfo *, int));
static char *
mappingflags PARAMS ((long));
+static char *
+lookupname PARAMS ((struct trans *, unsigned int, char *));
+
+static char *
+lookupdesc PARAMS ((struct trans *, unsigned int));
+
/* External function prototypes that can't be easily included in any
header file because the args are typedefs in system include files. */
@@ -123,6 +775,585 @@ supply_fpregset PARAMS ((fpregset_t *));
extern void
fill_fpregset PARAMS ((fpregset_t *, int));
+/*
+
+LOCAL FUNCTION
+
+ lookupdesc -- translate a value to a summary desc string
+
+SYNOPSIS
+
+ static char *lookupdesc (struct trans *transp, unsigned int val);
+
+DESCRIPTION
+
+ Given a pointer to a translation table and a value to be translated,
+ lookup the desc string and return it.
+ */
+
+static char *
+lookupdesc (transp, val)
+ struct trans *transp;
+ unsigned int val;
+{
+ char *desc;
+
+ for (desc = NULL; transp -> name != NULL; transp++)
+ {
+ if (transp -> value == val)
+ {
+ desc = transp -> desc;
+ break;
+ }
+ }
+
+ /* Didn't find a translation for the specified value, set a default one. */
+
+ if (desc == NULL)
+ {
+ desc = "Unknown";
+ }
+ return (desc);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ lookupname -- translate a value to symbolic name
+
+SYNOPSIS
+
+ static char *lookupname (struct trans *transp, unsigned int val,
+ char *prefix);
+
+DESCRIPTION
+
+ Given a pointer to a translation table, a value to be translated,
+ and a default prefix to return if the value can't be translated,
+ match the value with one of the translation table entries and
+ return a pointer to the symbolic name.
+
+ If no match is found it just returns the value as a printable string,
+ with the given prefix. The previous such value, if any, is freed
+ at this time.
+ */
+
+static char *
+lookupname (transp, val, prefix)
+ struct trans *transp;
+ unsigned int val;
+ char *prefix;
+{
+ static char *locbuf;
+ char *name;
+
+ for (name = NULL; transp -> name != NULL; transp++)
+ {
+ if (transp -> value == val)
+ {
+ name = transp -> name;
+ break;
+ }
+ }
+
+ /* Didn't find a translation for the specified value, build a default
+ one using the specified prefix and return it. The lifetime of
+ the value is only until the next one is needed. */
+
+ if (name == NULL)
+ {
+ if (locbuf != NULL)
+ {
+ free (locbuf);
+ }
+ locbuf = xmalloc (strlen (prefix) + 16);
+ (void) sprintf (locbuf, "%s %u", prefix, val);
+ name = locbuf;
+ }
+ return (name);
+}
+
+static char *
+sigcodename (sip)
+ siginfo_t *sip;
+{
+ struct sigcode *scp;
+ char *name = NULL;
+ static char locbuf[32];
+
+ for (scp = siginfo_table; scp -> codename != NULL; scp++)
+ {
+ if ((scp -> signo == sip -> si_signo) &&
+ (scp -> code == sip -> si_code))
+ {
+ name = scp -> codename;
+ break;
+ }
+ }
+ if (name == NULL)
+ {
+ (void) sprintf (locbuf, "sigcode %u", sip -> si_signo);
+ name = locbuf;
+ }
+ return (name);
+}
+
+static char *sigcodedesc (sip)
+ siginfo_t *sip;
+{
+ struct sigcode *scp;
+ char *desc = NULL;
+
+ for (scp = siginfo_table; scp -> codename != NULL; scp++)
+ {
+ if ((scp -> signo == sip -> si_signo) &&
+ (scp -> code == sip -> si_code))
+ {
+ desc = scp -> desc;
+ break;
+ }
+ }
+ if (desc == NULL)
+ {
+ desc = "Unrecognized signal or trap use";
+ }
+ return (desc);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ syscallname - translate a system call number into a system call name
+
+SYNOPSIS
+
+ char *syscallname (int syscallnum)
+
+DESCRIPTION
+
+ Given a system call number, translate it into the printable name
+ of a system call, or into "syscall <num>" if it is an unknown
+ number.
+ */
+
+static char *
+syscallname (syscallnum)
+ int syscallnum;
+{
+ static char locbuf[32];
+ char *rtnval;
+
+ if (syscallnum >= 0 && syscallnum < MAX_SYSCALLS)
+ {
+ rtnval = syscall_table[syscallnum];
+ }
+ else
+ {
+ (void) sprintf (locbuf, "syscall %u", syscallnum);
+ rtnval = locbuf;
+ }
+ return (rtnval);
+}
+
+/*
+
+LOCAL FUNCTION
+
+ init_syscall_table - initialize syscall translation table
+
+SYNOPSIS
+
+ void init_syscall_table (void)
+
+DESCRIPTION
+
+ Dynamically initialize the translation table to convert system
+ call numbers into printable system call names. Done once per
+ gdb run, on initialization.
+
+NOTES
+
+ This is awfully ugly, but preprocessor tricks to make it prettier
+ tend to be nonportable.
+ */
+
+static void
+init_syscall_table ()
+{
+ int syscallnum;
+
+#if defined (SYS_exit)
+ syscall_table[SYS_exit] = "exit";
+#endif
+#if defined (SYS_fork)
+ syscall_table[SYS_fork] = "fork";
+#endif
+#if defined (SYS_read)
+ syscall_table[SYS_read] = "read";
+#endif
+#if defined (SYS_write)
+ syscall_table[SYS_write] = "write";
+#endif
+#if defined (SYS_open)
+ syscall_table[SYS_open] = "open";
+#endif
+#if defined (SYS_close)
+ syscall_table[SYS_close] = "close";
+#endif
+#if defined (SYS_wait)
+ syscall_table[SYS_wait] = "wait";
+#endif
+#if defined (SYS_creat)
+ syscall_table[SYS_creat] = "creat";
+#endif
+#if defined (SYS_link)
+ syscall_table[SYS_link] = "link";
+#endif
+#if defined (SYS_unlink)
+ syscall_table[SYS_unlink] = "unlink";
+#endif
+#if defined (SYS_exec)
+ syscall_table[SYS_exec] = "exec";
+#endif
+#if defined (SYS_execv)
+ syscall_table[SYS_execv] = "execv";
+#endif
+#if defined (SYS_execve)
+ syscall_table[SYS_execve] = "execve";
+#endif
+#if defined (SYS_chdir)
+ syscall_table[SYS_chdir] = "chdir";
+#endif
+#if defined (SYS_time)
+ syscall_table[SYS_time] = "time";
+#endif
+#if defined (SYS_mknod)
+ syscall_table[SYS_mknod] = "mknod";
+#endif
+#if defined (SYS_chmod)
+ syscall_table[SYS_chmod] = "chmod";
+#endif
+#if defined (SYS_chown)
+ syscall_table[SYS_chown] = "chown";
+#endif
+#if defined (SYS_brk)
+ syscall_table[SYS_brk] = "brk";
+#endif
+#if defined (SYS_stat)
+ syscall_table[SYS_stat] = "stat";
+#endif
+#if defined (SYS_lseek)
+ syscall_table[SYS_lseek] = "lseek";
+#endif
+#if defined (SYS_getpid)
+ syscall_table[SYS_getpid] = "getpid";
+#endif
+#if defined (SYS_mount)
+ syscall_table[SYS_mount] = "mount";
+#endif
+#if defined (SYS_umount)
+ syscall_table[SYS_umount] = "umount";
+#endif
+#if defined (SYS_setuid)
+ syscall_table[SYS_setuid] = "setuid";
+#endif
+#if defined (SYS_getuid)
+ syscall_table[SYS_getuid] = "getuid";
+#endif
+#if defined (SYS_stime)
+ syscall_table[SYS_stime] = "stime";
+#endif
+#if defined (SYS_ptrace)
+ syscall_table[SYS_ptrace] = "ptrace";
+#endif
+#if defined (SYS_alarm)
+ syscall_table[SYS_alarm] = "alarm";
+#endif
+#if defined (SYS_fstat)
+ syscall_table[SYS_fstat] = "fstat";
+#endif
+#if defined (SYS_pause)
+ syscall_table[SYS_pause] = "pause";
+#endif
+#if defined (SYS_utime)
+ syscall_table[SYS_utime] = "utime";
+#endif
+#if defined (SYS_stty)
+ syscall_table[SYS_stty] = "stty";
+#endif
+#if defined (SYS_gtty)
+ syscall_table[SYS_gtty] = "gtty";
+#endif
+#if defined (SYS_access)
+ syscall_table[SYS_access] = "access";
+#endif
+#if defined (SYS_nice)
+ syscall_table[SYS_nice] = "nice";
+#endif
+#if defined (SYS_statfs)
+ syscall_table[SYS_statfs] = "statfs";
+#endif
+#if defined (SYS_sync)
+ syscall_table[SYS_sync] = "sync";
+#endif
+#if defined (SYS_kill)
+ syscall_table[SYS_kill] = "kill";
+#endif
+#if defined (SYS_fstatfs)
+ syscall_table[SYS_fstatfs] = "fstatfs";
+#endif
+#if defined (SYS_pgrpsys)
+ syscall_table[SYS_pgrpsys] = "pgrpsys";
+#endif
+#if defined (SYS_xenix)
+ syscall_table[SYS_xenix] = "xenix";
+#endif
+#if defined (SYS_dup)
+ syscall_table[SYS_dup] = "dup";
+#endif
+#if defined (SYS_pipe)
+ syscall_table[SYS_pipe] = "pipe";
+#endif
+#if defined (SYS_times)
+ syscall_table[SYS_times] = "times";
+#endif
+#if defined (SYS_profil)
+ syscall_table[SYS_profil] = "profil";
+#endif
+#if defined (SYS_plock)
+ syscall_table[SYS_plock] = "plock";
+#endif
+#if defined (SYS_setgid)
+ syscall_table[SYS_setgid] = "setgid";
+#endif
+#if defined (SYS_getgid)
+ syscall_table[SYS_getgid] = "getgid";
+#endif
+#if defined (SYS_signal)
+ syscall_table[SYS_signal] = "signal";
+#endif
+#if defined (SYS_msgsys)
+ syscall_table[SYS_msgsys] = "msgsys";
+#endif
+#if defined (SYS_sys3b)
+ syscall_table[SYS_sys3b] = "sys3b";
+#endif
+#if defined (SYS_acct)
+ syscall_table[SYS_acct] = "acct";
+#endif
+#if defined (SYS_shmsys)
+ syscall_table[SYS_shmsys] = "shmsys";
+#endif
+#if defined (SYS_semsys)
+ syscall_table[SYS_semsys] = "semsys";
+#endif
+#if defined (SYS_ioctl)
+ syscall_table[SYS_ioctl] = "ioctl";
+#endif
+#if defined (SYS_uadmin)
+ syscall_table[SYS_uadmin] = "uadmin";
+#endif
+#if defined (SYS_utssys)
+ syscall_table[SYS_utssys] = "utssys";
+#endif
+#if defined (SYS_fsync)
+ syscall_table[SYS_fsync] = "fsync";
+#endif
+#if defined (SYS_umask)
+ syscall_table[SYS_umask] = "umask";
+#endif
+#if defined (SYS_chroot)
+ syscall_table[SYS_chroot] = "chroot";
+#endif
+#if defined (SYS_fcntl)
+ syscall_table[SYS_fcntl] = "fcntl";
+#endif
+#if defined (SYS_ulimit)
+ syscall_table[SYS_ulimit] = "ulimit";
+#endif
+#if defined (SYS_rfsys)
+ syscall_table[SYS_rfsys] = "rfsys";
+#endif
+#if defined (SYS_rmdir)
+ syscall_table[SYS_rmdir] = "rmdir";
+#endif
+#if defined (SYS_mkdir)
+ syscall_table[SYS_mkdir] = "mkdir";
+#endif
+#if defined (SYS_getdents)
+ syscall_table[SYS_getdents] = "getdents";
+#endif
+#if defined (SYS_sysfs)
+ syscall_table[SYS_sysfs] = "sysfs";
+#endif
+#if defined (SYS_getmsg)
+ syscall_table[SYS_getmsg] = "getmsg";
+#endif
+#if defined (SYS_putmsg)
+ syscall_table[SYS_putmsg] = "putmsg";
+#endif
+#if defined (SYS_poll)
+ syscall_table[SYS_poll] = "poll";
+#endif
+#if defined (SYS_lstat)
+ syscall_table[SYS_lstat] = "lstat";
+#endif
+#if defined (SYS_symlink)
+ syscall_table[SYS_symlink] = "symlink";
+#endif
+#if defined (SYS_readlink)
+ syscall_table[SYS_readlink] = "readlink";
+#endif
+#if defined (SYS_setgroups)
+ syscall_table[SYS_setgroups] = "setgroups";
+#endif
+#if defined (SYS_getgroups)
+ syscall_table[SYS_getgroups] = "getgroups";
+#endif
+#if defined (SYS_fchmod)
+ syscall_table[SYS_fchmod] = "fchmod";
+#endif
+#if defined (SYS_fchown)
+ syscall_table[SYS_fchown] = "fchown";
+#endif
+#if defined (SYS_sigprocmask)
+ syscall_table[SYS_sigprocmask] = "sigprocmask";
+#endif
+#if defined (SYS_sigsuspend)
+ syscall_table[SYS_sigsuspend] = "sigsuspend";
+#endif
+#if defined (SYS_sigaltstack)
+ syscall_table[SYS_sigaltstack] = "sigaltstack";
+#endif
+#if defined (SYS_sigaction)
+ syscall_table[SYS_sigaction] = "sigaction";
+#endif
+#if defined (SYS_sigpending)
+ syscall_table[SYS_sigpending] = "sigpending";
+#endif
+#if defined (SYS_context)
+ syscall_table[SYS_context] = "context";
+#endif
+#if defined (SYS_evsys)
+ syscall_table[SYS_evsys] = "evsys";
+#endif
+#if defined (SYS_evtrapret)
+ syscall_table[SYS_evtrapret] = "evtrapret";
+#endif
+#if defined (SYS_statvfs)
+ syscall_table[SYS_statvfs] = "statvfs";
+#endif
+#if defined (SYS_fstatvfs)
+ syscall_table[SYS_fstatvfs] = "fstatvfs";
+#endif
+#if defined (SYS_nfssys)
+ syscall_table[SYS_nfssys] = "nfssys";
+#endif
+#if defined (SYS_waitsys)
+ syscall_table[SYS_waitsys] = "waitsys";
+#endif
+#if defined (SYS_sigsendsys)
+ syscall_table[SYS_sigsendsys] = "sigsendsys";
+#endif
+#if defined (SYS_hrtsys)
+ syscall_table[SYS_hrtsys] = "hrtsys";
+#endif
+#if defined (SYS_acancel)
+ syscall_table[SYS_acancel] = "acancel";
+#endif
+#if defined (SYS_async)
+ syscall_table[SYS_async] = "async";
+#endif
+#if defined (SYS_priocntlsys)
+ syscall_table[SYS_priocntlsys] = "priocntlsys";
+#endif
+#if defined (SYS_pathconf)
+ syscall_table[SYS_pathconf] = "pathconf";
+#endif
+#if defined (SYS_mincore)
+ syscall_table[SYS_mincore] = "mincore";
+#endif
+#if defined (SYS_mmap)
+ syscall_table[SYS_mmap] = "mmap";
+#endif
+#if defined (SYS_mprotect)
+ syscall_table[SYS_mprotect] = "mprotect";
+#endif
+#if defined (SYS_munmap)
+ syscall_table[SYS_munmap] = "munmap";
+#endif
+#if defined (SYS_fpathconf)
+ syscall_table[SYS_fpathconf] = "fpathconf";
+#endif
+#if defined (SYS_vfork)
+ syscall_table[SYS_vfork] = "vfork";
+#endif
+#if defined (SYS_fchdir)
+ syscall_table[SYS_fchdir] = "fchdir";
+#endif
+#if defined (SYS_readv)
+ syscall_table[SYS_readv] = "readv";
+#endif
+#if defined (SYS_writev)
+ syscall_table[SYS_writev] = "writev";
+#endif
+#if defined (SYS_xstat)
+ syscall_table[SYS_xstat] = "xstat";
+#endif
+#if defined (SYS_lxstat)
+ syscall_table[SYS_lxstat] = "lxstat";
+#endif
+#if defined (SYS_fxstat)
+ syscall_table[SYS_fxstat] = "fxstat";
+#endif
+#if defined (SYS_xmknod)
+ syscall_table[SYS_xmknod] = "xmknod";
+#endif
+#if defined (SYS_clocal)
+ syscall_table[SYS_clocal] = "clocal";
+#endif
+#if defined (SYS_setrlimit)
+ syscall_table[SYS_setrlimit] = "setrlimit";
+#endif
+#if defined (SYS_getrlimit)
+ syscall_table[SYS_getrlimit] = "getrlimit";
+#endif
+#if defined (SYS_lchown)
+ syscall_table[SYS_lchown] = "lchown";
+#endif
+#if defined (SYS_memcntl)
+ syscall_table[SYS_memcntl] = "memcntl";
+#endif
+#if defined (SYS_getpmsg)
+ syscall_table[SYS_getpmsg] = "getpmsg";
+#endif
+#if defined (SYS_putpmsg)
+ syscall_table[SYS_putpmsg] = "putpmsg";
+#endif
+#if defined (SYS_rename)
+ syscall_table[SYS_rename] = "rename";
+#endif
+#if defined (SYS_uname)
+ syscall_table[SYS_uname] = "uname";
+#endif
+#if defined (SYS_setegid)
+ syscall_table[SYS_setegid] = "setegid";
+#endif
+#if defined (SYS_sysconfig)
+ syscall_table[SYS_sysconfig] = "sysconfig";
+#endif
+#if defined (SYS_adjtime)
+ syscall_table[SYS_adjtime] = "adjtime";
+#endif
+#if defined (SYS_systeminfo)
+ syscall_table[SYS_systeminfo] = "systeminfo";
+#endif
+#if defined (SYS_seteuid)
+ syscall_table[SYS_seteuid] = "seteuid";
+#endif
+}
/*
@@ -397,6 +1628,7 @@ NOTES
If proc_init_failed ever gets called, control returns to the command
processing loop via the standard error handling code.
+
*/
void
@@ -409,18 +1641,15 @@ inferior_proc_init (pid)
}
else
{
- (void) memset (&pi.prrun, 0, sizeof (pi.prrun));
+ (void) memset ((char *) &pi.prrun, 0, sizeof (pi.prrun));
prfillset (&pi.prrun.pr_trace);
+ proc_signal_handling_change ();
prfillset (&pi.prrun.pr_fault);
prdelset (&pi.prrun.pr_fault, FLTPAGE);
if (ioctl (pi.fd, PIOCWSTOP, &pi.prstatus) < 0)
{
proc_init_failed ("PIOCWSTOP failed");
}
- else if (ioctl (pi.fd, PIOCSTRACE, &pi.prrun.pr_trace) < 0)
- {
- proc_init_failed ("PIOCSTRACE failed");
- }
else if (ioctl (pi.fd, PIOCSFAULT, &pi.prrun.pr_fault) < 0)
{
proc_init_failed ("PIOCSFAULT failed");
@@ -432,6 +1661,58 @@ inferior_proc_init (pid)
GLOBAL FUNCTION
+ proc_signal_handling_change
+
+SYNOPSIS
+
+ void proc_signal_handling_change (void);
+
+DESCRIPTION
+
+ When the user changes the state of gdb's signal handling via the
+ "handle" command, this function gets called to see if any change
+ in the /proc interface is required. It is also called internally
+ by other /proc interface functions to initialize the state of
+ the traced signal set.
+
+ One thing it does is that signals for which the state is "nostop",
+ "noprint", and "pass", have their trace bits reset in the pr_trace
+ field, so that they are no longer traced. This allows them to be
+ delivered directly to the inferior without the debugger ever being
+ involved.
+ */
+
+void
+proc_signal_handling_change ()
+{
+ int signo;
+
+ if (pi.valid)
+ {
+ for (signo = 0; signo < NSIG; signo++)
+ {
+ if (signal_stop_state (signo) == 0 &&
+ signal_print_state (signo) == 0 &&
+ signal_pass_state (signo) == 1)
+ {
+ prdelset (&pi.prrun.pr_trace, signo);
+ }
+ else
+ {
+ praddset (&pi.prrun.pr_trace, signo);
+ }
+ }
+ if (ioctl (pi.fd, PIOCSTRACE, &pi.prrun.pr_trace))
+ {
+ print_sys_errmsg ("PIOCSTRACE failed", errno);
+ }
+ }
+}
+
+/*
+
+GLOBAL FUNCTION
+
proc_set_exec_trap -- arrange for exec'd child to halt at startup
SYNOPSIS
@@ -453,6 +1734,10 @@ NOTE
We need to use all local variables since the child may be sharing
it's data space with the parent, if vfork was used rather than
fork.
+
+ Also note that we want to turn off the inherit-on-fork flag in
+ the child process so that any grand-children start with all
+ tracing flags cleared.
*/
void
@@ -471,12 +1756,11 @@ proc_set_exec_trap ()
}
premptyset (&exitset);
-/*
- * GW: Rationale...
- * Not all systems with /proc have all the exec* syscalls with the same
- * names. On the SGI, for example, there is no SYS_exec, but there
- * *is* a SYS_execv. So, we try to account for that.
- */
+ /* GW: Rationale...
+ Not all systems with /proc have all the exec* syscalls with the same
+ names. On the SGI, for example, there is no SYS_exec, but there
+ *is* a SYS_execv. So, we try to account for that. */
+
#ifdef SYS_exec
praddset (&exitset, SYS_exec);
#endif
@@ -493,6 +1777,21 @@ proc_set_exec_trap ()
fflush (stderr);
_exit (127);
}
+
+ /* 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) */
+ {
+ long pr_flags;
+ pr_flags = PR_FORK;
+ (void) ioctl (fd, PIOCRESET, &pr_flags);
+ }
+#endif
+#endif
}
/*
@@ -567,7 +1866,7 @@ DESCRIPTION
CORE_ADDR
proc_base_address (addr)
-CORE_ADDR addr;
+ CORE_ADDR addr;
{
int nmap;
struct prmap *prmaps;
@@ -597,7 +1896,7 @@ CORE_ADDR addr;
/*
-GLOBAL_FUNCTION
+LOCAL FUNCTION
proc_address_to_fd -- return open fd for file mapped to address
@@ -704,15 +2003,17 @@ attach (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.trace);
- (void) ioctl (pi.fd, PIOCGFAULT, &pi.fltset);
- (void) ioctl (pi.fd, PIOCGENTRY, &pi.entryset);
- (void) ioctl (pi.fd, PIOCGEXIT, &pi.exitset);
+ (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);
/* Set up trace and fault sets, as gdb expects them. */
(void) memset (&pi.prrun, 0, sizeof (pi.prrun));
prfillset (&pi.prrun.pr_trace);
+ proc_signal_handling_change ();
prfillset (&pi.prrun.pr_fault);
prdelset (&pi.prrun.pr_fault, FLTPAGE);
if (ioctl (pi.fd, PIOCSFAULT, &pi.prrun.pr_fault))
@@ -764,22 +2065,27 @@ detach (signal)
{
set_proc_siginfo (&pi, signal);
}
- if (ioctl (pi.fd, PIOCSEXIT, &pi.exitset) < 0)
+ if (ioctl (pi.fd, PIOCSEXIT, &pi.saved_exitset) < 0)
{
print_sys_errmsg (pi.pathname, errno);
printf ("PIOCSEXIT failed.\n");
}
- if (ioctl (pi.fd, PIOCSENTRY, &pi.entryset) < 0)
+ if (ioctl (pi.fd, PIOCSENTRY, &pi.saved_entryset) < 0)
{
print_sys_errmsg (pi.pathname, errno);
printf ("PIOCSENTRY failed.\n");
}
- if (ioctl (pi.fd, PIOCSTRACE, &pi.trace) < 0)
+ if (ioctl (pi.fd, PIOCSTRACE, &pi.saved_trace) < 0)
{
print_sys_errmsg (pi.pathname, errno);
printf ("PIOCSTRACE failed.\n");
}
- if (ioctl (pi.fd, PIOCSFAULT, &pi.fltset) < 0)
+ if (ioctl (pi.fd, PIOCSHOLD, &pi.saved_sighold) < 0)
+ {
+ print_sys_errmsg (pi.pathname, errno);
+ printf ("PIOSCHOLD failed.\n");
+ }
+ if (ioctl (pi.fd, PIOCSFAULT, &pi.saved_fltset) < 0)
{
print_sys_errmsg (pi.pathname, errno);
printf ("PIOCSFAULT failed.\n");
@@ -1012,8 +2318,8 @@ DESCRIPTION
static void
set_proc_siginfo (pip, signo)
- struct procinfo *pip;
- int signo;
+ struct procinfo *pip;
+ int signo;
{
struct siginfo newsiginfo;
struct siginfo *sip;
@@ -1050,7 +2356,7 @@ GLOBAL FUNCTION
SYNOPSIS
- void child_resume (int step, int signal)
+ void child_resume (int step, int signo)
DESCRIPTION
@@ -1068,16 +2374,16 @@ NOTE
*/
void
-child_resume (step, signal)
+child_resume (step, signo)
int step;
- int signal;
+ int signo;
{
errno = 0;
pi.prrun.pr_flags = PRSVADDR | PRSTRACE | PRSFAULT | PRCFAULT;
pi.prrun.pr_vaddr = (caddr_t) *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
- if (signal)
+ if (signo)
{
- set_proc_siginfo (&pi, signal);
+ set_proc_siginfo (&pi, signo);
}
else
{
@@ -1154,10 +2460,10 @@ NOTES
void
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
- char *core_reg_sect;
- unsigned core_reg_size;
- int which;
- unsigned int reg_addr; /* Unused in this version */
+ char *core_reg_sect;
+ unsigned core_reg_size;
+ int which;
+ unsigned int reg_addr; /* Unused in this version */
{
if (which == 0)
@@ -1296,12 +2602,8 @@ open_proc_file (pid, pip)
sprintf (pip -> pathname, PROC_NAME_FMT, pid);
if ((pip -> fd = open (pip -> pathname, O_RDWR)) >= 0)
{
- long pr_flags;
-
pip -> valid = 1;
pip -> pid = pid;
- pr_flags = PR_FORK;
- (void) ioctl (pip -> fd, PIOCRESET, &pr_flags);
}
return (pip -> valid);
}
@@ -1323,49 +2625,428 @@ mappingflags (flags)
}
static void
-proc_info_address_map (pip, verbose)
+info_proc_flags (pip, summary)
+ struct procinfo *pip;
+ int summary;
+{
+ struct trans *transp;
+
+ printf_filtered ("%-32s", "Process status flags:");
+ if (!summary)
+ {
+ printf_filtered ("\n\n");
+ }
+ for (transp = pr_flag_table; transp -> name != NULL; transp++)
+ {
+ if (pip -> prstatus.pr_flags & transp -> value)
+ {
+ if (summary)
+ {
+ printf_filtered ("%s ", transp -> name);
+ }
+ else
+ {
+ printf_filtered ("\t%-16s %s.\n", transp -> name, transp -> desc);
+ }
+ }
+ }
+ printf_filtered ("\n");
+}
+
+static void
+info_proc_stop (pip, summary)
+ struct procinfo *pip;
+ int summary;
+{
+ struct trans *transp;
+ int why;
+ int what;
+
+ why = pip -> prstatus.pr_why;
+ what = pip -> prstatus.pr_what;
+
+ if (pip -> prstatus.pr_flags & PR_STOPPED)
+ {
+ printf_filtered ("%-32s", "Reason for stopping:");
+ if (!summary)
+ {
+ printf_filtered ("\n\n");
+ }
+ for (transp = pr_why_table; transp -> name != NULL; transp++)
+ {
+ if (why == transp -> value)
+ {
+ if (summary)
+ {
+ printf_filtered ("%s ", transp -> name);
+ }
+ else
+ {
+ printf_filtered ("\t%-16s %s.\n",
+ transp -> name, transp -> desc);
+ }
+ break;
+ }
+ }
+
+ /* Use the pr_why field to determine what the pr_what field means, and
+ print more information. */
+
+ switch (why)
+ {
+ case PR_REQUESTED:
+ /* pr_what is unused for this case */
+ break;
+ case PR_JOBCONTROL:
+ case PR_SIGNALLED:
+ if (summary)
+ {
+ printf_filtered ("%s ", signalname (what));
+ }
+ else
+ {
+ printf_filtered ("\t%-16s %s.\n", signalname (what),
+ sys_siglist[what]);
+ }
+ break;
+ case PR_SYSENTRY:
+ if (summary)
+ {
+ printf_filtered ("%s ", syscallname (what));
+ }
+ else
+ {
+ printf_filtered ("\t%-16s %s.\n", syscallname (what),
+ "Entered this system call");
+ }
+ break;
+ case PR_SYSEXIT:
+ if (summary)
+ {
+ printf_filtered ("%s ", syscallname (what));
+ }
+ else
+ {
+ printf_filtered ("\t%-16s %s.\n", syscallname (what),
+ "Returned from this system call");
+ }
+ break;
+ case PR_FAULTED:
+ if (summary)
+ {
+ printf_filtered ("%s ",
+ lookupname (faults_table, what, "fault"));
+ }
+ else
+ {
+ printf_filtered ("\t%-16s %s.\n",
+ lookupname (faults_table, what, "fault"),
+ lookupdesc (faults_table, what));
+ }
+ break;
+ }
+ printf_filtered ("\n");
+ }
+}
+
+static void
+info_proc_siginfo (pip, summary)
+ struct procinfo *pip;
+ int summary;
+{
+ struct siginfo *sip;
+
+ if ((pip -> prstatus.pr_flags & PR_STOPPED) &&
+ (pip -> prstatus.pr_why == PR_SIGNALLED ||
+ pip -> prstatus.pr_why == PR_FAULTED))
+ {
+ printf_filtered ("%-32s", "Additional signal/fault info:");
+ sip = &pip -> prstatus.pr_info;
+ if (summary)
+ {
+ printf_filtered ("%s ", signalname (sip -> si_signo));
+ if (sip -> si_errno > 0)
+ {
+ printf_filtered ("%s ", lookupname (errno_table,
+ sip -> si_errno, "errno"));
+ }
+ if (sip -> si_code <= 0)
+ {
+ printf_filtered ("sent by pid %d, uid %d ", sip -> si_pid,
+ sip -> si_uid);
+ }
+ else
+ {
+ printf_filtered ("%s ", sigcodename (sip));
+ if ((sip -> si_signo == SIGILL) ||
+ (sip -> si_signo == SIGFPE) ||
+ (sip -> si_signo == SIGSEGV) ||
+ (sip -> si_signo == SIGBUS))
+ {
+ printf_filtered ("addr=%#x ", sip -> si_addr);
+ }
+ else if ((sip -> si_signo == SIGCHLD))
+ {
+ printf_filtered ("child pid %u, status %u ",
+ sip -> si_pid,
+ sip -> si_status);
+ }
+ else if ((sip -> si_signo == SIGPOLL))
+ {
+ printf_filtered ("band %u ", sip -> si_band);
+ }
+ }
+ }
+ else
+ {
+ printf_filtered ("\n\n");
+ printf_filtered ("\t%-16s %s.\n", signalname (sip -> si_signo),
+ sys_siglist[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));
+ }
+ if (sip -> si_code <= 0)
+ {
+ printf_filtered ("\t%-16u %s\n", sip -> si_pid,
+ "PID of process sending signal");
+ printf_filtered ("\t%-16u %s\n", sip -> si_uid,
+ "UID of process sending signal");
+ }
+ else
+ {
+ printf_filtered ("\t%-16s %s.\n", sigcodename (sip),
+ sigcodedesc (sip));
+ if ((sip -> si_signo == SIGILL) ||
+ (sip -> si_signo == SIGFPE))
+ {
+ printf_filtered ("\t%-16#x %s.\n", sip -> si_addr,
+ "Address of faulting instruction");
+ }
+ else if ((sip -> si_signo == SIGSEGV) ||
+ (sip -> si_signo == SIGBUS))
+ {
+ printf_filtered ("\t%-16#x %s.\n", sip -> si_addr,
+ "Address of faulting memory reference");
+ }
+ else if ((sip -> si_signo == SIGCHLD))
+ {
+ printf_filtered ("\t%-16u %s.\n", sip -> si_pid,
+ "Child process ID");
+ printf_filtered ("\t%-16u %s.\n", sip -> si_status,
+ "Child process exit value or signal");
+ }
+ else if ((sip -> si_signo == SIGPOLL))
+ {
+ printf_filtered ("\t%-16u %s.\n", sip -> si_band,
+ "Band event for POLL_{IN,OUT,MSG}");
+ }
+ }
+ }
+ printf_filtered ("\n");
+ }
+}
+
+static void
+info_proc_syscalls (pip, summary)
+ struct procinfo *pip;
+ int summary;
+{
+ int syscallnum;
+
+ if (!summary)
+ {
+
+#if 0 /* FIXME: Needs to use gdb-wide configured info about system calls. */
+ if (pip -> prstatus.pr_flags & PR_ASLEEP)
+ {
+ int syscallnum = pip -> prstatus.pr_reg[R_D0];
+ if (summary)
+ {
+ printf_filtered ("%-32s", "Sleeping in system call:");
+ printf_filtered ("%s", syscallname (syscallnum));
+ }
+ else
+ {
+ printf_filtered ("Sleeping in system call '%s'.\n",
+ syscallname (syscallnum));
+ }
+ }
+#endif
+
+ if (ioctl (pip -> fd, PIOCGENTRY, &pip -> entryset) < 0)
+ {
+ print_sys_errmsg (pip -> pathname, errno);
+ error ("PIOCGENTRY failed");
+ }
+
+ if (ioctl (pip -> fd, PIOCGEXIT, &pip -> exitset) < 0)
+ {
+ print_sys_errmsg (pip -> pathname, errno);
+ error ("PIOCGEXIT failed");
+ }
+
+ printf_filtered ("System call tracing information:\n\n");
+
+ printf_filtered ("\t%-12s %-8s %-8s\n",
+ "System call",
+ "Entry",
+ "Exit");
+ for (syscallnum = 0; syscallnum < MAX_SYSCALLS; syscallnum++)
+ {
+ QUIT;
+ if (syscall_table[syscallnum] != NULL)
+ {
+ printf_filtered ("\t%-12s ", syscall_table[syscallnum]);
+ printf_filtered ("%-8s ",
+ prismember (&pip -> entryset, syscallnum)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip -> exitset, syscallnum)
+ ? "on" : "off");
+ printf_filtered ("\n");
+ }
+ }
+ printf_filtered ("\n");
+ }
+}
+
+static char *
+signalname (signo)
+ int signo;
+{
+ char *abbrev;
+ static char locbuf[32];
+
+ abbrev = sig_abbrev (signo);
+ if (abbrev == NULL)
+ {
+ sprintf (locbuf, "signal %d", signo);
+ }
+ else
+ {
+ sprintf (locbuf, "SIG%s (%d)", abbrev, signo);
+ }
+ return (locbuf);
+}
+
+static void
+info_proc_signals (pip, summary)
+ struct procinfo *pip;
+ int summary;
+{
+ int signo;
+
+ if (!summary)
+ {
+ if (ioctl (pip -> fd, PIOCGTRACE, &pip -> trace) < 0)
+ {
+ print_sys_errmsg (pip -> pathname, errno);
+ error ("PIOCGTRACE failed");
+ }
+
+ printf_filtered ("Disposition of signals:\n\n");
+ printf_filtered ("\t%-15s %-8s %-8s %-8s %s\n\n",
+ "Signal", "Trace", "Hold", "Pending", "Description");
+ for (signo = 0; signo < NSIG; signo++)
+ {
+ QUIT;
+ printf_filtered ("\t%-15s ", signalname (signo));
+ printf_filtered ("%-8s ",
+ prismember (&pip -> trace, signo)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip -> prstatus.pr_sighold, signo)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip -> prstatus.pr_sigpend, signo)
+ ? "yes" : "no");
+ printf_filtered (" %s\n", sys_siglist[signo]);
+ }
+ printf_filtered ("\n");
+ }
+}
+
+static void
+info_proc_faults (pip, summary)
+ struct procinfo *pip;
+ int summary;
+{
+ struct trans *transp;
+
+ if (!summary)
+ {
+ if (ioctl (pip -> fd, PIOCGFAULT, &pip -> fltset) < 0)
+ {
+ print_sys_errmsg (pip -> pathname, errno);
+ error ("PIOCGFAULT failed");
+ }
+
+ printf_filtered ("Current traced hardware fault set:\n\n");
+ printf_filtered ("\t%-12s %-8s\n", "Fault", "Trace");
+
+ for (transp = faults_table; transp -> name != NULL; transp++)
+ {
+ QUIT;
+ printf_filtered ("\t%-12s ", transp -> name);
+ printf_filtered ("%-8s", prismember (&pip -> fltset, transp -> value)
+ ? "on" : "off");
+ printf_filtered ("\n");
+ }
+ printf_filtered ("\n");
+ }
+}
+
+static void
+info_proc_mappings (pip, summary)
struct procinfo *pip;
- int verbose;
+ int summary;
{
int nmap;
struct prmap *prmaps;
struct prmap *prmap;
- printf_filtered ("Mapped address spaces:\n\n");
- printf_filtered ("\t%10s %10s %10s %10s %6s\n",
- "Start Addr",
- " End Addr",
- " Size",
- " Offset",
- "Flags");
- if (ioctl (pip -> fd, PIOCNMAP, &nmap) == 0)
+ if (!summary)
{
- prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
- if (ioctl (pip -> fd, PIOCMAP, prmaps) == 0)
+ printf_filtered ("Mapped address spaces:\n\n");
+ printf_filtered ("\t%10s %10s %10s %10s %6s\n",
+ "Start Addr",
+ " End Addr",
+ " Size",
+ " Offset",
+ "Flags");
+ if (ioctl (pip -> fd, PIOCNMAP, &nmap) == 0)
{
- for (prmap = prmaps; prmap -> pr_size; ++prmap)
+ prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
+ if (ioctl (pip -> fd, PIOCMAP, prmaps) == 0)
{
- printf_filtered ("\t%#10x %#10x %#10x %#10x %6s\n",
- prmap -> pr_vaddr,
- prmap -> pr_vaddr + prmap -> pr_size - 1,
- prmap -> pr_size,
- prmap -> pr_off,
- mappingflags (prmap -> pr_mflags));
+ for (prmap = prmaps; prmap -> pr_size; ++prmap)
+ {
+ printf_filtered ("\t%#10x %#10x %#10x %#10x %6s\n",
+ prmap -> pr_vaddr,
+ prmap -> pr_vaddr + prmap -> pr_size - 1,
+ prmap -> pr_size,
+ prmap -> pr_off,
+ mappingflags (prmap -> pr_mflags));
+ }
}
}
+ printf_filtered ("\n");
}
- printf_filtered ("\n\n");
}
/*
LOCAL FUNCTION
- proc_info -- implement the "info proc" command
+ info_proc -- implement the "info proc" command
SYNOPSIS
- void proc_info (char *args, int from_tty)
+ void info_proc (char *args, int from_tty)
DESCRIPTION
@@ -1374,24 +3055,39 @@ DESCRIPTION
Examples of the use of "info proc" are:
- info proc Print short info about current inferior.
- info proc verbose Print verbose info about current inferior.
- info proc 123 Print short info about process pid 123.
- info proc 123 verbose Print verbose info about process pid 123.
+ info proc (prints summary info for current inferior)
+ info proc 123 (prints summary info for process with pid 123)
+ info proc mappings (prints address mappings)
+ info proc times (prints process/children times)
+ info proc id (prints pid, ppid, gid, sid, etc)
+ info proc status (prints general process state info)
+ info proc signals (prints info about signal handling)
+ info proc all (prints all info)
*/
static void
-proc_info (args, from_tty)
+info_proc (args, from_tty)
char *args;
int from_tty;
{
- int verbose = 0;
int pid;
struct procinfo pii;
struct procinfo *pip;
struct cleanup *old_chain;
char *nexttok;
+ char **argv;
+ int argsize;
+ int summary = 1;
+ int flags = 0;
+ int syscalls = 0;
+ int signals = 0;
+ int faults = 0;
+ int mappings = 0;
+ int times = 0;
+ int id = 0;
+ int status = 0;
+ int all = 0;
old_chain = make_cleanup (null_cleanup, 0);
@@ -1399,20 +3095,63 @@ proc_info (args, from_tty)
pip = &pi;
- /* Parse the args string, looking for "verbose" (or any abbrev) and
- for a specific pid. If a specific pid is found, the process
- file is opened. */
-
if (args != NULL)
{
- while ((nexttok = strtok (args, " \t")) != NULL)
+ if ((argv = buildargv (args)) == NULL)
+ {
+ nomem (0);
+ }
+ make_cleanup (freeargv, (char *) argv);
+
+ while (*argv != NULL)
{
- args = NULL;
- if (strncmp (nexttok, "verbose", strlen (nexttok)) == 0)
+ argsize = strlen (*argv);
+ if (argsize >= 1 && strncmp (*argv, "all", argsize) == 0)
+ {
+ summary = 0;
+ all = 1;
+ }
+ else if (argsize >= 2 && strncmp (*argv, "faults", argsize) == 0)
+ {
+ summary = 0;
+ faults = 1;
+ }
+ else if (argsize >= 2 && strncmp (*argv, "flags", argsize) == 0)
+ {
+ summary = 0;
+ flags = 1;
+ }
+ else if (argsize >= 1 && strncmp (*argv, "id", argsize) == 0)
+ {
+ summary = 0;
+ id = 1;
+ }
+ else if (argsize >= 1 && strncmp (*argv, "mappings", argsize) == 0)
+ {
+ summary = 0;
+ mappings = 1;
+ }
+ else if (argsize >= 2 && strncmp (*argv, "signals", argsize) == 0)
+ {
+ summary = 0;
+ signals = 1;
+ }
+ else if (argsize >= 2 && strncmp (*argv, "status", argsize) == 0)
+ {
+ summary = 0;
+ status = 1;
+ }
+ else if (argsize >= 2 && strncmp (*argv, "syscalls", argsize) == 0)
{
- verbose++;
+ summary = 0;
+ syscalls = 1;
}
- else if ((pii.pid = atoi (nexttok)) > 0)
+ else if (argsize >= 1 && strncmp (*argv, "times", argsize) == 0)
+ {
+ summary = 0;
+ times = 1;
+ }
+ else if ((pii.pid = atoi (*argv)) > 0)
{
pid = pii.pid;
pip = &pii;
@@ -1424,6 +3163,11 @@ proc_info (args, from_tty)
}
make_cleanup (close_proc_file, pip);
}
+ else if (**argv != '\000')
+ {
+ error ("Unrecognized or ambiguous keyword `%s'.", *argv);
+ }
+ argv++;
}
}
@@ -1440,24 +3184,39 @@ proc_info (args, from_tty)
error ("PIOCSTATUS failed");
}
- printf_filtered ("\nStatus information for %s:\n\n", pip -> pathname);
- proc_info_address_map (pip, verbose);
-#if 0
- proc_info_flags (pip, verbose);
- proc_info_why (pip, verbose);
- proc_info_what (pip, verbose);
- proc_info_info (pip, verbose);
- proc_info_cursig (pip, verbose);
- proc_info_sigpend (pip, verbose);
- proc_info_sighold (pip, verbose);
- proc_info_altstack (pip, verbose);
- proc_info_action (pip, verbose);
- proc_info_id (pip, verbose);
- proc_info_times (pip, verbose);
- proc_info_clname (pip,verbose);
- proc_info_instr (pip, verbose);
- proc_info_reg (pip, verbose);
-#endif
+ /* Print verbose information of the requested type(s), or just a summary
+ of the information for all types. */
+
+ printf_filtered ("\nInformation for %s:\n\n", pip -> pathname);
+ if (summary || all || flags)
+ {
+ info_proc_flags (pip, summary);
+ }
+ if (summary || all)
+ {
+ info_proc_stop (pip, summary);
+ }
+ if (summary || all || signals || faults)
+ {
+ info_proc_siginfo (pip, summary);
+ }
+ if (summary || all || syscalls)
+ {
+ info_proc_syscalls (pip, summary);
+ }
+ if (summary || all || mappings)
+ {
+ info_proc_mappings (pip, summary);
+ }
+ if (summary || all || signals)
+ {
+ info_proc_signals (pip, summary);
+ }
+ if (summary || all || faults)
+ {
+ info_proc_faults (pip, summary);
+ }
+ printf_filtered ("\n");
/* All done, deal with closing any temporary process info structure,
freeing temporary memory , etc. */
@@ -1483,13 +3242,18 @@ DESCRIPTION
*/
static char *proc_desc =
-"Show current process status information using /proc entry.\n\
-With no arguments, prints short form. With 'verbose' prints long form.";
+"Show process status information using /proc entry.\n\
+Specify process id or use current inferior by default.\n\
+Specify keywords for detailed information; default is summary.\n\
+Keywords are: `all', `faults', `flags', `id', `mappings', `signals',\n\
+`status', `syscalls', and `times'.\n\
+Unambiguous abbreviations may be used.";
void
_initialize_proc_fs ()
{
- add_info ("proc", proc_info, proc_desc);
+ add_info ("proc", info_proc, proc_desc);
+ init_syscall_table ();
}
#endif /* USE_PROC_FS */
diff --git a/gdb/xm-irix4.h b/gdb/xm-irix4.h
index e25a144..e25b6be 100644
--- a/gdb/xm-irix4.h
+++ b/gdb/xm-irix4.h
@@ -42,9 +42,27 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
#define USE_PROC_FS
#define PROC_NAME_FMT "/debug/%d"
+
+/* If we are using SVR4 /proc instead of ptrace, use CREATE_INFERIOR_HOOK
+ to do internal /proc initialization. */
+#ifdef USE_PROC_FS
#define CREATE_INFERIOR_HOOK(pid) inferior_proc_init(pid)
+#endif
/* Irix defines psignal() in signal.h, which gets gcc rather angry at us
* because their definition is markedly different.
*/
#define PSIGNAL_IN_SIGNAL_H
+
+/* If gdb's signal handling changes (due to a "handle" command), then
+ this macro expands to an action to perform to notify other parts of
+ gdb that might care, that signal handling has changed. For hosts using
+ the /proc interface, gdb has more control over which signals cause the
+ inferior to stop and which do not. In some cases, it is desirable to
+ have signals delivered directly to the inferior without involving the
+ debugger at all. */
+#ifdef USE_PROC_FS
+#define NOTICE_SIGNAL_HANDLING_CHANGE proc_signal_handling_change()
+#endif
+
+#define BROKEN_SIGINFO_H /* <sys/siginfo.h> si_pid & si_uid are bogus */
diff --git a/gdb/xm-sysv4.h b/gdb/xm-sysv4.h
index 35c831d..c51c58d 100644
--- a/gdb/xm-sysv4.h
+++ b/gdb/xm-sysv4.h
@@ -65,3 +65,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Use setpgid(0,0) to run inferior in a separate process group */
#define NEED_POSIX_SETPGID
+
+/* If gdb's signal handling changes (due to a "handle" command), then
+ this macro expands to an action to perform to notify other parts of
+ gdb that might care, that signal handling has changed. For hosts using
+ the /proc interface, gdb has more control over which signals cause the
+ inferior to stop and which do not. In some cases, it is desirable to
+ have signals delivered directly to the inferior without involving the
+ debugger at all. */
+
+#ifdef USE_PROC_FS
+#define NOTICE_SIGNAL_HANDLING_CHANGE proc_signal_handling_change()
+#endif