Make the /proc support a target-struct in its own right.
* inferior.h (proc_wait, inferior_proc_init, proc_set_exec_trap): No longer global functions. (fork_inferior): New global function from fork-child.c. * inftarg.c (child_wait): Remove USE_PROC_FS conditional. (ptrace_me, ptrace_him): New stub functions for fork_inferior(). (child_create_inferior): Moved to fork-child.c as fork_inferior. (child_create_inferior): New tiny function that calls fork_inferior. * fork-child.c: New file, containing fork_inferior, which is built from slight mods to inftarg.c's child_create_inferior. * procfs.c (procfs_ops): Add target vector. (attach): Rename as static do_attach. (procfs_create_inferior): New tiny function that calls fork_inferior. (child_xfer_memory): Rename to static procfs_xfer_memory. (store_inferior_registers): Rename to static procfs_store_registers. (inferior_proc_init): Rename to static procfs_init_inferior. (procfs_attach, procfs_detach, procfs_prepare_to_store, procfs_files_info, procfs_open, procfs_mourn_inferior, procfs_can_run): Slightly mangled copies of the corresponding child_XXX routines from inftarg.c. (proc_wait): Renamed to static procfs_wait. (child_resume): Rename to static procfs_resume. (fetch_inferior_registers): Rename to static procfs_fetch_registers. (initialize_proc_fs): Rename to initialize_procfs. Set up procfs_ops, too. * xm-irix4.h, xm-sysv4.h (CREATE_INFERIOR_HOOK): No longer needed.
This commit is contained in:
parent
b38f304c4f
commit
3fbdd5366e
|
@ -1,11 +1,47 @@
|
||||||
Sat Sep 26 00:25:15 1992 John Gilmore (gnu@cygnus.com)
|
Sat Sep 26 00:25:15 1992 John Gilmore (gnu@cygnus.com)
|
||||||
|
|
||||||
|
Make the /proc support a target-struct in its own right.
|
||||||
|
|
||||||
* Makefile.in: Remove inftarg.[co], since it is now included via
|
* Makefile.in: Remove inftarg.[co], since it is now included via
|
||||||
config/*.mh files.
|
config/*.mh files.
|
||||||
* config/*.mh: Add inftarg.o and fork-child.o to all *.mh that
|
* config/*.mh: Add inftarg.o and fork-child.o to all *.mh that
|
||||||
reference infptrace.o. Add fork-child.o to all *.mh that
|
reference infptrace.o. Add fork-child.o to all *.mh that
|
||||||
reference procfs.o.
|
reference procfs.o.
|
||||||
|
|
||||||
|
* inferior.h (proc_wait, inferior_proc_init, proc_set_exec_trap):
|
||||||
|
No longer global functions.
|
||||||
|
(fork_inferior): New global function from fork-child.c.
|
||||||
|
* inftarg.c (child_wait): Remove USE_PROC_FS conditional.
|
||||||
|
(ptrace_me, ptrace_him): New stub functions for fork_inferior().
|
||||||
|
(child_create_inferior): Moved to fork-child.c as fork_inferior.
|
||||||
|
(child_create_inferior): New tiny function that calls fork_inferior.
|
||||||
|
* fork-child.c: New file, containing fork_inferior, which is
|
||||||
|
built from slight mods to inftarg.c's child_create_inferior.
|
||||||
|
|
||||||
|
* procfs.c (procfs_ops): Add target vector.
|
||||||
|
(attach): Rename as static do_attach.
|
||||||
|
(procfs_create_inferior): New tiny function that calls fork_inferior.
|
||||||
|
(child_xfer_memory): Rename to static procfs_xfer_memory.
|
||||||
|
(store_inferior_registers): Rename to static procfs_store_registers.
|
||||||
|
(inferior_proc_init): Rename to static procfs_init_inferior.
|
||||||
|
(procfs_attach, procfs_detach, procfs_prepare_to_store,
|
||||||
|
procfs_files_info, procfs_open, procfs_mourn_inferior,
|
||||||
|
procfs_can_run): Slightly mangled copies of the corresponding
|
||||||
|
child_XXX routines from inftarg.c.
|
||||||
|
(proc_wait): Renamed to static procfs_wait.
|
||||||
|
(child_resume): Rename to static procfs_resume.
|
||||||
|
(fetch_inferior_registers): Rename to static procfs_fetch_registers.
|
||||||
|
(initialize_proc_fs): Rename to initialize_procfs. Set up
|
||||||
|
procfs_ops, too.
|
||||||
|
|
||||||
|
* putenv.c: index -> strchr.
|
||||||
|
* regex.c: Always rename bcopy to memcpy, etc.
|
||||||
|
FIXME: Eventually do the renames rather than use #define's.
|
||||||
|
* sparc-tdep.c (deferred_stores): Moved from sparc-xdep.c.
|
||||||
|
Fix bcopy->memcpy.
|
||||||
|
* sparc-xdep.c: Move deferred_stores to target dependent.
|
||||||
|
* xm-irix4.h, xm-sysv4.h (CREATE_INFERIOR_HOOK): No longer needed.
|
||||||
|
|
||||||
Fri Sep 25 21:59:27 1992 John Gilmore (gnu@cygnus.com)
|
Fri Sep 25 21:59:27 1992 John Gilmore (gnu@cygnus.com)
|
||||||
|
|
||||||
Split non-target-dependent code out of target_attach routines.
|
Split non-target-dependent code out of target_attach routines.
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
/* Fork a Unix child process, and set up to debug it, for GDB.
|
||||||
|
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||||
|
Contributed by Cygnus Support.
|
||||||
|
|
||||||
|
This file is part of GDB.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "frame.h" /* required by inferior.h */
|
||||||
|
#include "inferior.h"
|
||||||
|
#include "target.h"
|
||||||
|
#include "wait.h"
|
||||||
|
#include "gdbcore.h"
|
||||||
|
#include "terminal.h" /* For #ifdef TIOCGPGRP and new_tty */
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#ifdef SET_STACK_LIMIT_HUGE
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
|
||||||
|
extern int original_stack_limit;
|
||||||
|
#endif /* SET_STACK_LIMIT_HUGE */
|
||||||
|
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
|
/* Start an inferior Unix child process and sets inferior_pid to its pid.
|
||||||
|
EXEC_FILE is the file to run.
|
||||||
|
ALLARGS is a string containing the arguments to the program.
|
||||||
|
ENV is the environment vector to pass. Errors reported with error(). */
|
||||||
|
|
||||||
|
#ifndef SHELL_FILE
|
||||||
|
#define SHELL_FILE "/bin/sh"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
|
||||||
|
char *exec_file;
|
||||||
|
char *allargs;
|
||||||
|
char **env;
|
||||||
|
void (*traceme_fun) PARAMS ((void));
|
||||||
|
void (*init_trace_fun) PARAMS ((int));
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
char *shell_command;
|
||||||
|
char *shell_file;
|
||||||
|
static char default_shell_file[] = SHELL_FILE;
|
||||||
|
int len;
|
||||||
|
int pending_execs;
|
||||||
|
/* Set debug_fork then attach to the child while it sleeps, to debug. */
|
||||||
|
static int debug_fork = 0;
|
||||||
|
/* This is set to the result of setpgrp, which if vforked, will be visible
|
||||||
|
to you in the parent process. It's only used by humans for debugging. */
|
||||||
|
static int debug_setpgrp = 657473;
|
||||||
|
char **save_our_env;
|
||||||
|
|
||||||
|
/* If no exec file handed to us, get it from the exec-file command -- with
|
||||||
|
a good, common error message if none is specified. */
|
||||||
|
if (exec_file == 0)
|
||||||
|
exec_file = get_exec_file(1);
|
||||||
|
|
||||||
|
/* The user might want tilde-expansion, and in general probably wants
|
||||||
|
the program to behave the same way as if run from
|
||||||
|
his/her favorite shell. So we let the shell run it for us.
|
||||||
|
FIXME, this should probably search the local environment (as
|
||||||
|
modified by the setenv command), not the env gdb inherited. */
|
||||||
|
shell_file = getenv ("SHELL");
|
||||||
|
if (shell_file == NULL)
|
||||||
|
shell_file = default_shell_file;
|
||||||
|
|
||||||
|
len = 5 + strlen (exec_file) + 1 + strlen (allargs) + 1 + /*slop*/ 10;
|
||||||
|
/* If desired, concat something onto the front of ALLARGS.
|
||||||
|
SHELL_COMMAND is the result. */
|
||||||
|
#ifdef SHELL_COMMAND_CONCAT
|
||||||
|
shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + len);
|
||||||
|
strcpy (shell_command, SHELL_COMMAND_CONCAT);
|
||||||
|
#else
|
||||||
|
shell_command = (char *) alloca (len);
|
||||||
|
shell_command[0] = '\0';
|
||||||
|
#endif
|
||||||
|
strcat (shell_command, "exec ");
|
||||||
|
strcat (shell_command, exec_file);
|
||||||
|
strcat (shell_command, " ");
|
||||||
|
strcat (shell_command, allargs);
|
||||||
|
|
||||||
|
/* exec is said to fail if the executable is open. */
|
||||||
|
close_exec_file ();
|
||||||
|
|
||||||
|
/* Retain a copy of our environment variables, since the child will
|
||||||
|
replace the value of environ and if we're vforked, we have to
|
||||||
|
restore it. */
|
||||||
|
save_our_env = environ;
|
||||||
|
|
||||||
|
/* Tell the terminal handling subsystem what tty we plan to run on;
|
||||||
|
it will just record the information for later. */
|
||||||
|
|
||||||
|
new_tty_prefork (inferior_io_terminal);
|
||||||
|
|
||||||
|
/* It is generally good practice to flush any possible pending stdio
|
||||||
|
output prior to doing a fork, to avoid the possibility of both the
|
||||||
|
parent and child flushing the same data after the fork. */
|
||||||
|
|
||||||
|
fflush (stdout);
|
||||||
|
fflush (stderr);
|
||||||
|
|
||||||
|
#if defined(USG) && !defined(HAVE_VFORK)
|
||||||
|
pid = fork ();
|
||||||
|
#else
|
||||||
|
if (debug_fork)
|
||||||
|
pid = fork ();
|
||||||
|
else
|
||||||
|
pid = vfork ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pid < 0)
|
||||||
|
perror_with_name ("vfork");
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
{
|
||||||
|
if (debug_fork)
|
||||||
|
sleep (debug_fork);
|
||||||
|
|
||||||
|
#ifdef TIOCGPGRP
|
||||||
|
/* Run inferior in a separate process group. */
|
||||||
|
#ifdef NEED_POSIX_SETPGID
|
||||||
|
debug_setpgrp = setpgid (0, 0);
|
||||||
|
#else
|
||||||
|
#if defined(USG) && !defined(SETPGRP_ARGS)
|
||||||
|
debug_setpgrp = setpgrp ();
|
||||||
|
#else
|
||||||
|
debug_setpgrp = setpgrp (getpid (), getpid ());
|
||||||
|
#endif /* USG */
|
||||||
|
#endif /* NEED_POSIX_SETPGID */
|
||||||
|
if (debug_setpgrp == -1)
|
||||||
|
perror("setpgrp failed in child");
|
||||||
|
#endif /* TIOCGPGRP */
|
||||||
|
|
||||||
|
#ifdef SET_STACK_LIMIT_HUGE
|
||||||
|
/* Reset the stack limit back to what it was. */
|
||||||
|
{
|
||||||
|
struct rlimit rlim;
|
||||||
|
|
||||||
|
getrlimit (RLIMIT_STACK, &rlim);
|
||||||
|
rlim.rlim_cur = original_stack_limit;
|
||||||
|
setrlimit (RLIMIT_STACK, &rlim);
|
||||||
|
}
|
||||||
|
#endif /* SET_STACK_LIMIT_HUGE */
|
||||||
|
|
||||||
|
/* Ask the tty subsystem to switch to the one we specified earlier
|
||||||
|
(or to share the current terminal, if none was specified). */
|
||||||
|
|
||||||
|
new_tty ();
|
||||||
|
|
||||||
|
/* Changing the signal handlers for the inferior after
|
||||||
|
a vfork can also change them for the superior, so we don't mess
|
||||||
|
with signals here. See comments in
|
||||||
|
initialize_signals for how we get the right signal handlers
|
||||||
|
for the inferior. */
|
||||||
|
|
||||||
|
/* "Trace me, Dr. Memory!" */
|
||||||
|
(*traceme_fun) ();
|
||||||
|
|
||||||
|
/* There is no execlpe call, so we have to set the environment
|
||||||
|
for our child in the global variable. If we've vforked, this
|
||||||
|
clobbers the parent, but environ is restored a few lines down
|
||||||
|
in the parent. By the way, yes we do need to look down the
|
||||||
|
path to find $SHELL. Rich Pixley says so, and I agree. */
|
||||||
|
environ = env;
|
||||||
|
execlp (shell_file, shell_file, "-c", shell_command, (char *)0);
|
||||||
|
|
||||||
|
fprintf (stderr, "Cannot exec %s: %s.\n", shell_file,
|
||||||
|
safe_strerror (errno));
|
||||||
|
fflush (stderr);
|
||||||
|
_exit (0177);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore our environment in case a vforked child clob'd it. */
|
||||||
|
environ = save_our_env;
|
||||||
|
|
||||||
|
/* Now that we have a child process, make it our target, and
|
||||||
|
initialize anything target-vector-specific that needs initializing. */
|
||||||
|
(*init_trace_fun)(pid);
|
||||||
|
|
||||||
|
#ifdef CREATE_INFERIOR_HOOK
|
||||||
|
CREATE_INFERIOR_HOOK (pid);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The process was started by the fork that created it,
|
||||||
|
but it will have stopped one instruction after execing the shell.
|
||||||
|
Here we must get it up to actual execution of the real program. */
|
||||||
|
|
||||||
|
inferior_pid = pid; /* Needed for wait_for_inferior stuff below */
|
||||||
|
|
||||||
|
clear_proceed_status ();
|
||||||
|
|
||||||
|
/* We will get a trace trap after one instruction.
|
||||||
|
Continue it automatically. Eventually (after shell does an exec)
|
||||||
|
it will get another trace trap. Then insert breakpoints and continue. */
|
||||||
|
|
||||||
|
#ifdef START_INFERIOR_TRAPS_EXPECTED
|
||||||
|
pending_execs = START_INFERIOR_TRAPS_EXPECTED;
|
||||||
|
#else
|
||||||
|
pending_execs = 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
init_wait_for_inferior ();
|
||||||
|
|
||||||
|
/* Set up the "saved terminal modes" of the inferior
|
||||||
|
based on what modes we are starting it with. */
|
||||||
|
target_terminal_init ();
|
||||||
|
|
||||||
|
/* Install inferior's terminal modes. */
|
||||||
|
target_terminal_inferior ();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
stop_soon_quietly = 1; /* Make wait_for_inferior be quiet */
|
||||||
|
wait_for_inferior ();
|
||||||
|
if (stop_signal != SIGTRAP)
|
||||||
|
{
|
||||||
|
/* Let shell child handle its own signals in its own way */
|
||||||
|
/* FIXME, what if child has exit()ed? Must exit loop somehow */
|
||||||
|
resume (0, stop_signal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We handle SIGTRAP, however; it means child did an exec. */
|
||||||
|
if (0 == --pending_execs)
|
||||||
|
break;
|
||||||
|
resume (0, 0); /* Just make it go on */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stop_soon_quietly = 0;
|
||||||
|
|
||||||
|
/* We are now in the child process of interest, having exec'd the
|
||||||
|
correct program, and are poised at the first instruction of the
|
||||||
|
new program. */
|
||||||
|
#ifdef SOLIB_CREATE_INFERIOR_HOOK
|
||||||
|
SOLIB_CREATE_INFERIOR_HOOK (pid);
|
||||||
|
#endif
|
||||||
|
}
|
329
gdb/procfs.c
329
gdb/procfs.c
|
@ -34,8 +34,6 @@ regardless of whether or not the actual target has floating point hardware.
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
#ifdef USE_PROC_FS /* Entire file goes away if not using /proc */
|
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/procfs.h>
|
#include <sys/procfs.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -45,6 +43,7 @@ regardless of whether or not the actual target has floating point hardware.
|
||||||
#include "inferior.h"
|
#include "inferior.h"
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
#include "gdbcore.h"
|
||||||
|
|
||||||
#define MAX_SYSCALLS 256 /* Maximum number of syscalls for table */
|
#define MAX_SYSCALLS 256 /* Maximum number of syscalls for table */
|
||||||
|
|
||||||
|
@ -52,6 +51,8 @@ regardless of whether or not the actual target has floating point hardware.
|
||||||
#define PROC_NAME_FMT "/proc/%05d"
|
#define PROC_NAME_FMT "/proc/%05d"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern struct target_ops procfs_ops; /* Forward declaration */
|
||||||
|
|
||||||
#if 1 /* FIXME: Gross and ugly hack to resolve coredep.c global */
|
#if 1 /* FIXME: Gross and ugly hack to resolve coredep.c global */
|
||||||
CORE_ADDR kernel_u_addr;
|
CORE_ADDR kernel_u_addr;
|
||||||
#endif
|
#endif
|
||||||
|
@ -406,6 +407,15 @@ lookupname PARAMS ((struct trans *, unsigned int, char *));
|
||||||
static char *
|
static char *
|
||||||
lookupdesc PARAMS ((struct trans *, unsigned int));
|
lookupdesc PARAMS ((struct trans *, unsigned int));
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_attach PARAMS ((int pid));
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_detach PARAMS ((int siggnal));
|
||||||
|
|
||||||
|
static void
|
||||||
|
procfs_create_inferior PARAMS ((char *, char *, char **));
|
||||||
|
|
||||||
/* External function prototypes that can't be easily included in any
|
/* External function prototypes that can't be easily included in any
|
||||||
header file because the args are typedefs in system include files. */
|
header file because the args are typedefs in system include files. */
|
||||||
|
|
||||||
|
@ -545,7 +555,8 @@ sigcodename (sip)
|
||||||
return (name);
|
return (name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *sigcodedesc (sip)
|
static char *
|
||||||
|
sigcodedesc (sip)
|
||||||
siginfo_t *sip;
|
siginfo_t *sip;
|
||||||
{
|
{
|
||||||
struct sigcode *scp;
|
struct sigcode *scp;
|
||||||
|
@ -1031,13 +1042,13 @@ ptrace (request, pid, arg3, arg4)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
kill_inferior - kill any currently inferior
|
procfs_kill_inferior - kill any currently inferior
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
void kill_inferior (void)
|
void procfs_kill_inferior (void)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -1051,8 +1062,8 @@ NOTES
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
kill_inferior ()
|
procfs_kill_inferior ()
|
||||||
{
|
{
|
||||||
if (inferior_pid != 0)
|
if (inferior_pid != 0)
|
||||||
{
|
{
|
||||||
|
@ -1097,13 +1108,13 @@ unconditionally_kill_inferior ()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
child_xfer_memory -- copy data to or from inferior memory space
|
procfs_xfer_memory -- copy data to or from inferior memory space
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
int child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
|
int procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
|
||||||
int dowrite, struct target_ops target)
|
int dowrite, struct target_ops target)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
@ -1113,7 +1124,7 @@ DESCRIPTION
|
||||||
if DOWRITE is zero or to inferior if DOWRITE is nonzero.
|
if DOWRITE is zero or to inferior if DOWRITE is nonzero.
|
||||||
|
|
||||||
Returns the length copied, which is either the LEN argument or
|
Returns the length copied, which is either the LEN argument or
|
||||||
zero. This xfer function does not do partial moves, since child_ops
|
zero. This xfer function does not do partial moves, since procfs_ops
|
||||||
doesn't allow memory operations to cross below us in the target stack
|
doesn't allow memory operations to cross below us in the target stack
|
||||||
anyway.
|
anyway.
|
||||||
|
|
||||||
|
@ -1122,9 +1133,8 @@ NOTES
|
||||||
The /proc interface makes this an almost trivial task.
|
The /proc interface makes this an almost trivial task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
int
|
procfs_xfer_memory (memaddr, myaddr, len, dowrite, target)
|
||||||
child_xfer_memory (memaddr, myaddr, len, dowrite, target)
|
|
||||||
CORE_ADDR memaddr;
|
CORE_ADDR memaddr;
|
||||||
char *myaddr;
|
char *myaddr;
|
||||||
int len;
|
int len;
|
||||||
|
@ -1153,13 +1163,13 @@ child_xfer_memory (memaddr, myaddr, len, dowrite, target)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
store_inferior_registers -- copy register values back to inferior
|
procfs_store_registers -- copy register values back to inferior
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
void store_inferior_registers (int regno)
|
void procfs_store_registers (int regno)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -1189,8 +1199,8 @@ NOTES
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
store_inferior_registers (regno)
|
procfs_store_registers (regno)
|
||||||
int regno;
|
int regno;
|
||||||
{
|
{
|
||||||
if (regno != -1)
|
if (regno != -1)
|
||||||
|
@ -1219,13 +1229,13 @@ store_inferior_registers (regno)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
inferior_proc_init - initialize access to a /proc entry
|
procfs_init_inferior - initialize access to a /proc entry
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
void inferior_proc_init (int pid)
|
void procfs_init_inferior (int pid)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -1242,10 +1252,13 @@ NOTES
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
inferior_proc_init (pid)
|
procfs_init_inferior (pid)
|
||||||
int pid;
|
int pid;
|
||||||
{
|
{
|
||||||
|
|
||||||
|
push_target (&procfs_ops);
|
||||||
|
|
||||||
if (!open_proc_file (pid, &pi, O_RDWR))
|
if (!open_proc_file (pid, &pi, O_RDWR))
|
||||||
{
|
{
|
||||||
proc_init_failed ("can't open process file");
|
proc_init_failed ("can't open process file");
|
||||||
|
@ -1322,7 +1335,7 @@ proc_signal_handling_change ()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
proc_set_exec_trap -- arrange for exec'd child to halt at startup
|
proc_set_exec_trap -- arrange for exec'd child to halt at startup
|
||||||
|
|
||||||
|
@ -1351,7 +1364,7 @@ NOTE
|
||||||
tracing flags cleared.
|
tracing flags cleared.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
proc_set_exec_trap ()
|
proc_set_exec_trap ()
|
||||||
{
|
{
|
||||||
sysset_t exitset;
|
sysset_t exitset;
|
||||||
|
@ -1465,6 +1478,7 @@ proc_iterate_over_mappings (func)
|
||||||
return (funcstat);
|
return (funcstat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* Currently unused */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
GLOBAL FUNCTION
|
||||||
|
@ -1486,9 +1500,6 @@ DESCRIPTION
|
||||||
segment containing that address.
|
segment containing that address.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if 0 /* Currently unused */
|
|
||||||
|
|
||||||
CORE_ADDR
|
CORE_ADDR
|
||||||
proc_base_address (addr)
|
proc_base_address (addr)
|
||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
|
@ -1561,17 +1572,117 @@ proc_address_to_fd (addr, complain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef ATTACH_DETACH
|
/* Attach to process PID, then initialize for debugging it
|
||||||
|
and wait for the trace-trap that results from attaching. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
procfs_attach (args, from_tty)
|
||||||
|
char *args;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
char *exec_file;
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
if (!args)
|
||||||
|
error_no_arg ("process-id to attach");
|
||||||
|
|
||||||
|
pid = atoi (args);
|
||||||
|
|
||||||
|
if (pid == getpid()) /* Trying to masturbate? */
|
||||||
|
error ("I refuse to debug myself!");
|
||||||
|
|
||||||
|
if (from_tty)
|
||||||
|
{
|
||||||
|
exec_file = (char *) get_exec_file (0);
|
||||||
|
|
||||||
|
if (exec_file)
|
||||||
|
printf ("Attaching program `%s', pid %d\n", exec_file, pid);
|
||||||
|
else
|
||||||
|
printf ("Attaching pid %d\n", pid);
|
||||||
|
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_attach (pid);
|
||||||
|
inferior_pid = pid;
|
||||||
|
push_target (&procfs_ops);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Take a program previously attached to and detaches it.
|
||||||
|
The program resumes execution and will no longer stop
|
||||||
|
on signals, etc. We'd better not have left any breakpoints
|
||||||
|
in the program or it'll die when it hits one. For this
|
||||||
|
to work, it may be necessary for the process to have been
|
||||||
|
previously attached. It *might* work if the program was
|
||||||
|
started via the normal ptrace (PTRACE_TRACEME). */
|
||||||
|
|
||||||
|
static void
|
||||||
|
procfs_detach (args, from_tty)
|
||||||
|
char *args;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
int siggnal = 0;
|
||||||
|
|
||||||
|
if (from_tty)
|
||||||
|
{
|
||||||
|
char *exec_file = get_exec_file (0);
|
||||||
|
if (exec_file == 0)
|
||||||
|
exec_file = "";
|
||||||
|
printf ("Detaching program: %s pid %d\n",
|
||||||
|
exec_file, inferior_pid);
|
||||||
|
fflush (stdout);
|
||||||
|
}
|
||||||
|
if (args)
|
||||||
|
siggnal = atoi (args);
|
||||||
|
|
||||||
|
do_detach (siggnal);
|
||||||
|
inferior_pid = 0;
|
||||||
|
unpush_target (&procfs_ops); /* Pop out of handling an inferior */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get ready to modify the registers array. On machines which store
|
||||||
|
individual registers, this doesn't need to do anything. On machines
|
||||||
|
which store all the registers in one fell swoop, this makes sure
|
||||||
|
that registers contains all the registers from the program being
|
||||||
|
debugged. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
procfs_prepare_to_store ()
|
||||||
|
{
|
||||||
|
#ifdef CHILD_PREPARE_TO_STORE
|
||||||
|
CHILD_PREPARE_TO_STORE ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print status information about what we're accessing. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
procfs_files_info (ignore)
|
||||||
|
struct target_ops *ignore;
|
||||||
|
{
|
||||||
|
printf ("\tUsing the running image of %s process %d via /proc.\n",
|
||||||
|
attach_flag? "attached": "child", inferior_pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ARGSUSED */
|
||||||
|
static void
|
||||||
|
procfs_open (arg, from_tty)
|
||||||
|
char *arg;
|
||||||
|
int from_tty;
|
||||||
|
{
|
||||||
|
error ("Use the \"run\" command to start a Unix child process.");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
attach -- attach to an already existing process
|
do_attach -- attach to an already existing process
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
int attach (int pid)
|
int do_attach (int pid)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -1588,8 +1699,8 @@ NOTES
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
static int
|
||||||
attach (pid)
|
do_attach (pid)
|
||||||
int pid;
|
int pid;
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
@ -1681,13 +1792,13 @@ attach (pid)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
detach -- detach from an attached-to process
|
do_detach -- detach from an attached-to process
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
void detach (int signal)
|
void do_detach (int signal)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -1708,8 +1819,8 @@ DESCRIPTION
|
||||||
be the ideal situation. (FIXME).
|
be the ideal situation. (FIXME).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
detach (signal)
|
do_detach (signal)
|
||||||
int signal;
|
int signal;
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
@ -1786,17 +1897,18 @@ detach (signal)
|
||||||
attach_flag = 0;
|
attach_flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ATTACH_DETACH */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
|
procfs_wait -- emulate wait() as much as possible
|
||||||
|
Wait for child to do something. Return pid of child, or -1 in case
|
||||||
|
of error; store status through argument pointer STATUS.
|
||||||
|
|
||||||
proc_wait -- emulate wait() as much as possible
|
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
int proc_wait (int *statloc)
|
int procfs_wait (int *statloc)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -1825,8 +1937,8 @@ NOTES
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
static int
|
||||||
proc_wait (statloc)
|
procfs_wait (statloc)
|
||||||
int *statloc;
|
int *statloc;
|
||||||
{
|
{
|
||||||
short what;
|
short what;
|
||||||
|
@ -1942,10 +2054,19 @@ proc_wait (statloc)
|
||||||
pi.prstatus.pr_flags);
|
pi.prstatus.pr_flags);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statloc)
|
if (statloc)
|
||||||
{
|
{
|
||||||
*statloc = statval;
|
*statloc = statval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rtnval == -1) /* No more children to wait for */
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Child process unexpectedly missing.\n");
|
||||||
|
*statloc = 42; /* Claim it exited with signal 42 */
|
||||||
|
return rtnval;
|
||||||
|
}
|
||||||
|
|
||||||
return (rtnval);
|
return (rtnval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2021,13 +2142,13 @@ set_proc_siginfo (pip, signo)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
child_resume -- resume execution of the inferior process
|
procfs_resume -- resume execution of the inferior process
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
void child_resume (int step, int signo)
|
void procfs_resume (int step, int signo)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -2055,8 +2176,8 @@ NOTE
|
||||||
an inferior to continue running at the same time as gdb. (FIXME?)
|
an inferior to continue running at the same time as gdb. (FIXME?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
child_resume (step, signo)
|
procfs_resume (step, signo)
|
||||||
int step;
|
int step;
|
||||||
int signo;
|
int signo;
|
||||||
{
|
{
|
||||||
|
@ -2095,13 +2216,13 @@ child_resume (step, signo)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
LOCAL FUNCTION
|
||||||
|
|
||||||
fetch_inferior_registers -- fetch current registers from inferior
|
procfs_fetch_registers -- fetch current registers from inferior
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
void fetch_inferior_registers (int regno)
|
void procfs_fetch_registers (int regno)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -2111,8 +2232,8 @@ DESCRIPTION
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
static void
|
||||||
fetch_inferior_registers (regno)
|
procfs_fetch_registers (regno)
|
||||||
int regno;
|
int regno;
|
||||||
{
|
{
|
||||||
if (ioctl (pi.fd, PIOCGREG, &pi.gregset) != -1)
|
if (ioctl (pi.fd, PIOCGREG, &pi.gregset) != -1)
|
||||||
|
@ -2773,7 +2894,9 @@ DESCRIPTION
|
||||||
info proc mappings (prints address mappings)
|
info proc mappings (prints address mappings)
|
||||||
info proc times (prints process/children times)
|
info proc times (prints process/children times)
|
||||||
info proc id (prints pid, ppid, gid, sid, etc)
|
info proc id (prints pid, ppid, gid, sid, etc)
|
||||||
|
FIXME: i proc id not implemented.
|
||||||
info proc status (prints general process state info)
|
info proc status (prints general process state info)
|
||||||
|
FIXME: i proc status not implemented.
|
||||||
info proc signals (prints info about signal handling)
|
info proc signals (prints info about signal handling)
|
||||||
info proc all (prints all info)
|
info proc all (prints all info)
|
||||||
|
|
||||||
|
@ -2936,15 +3059,86 @@ info_proc (args, from_tty)
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fork an inferior process, and start debugging it with /proc. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
procfs_create_inferior (exec_file, allargs, env)
|
||||||
|
char *exec_file;
|
||||||
|
char *allargs;
|
||||||
|
char **env;
|
||||||
|
{
|
||||||
|
fork_inferior (exec_file, allargs, env,
|
||||||
|
proc_set_exec_trap, procfs_init_inferior);
|
||||||
|
/* We are at the first instruction we care about. */
|
||||||
|
/* Pedal to the metal... */
|
||||||
|
proceed ((CORE_ADDR) -1, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up after the inferior dies. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
procfs_mourn_inferior ()
|
||||||
|
{
|
||||||
|
unpush_target (&procfs_ops);
|
||||||
|
generic_mourn_inferior ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
|
||||||
|
static int
|
||||||
|
procfs_can_run ()
|
||||||
|
{
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct target_ops procfs_ops = {
|
||||||
|
"procfs", /* to_shortname */
|
||||||
|
"Unix /proc child process", /* to_longname */
|
||||||
|
"Unix /proc child process (started by the \"run\" command).", /* to_doc */
|
||||||
|
procfs_open, /* to_open */
|
||||||
|
0, /* to_close */
|
||||||
|
procfs_attach, /* to_attach */
|
||||||
|
procfs_detach, /* to_detach */
|
||||||
|
procfs_resume, /* to_resume */
|
||||||
|
procfs_wait, /* to_wait */
|
||||||
|
procfs_fetch_registers, /* to_fetch_registers */
|
||||||
|
procfs_store_registers, /* to_store_registers */
|
||||||
|
procfs_prepare_to_store, /* to_prepare_to_store */
|
||||||
|
procfs_xfer_memory, /* to_xfer_memory */
|
||||||
|
procfs_files_info, /* to_files_info */
|
||||||
|
memory_insert_breakpoint, /* to_insert_breakpoint */
|
||||||
|
memory_remove_breakpoint, /* to_remove_breakpoint */
|
||||||
|
terminal_init_inferior, /* to_terminal_init */
|
||||||
|
terminal_inferior, /* to_terminal_inferior */
|
||||||
|
terminal_ours_for_output, /* to_terminal_ours_for_output */
|
||||||
|
terminal_ours, /* to_terminal_ours */
|
||||||
|
child_terminal_info, /* to_terminal_info */
|
||||||
|
procfs_kill_inferior, /* to_kill */
|
||||||
|
0, /* to_load */
|
||||||
|
0, /* to_lookup_symbol */
|
||||||
|
procfs_create_inferior, /* to_create_inferior */
|
||||||
|
procfs_mourn_inferior, /* to_mourn_inferior */
|
||||||
|
procfs_can_run, /* to_can_run */
|
||||||
|
process_stratum, /* to_stratum */
|
||||||
|
0, /* to_next */
|
||||||
|
1, /* to_has_all_memory */
|
||||||
|
1, /* to_has_memory */
|
||||||
|
1, /* to_has_stack */
|
||||||
|
1, /* to_has_registers */
|
||||||
|
1, /* to_has_execution */
|
||||||
|
0, /* sections */
|
||||||
|
0, /* sections_end */
|
||||||
|
OPS_MAGIC /* to_magic */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
GLOBAL FUNCTION
|
GLOBAL FUNCTION
|
||||||
|
|
||||||
_initialize_proc_fs -- initialize the process file system stuff
|
_initialize_procfs -- initialize the process file system stuff
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
|
|
||||||
void _initialize_proc_fs (void)
|
void _initialize_procfs (void)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
|
@ -2953,19 +3147,18 @@ DESCRIPTION
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *proc_desc =
|
void
|
||||||
|
_initialize_procfs ()
|
||||||
|
{
|
||||||
|
add_target (&procfs_ops);
|
||||||
|
|
||||||
|
add_info ("proc", info_proc,
|
||||||
"Show process status information using /proc entry.\n\
|
"Show process status information using /proc entry.\n\
|
||||||
Specify process id or use current inferior by default.\n\
|
Specify process id or use current inferior by default.\n\
|
||||||
Specify keywords for detailed information; default is summary.\n\
|
Specify keywords for detailed information; default is summary.\n\
|
||||||
Keywords are: `all', `faults', `flags', `id', `mappings', `signals',\n\
|
Keywords are: `all', `faults', `flags', `id', `mappings', `signals',\n\
|
||||||
`status', `syscalls', and `times'.\n\
|
`status', `syscalls', and `times'.\n\
|
||||||
Unambiguous abbreviations may be used.";
|
Unambiguous abbreviations may be used.");
|
||||||
|
|
||||||
void
|
|
||||||
_initialize_proc_fs ()
|
|
||||||
{
|
|
||||||
add_info ("proc", info_proc, proc_desc);
|
|
||||||
init_syscall_table ();
|
init_syscall_table ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_PROC_FS */
|
|
||||||
|
|
|
@ -43,12 +43,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
#define USE_PROC_FS
|
#define USE_PROC_FS
|
||||||
#define PROC_NAME_FMT "/debug/%d"
|
#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
|
/* Irix defines psignal() in signal.h, which gets gcc rather angry at us
|
||||||
* because their definition is markedly different.
|
* because their definition is markedly different.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -55,13 +55,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#define ATTACH_DETACH
|
#define ATTACH_DETACH
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
/* Use setpgid(0,0) to run inferior in a separate process group */
|
/* Use setpgid(0,0) to run inferior in a separate process group */
|
||||||
|
|
||||||
#define NEED_POSIX_SETPGID
|
#define NEED_POSIX_SETPGID
|
||||||
|
|
Loading…
Reference in New Issue