Skip to content
Snippets Groups Projects
Commit c7c14b96 authored by Mark Kettenis's avatar Mark Kettenis
Browse files

* inf-ptrace.c: Reorder functions.

(inf_ptrace_open, inf_ptrace_reported_exec_events_per_call)
(inf_ptrace_can_run, inf_ptrace_post_attach): Removed.
(inf_ptrace_target): Don't set to_open,
to_reported_exec_events_per_call, to_can_run, to_post_attach,
to_stratum, to_has_all_memory, to_has_memory, to_has_stack,
to_has_registers, to_has_execution, to_magic.  Reorder remaining
initializations.
parent 3b22753a
No related branches found
No related tags found
No related merge requests found
2005-07-25 Mark Kettenis <kettenis@gnu.org>
* inf-ptrace.c: Reorder functions.
(inf_ptrace_open, inf_ptrace_reported_exec_events_per_call)
(inf_ptrace_can_run, inf_ptrace_post_attach): Removed.
(inf_ptrace_target): Don't set to_open,
to_reported_exec_events_per_call, to_can_run, to_post_attach,
to_stratum, to_has_all_memory, to_has_memory, to_has_stack,
to_has_registers, to_has_execution, to_magic. Reorder remaining
initializations.
2005-07-25 Mark Mitchell <mark@codesourcery.com>
* configure.ac: On MinGW, do not require a termcap library, and
......
......@@ -39,141 +39,65 @@
/* HACK: Save the ptrace ops returned by inf_ptrace_target. */
static struct target_ops *ptrace_ops_hack;
/* Stub function which causes the inferior that runs it, to be ptrace-able
by its parent process. */
static void
inf_ptrace_kill_inferior (void)
inf_ptrace_me (void)
{
int status;
int pid = PIDGET (inferior_ptid);
if (pid == 0)
return;
/* This once used to call "kill" to kill the inferior just in case
the inferior was still running. As others have noted in the past
(kingdon) there shouldn't be any way to get here if the inferior
is still running -- else there's a major problem elsewere in GDB
and it needs to be fixed.
The kill call causes problems under HP-UX 10, so it's been
removed; if this causes problems we'll deal with them as they
arise. */
ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3) 0, 0);
wait (&status);
target_mourn_inferior ();
/* "Trace me, Dr. Memory!" */
ptrace (0, 0, (PTRACE_TYPE_ARG3) 0, 0);
}
/* Resume execution of the inferior process. If STEP is nonzero,
single-step it. If SIGNAL is nonzero, give it that signal. */
/* Stub function which causes the GDB that runs it, to start ptrace-ing
the child process. */
static void
inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
inf_ptrace_him (int pid)
{
int request = PT_CONTINUE;
int pid = PIDGET (ptid);
push_target (ptrace_ops_hack);
if (pid == -1)
/* Resume all threads. */
/* I think this only gets used in the non-threaded case, where
"resume all threads" and "resume inferior_ptid" are the
same. */
pid = PIDGET (inferior_ptid);
/* On some targets, there must be some explicit synchronization
between the parent and child processes after the debugger
forks, and before the child execs the debuggee program. This
call basically gives permission for the child to exec. */
if (step)
{
/* If this system does not support PT_STEP, a higher level
function will have called single_step() to transmute the step
request into a continue request (by setting breakpoints on
all possible successor instructions), so we don't have to
worry about that here. */
request = PT_STEP;
}
target_acknowledge_created_inferior (pid);
/* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
where it was. If GDB wanted it to start some other way, we have
already written a new PC value to the child. */
errno = 0;
ptrace (request, pid, (PTRACE_TYPE_ARG3) 1, target_signal_to_host (signal));
if (errno != 0)
perror_with_name (("ptrace"));
/* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
be 1 or 2 depending on whether we're starting without or with a
shell. */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
/* On some targets, there must be some explicit actions taken after
the inferior has been started up. */
target_post_startup_inferior (pid_to_ptid (pid));
}
/* Wait for child to do something. Return pid of child, or -1 in case
of error; store status through argument pointer OURSTATUS. */
/* Start an inferior Unix child process and sets inferior_ptid 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(). */
static ptid_t
inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
static void
inf_ptrace_create_inferior (char *exec_file, char *allargs, char **env,
int from_tty)
{
int save_errno;
int status;
char *execd_pathname = NULL;
int exit_status;
int related_pid;
int syscall_id;
enum target_waitkind kind;
int pid;
do
{
set_sigint_trap (); /* Causes SIGINT to be passed on to the
attached process. */
set_sigio_trap ();
pid = wait (&status);
save_errno = errno;
clear_sigio_trap ();
clear_sigint_trap ();
if (pid == -1)
{
if (save_errno == EINTR)
continue;
fprintf_unfiltered (gdb_stderr,
"Child process unexpectedly missing: %s.\n",
safe_strerror (save_errno));
/* Claim it exited with unknown signal. */
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
return pid_to_ptid (-1);
}
/* Did it exit? */
if (target_has_exited (pid, status, &exit_status))
{
/* ??rehrauer: For now, ignore this. */
continue;
}
if (!target_thread_alive (pid_to_ptid (pid)))
{
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
return pid_to_ptid (pid);
}
}
while (pid != PIDGET (inferior_ptid)); /* Some other child died or
stopped. */
store_waitstatus (ourstatus, status);
return pid_to_ptid (pid);
fork_inferior (exec_file, allargs, env, inf_ptrace_me, inf_ptrace_him,
NULL, NULL);
/* We are at the first instruction we care about. */
observer_notify_inferior_created (&current_target, from_tty);
/* Pedal to the metal... */
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
}
/* Check to see if the given thread is alive.
FIXME: Is kill() ever the right way to do this? I doubt it, but
for now we're going to try and be compatable with the old thread
code. */
static int
inf_ptrace_thread_alive (ptid_t ptid)
static void
inf_ptrace_mourn_inferior (void)
{
pid_t pid = PIDGET (ptid);
return (kill (pid, 0) != -1);
unpush_target (ptrace_ops_hack);
generic_mourn_inferior ();
}
/* Attach to process PID, then initialize for debugging it. */
......@@ -229,13 +153,6 @@ inf_ptrace_attach (char *args, int from_tty)
observer_notify_inferior_created (&current_target, from_tty);
}
static void
inf_ptrace_post_attach (int pid)
{
/* This version of Unix doesn't require a meaningful "post attach"
operation by a debugger. */
}
/* 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
......@@ -275,79 +192,138 @@ inf_ptrace_detach (char *args, int from_tty)
unpush_target (ptrace_ops_hack);
}
/* Print status information about what we're accessing. */
static void
inf_ptrace_files_info (struct target_ops *ignore)
inf_ptrace_kill_inferior (void)
{
printf_unfiltered (_("\tUsing the running image of %s %s.\n"),
attach_flag ? "attached" : "child",
target_pid_to_str (inferior_ptid));
int status;
int pid = PIDGET (inferior_ptid);
if (pid == 0)
return;
/* This once used to call "kill" to kill the inferior just in case
the inferior was still running. As others have noted in the past
(kingdon) there shouldn't be any way to get here if the inferior
is still running -- else there's a major problem elsewere in GDB
and it needs to be fixed.
The kill call causes problems under HP-UX 10, so it's been
removed; if this causes problems we'll deal with them as they
arise. */
ptrace (PT_KILL, pid, (PTRACE_TYPE_ARG3) 0, 0);
wait (&status);
target_mourn_inferior ();
}
/* Send a SIGINT to the process group. This acts just like the user
typed a ^C on the controlling terminal.
FIXME: This may not be correct for all systems. Some may want to
use killpg() instead of kill (-pgrp). */
static void
inf_ptrace_open (char *arg, int from_tty)
inf_ptrace_stop (void)
{
error (_("Use the \"run\" command to start a Unix child process."));
kill (-inferior_process_group, SIGINT);
}
/* Stub function which causes the inferior that runs it, to be ptrace-able
by its parent process. */
/* Resume execution of the inferior process. If STEP is nonzero,
single-step it. If SIGNAL is nonzero, give it that signal. */
static void
inf_ptrace_me (void)
inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
{
/* "Trace me, Dr. Memory!" */
ptrace (0, 0, (PTRACE_TYPE_ARG3) 0, 0);
int request = PT_CONTINUE;
int pid = PIDGET (ptid);
if (pid == -1)
/* Resume all threads. */
/* I think this only gets used in the non-threaded case, where
"resume all threads" and "resume inferior_ptid" are the
same. */
pid = PIDGET (inferior_ptid);
if (step)
{
/* If this system does not support PT_STEP, a higher level
function will have called single_step() to transmute the step
request into a continue request (by setting breakpoints on
all possible successor instructions), so we don't have to
worry about that here. */
request = PT_STEP;
}
/* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
where it was. If GDB wanted it to start some other way, we have
already written a new PC value to the child. */
errno = 0;
ptrace (request, pid, (PTRACE_TYPE_ARG3) 1, target_signal_to_host (signal));
if (errno != 0)
perror_with_name (("ptrace"));
}
/* Stub function which causes the GDB that runs it, to start ptrace-ing
the child process. */
/* Wait for child to do something. Return pid of child, or -1 in case
of error; store status through argument pointer OURSTATUS. */
static void
inf_ptrace_him (int pid)
static ptid_t
inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
push_target (ptrace_ops_hack);
int save_errno;
int status;
char *execd_pathname = NULL;
int exit_status;
int related_pid;
int syscall_id;
enum target_waitkind kind;
int pid;
/* On some targets, there must be some explicit synchronization
between the parent and child processes after the debugger
forks, and before the child execs the debuggee program. This
call basically gives permission for the child to exec. */
do
{
set_sigint_trap (); /* Causes SIGINT to be passed on to the
attached process. */
set_sigio_trap ();
target_acknowledge_created_inferior (pid);
pid = wait (&status);
/* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
be 1 or 2 depending on whether we're starting without or with a
shell. */
startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
save_errno = errno;
/* On some targets, there must be some explicit actions taken after
the inferior has been started up. */
target_post_startup_inferior (pid_to_ptid (pid));
}
clear_sigio_trap ();
/* Start an inferior Unix child process and sets inferior_ptid 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(). */
clear_sigint_trap ();
static void
inf_ptrace_create_inferior (char *exec_file, char *allargs, char **env,
int from_tty)
{
fork_inferior (exec_file, allargs, env, inf_ptrace_me, inf_ptrace_him,
NULL, NULL);
/* We are at the first instruction we care about. */
observer_notify_inferior_created (&current_target, from_tty);
/* Pedal to the metal... */
proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
}
if (pid == -1)
{
if (save_errno == EINTR)
continue;
static int
inf_ptrace_reported_exec_events_per_exec_call (void)
{
/* Typically, we get a single SIGTRAP per exec. */
return 1;
fprintf_unfiltered (gdb_stderr,
"Child process unexpectedly missing: %s.\n",
safe_strerror (save_errno));
/* Claim it exited with unknown signal. */
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
return pid_to_ptid (-1);
}
/* Did it exit? */
if (target_has_exited (pid, status, &exit_status))
{
/* ??rehrauer: For now, ignore this. */
continue;
}
if (!target_thread_alive (pid_to_ptid (pid)))
{
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
return pid_to_ptid (pid);
}
}
while (pid != PIDGET (inferior_ptid)); /* Some other child died or
stopped. */
store_waitstatus (ourstatus, status);
return pid_to_ptid (pid);
}
static int
......@@ -370,31 +346,6 @@ inf_ptrace_has_exited (int pid, int wait_status, int *exit_status)
return 0;
}
static void
inf_ptrace_mourn_inferior (void)
{
unpush_target (ptrace_ops_hack);
generic_mourn_inferior ();
}
static int
inf_ptrace_can_run (void)
{
return 1;
}
/* Send a SIGINT to the process group. This acts just like the user
typed a ^C on the controlling terminal.
FIXME: This may not be correct for all systems. Some may want to
use killpg() instead of kill (-pgrp). */
static void
inf_ptrace_stop (void)
{
kill (-inferior_process_group, SIGINT);
}
/* Perform a partial transfer to/from the specified object. For
memory transfers, fall back to the old memory xfer functions. */
......@@ -516,6 +467,30 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
}
}
/* Check to see if the given thread is alive.
FIXME: Is kill() ever the right way to do this? I doubt it, but
for now we're going to try and be compatable with the old thread
code. */
static int
inf_ptrace_thread_alive (ptid_t ptid)
{
pid_t pid = PIDGET (ptid);
return (kill (pid, 0) != -1);
}
/* Print status information about what we're accessing. */
static void
inf_ptrace_files_info (struct target_ops *ignore)
{
printf_unfiltered (_("\tUsing the running image of %s %s.\n"),
attach_flag ? "attached" : "child",
target_pid_to_str (inferior_ptid));
}
static char *
inf_ptrace_pid_to_str (ptid_t ptid)
{
......@@ -530,33 +505,22 @@ inf_ptrace_target (void)
{
struct target_ops *t = inf_child_target ();
t->to_open = inf_ptrace_open;
t->to_attach = inf_ptrace_attach;
t->to_post_attach = inf_ptrace_post_attach;
t->to_detach = inf_ptrace_detach;
t->to_resume = inf_ptrace_resume;
t->to_wait = inf_ptrace_wait;
t->to_xfer_partial = inf_ptrace_xfer_partial;
t->to_files_info = inf_ptrace_files_info;
t->to_kill = inf_ptrace_kill_inferior;
t->to_create_inferior = inf_ptrace_create_inferior;
t->to_reported_exec_events_per_exec_call =
inf_ptrace_reported_exec_events_per_exec_call;
t->to_has_exited = inf_ptrace_has_exited;
t->to_mourn_inferior = inf_ptrace_mourn_inferior;
t->to_can_run = inf_ptrace_can_run;
t->to_thread_alive = inf_ptrace_thread_alive;
t->to_pid_to_str = inf_ptrace_pid_to_str;
t->to_stop = inf_ptrace_stop;
t->to_stratum = process_stratum;
t->to_has_all_memory = 1;
t->to_has_memory = 1;
t->to_has_stack = 1;
t->to_has_registers = 1;
t->to_has_execution = 1;
t->to_magic = OPS_MAGIC;
ptrace_ops_hack = t;
t->to_xfer_partial = inf_ptrace_xfer_partial;
t->to_has_exited = inf_ptrace_has_exited;
ptrace_ops_hack = t;
return t;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment