/* Low-level child interface to ptrace.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
- 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
+ 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_wait.h"
#include <signal.h>
+#include "inf-ptrace.h"
#include "inf-child.h"
#include "gdbthread.h"
CORE_ADDR step_range_start = last_tp->step_range_start;
CORE_ADDR step_range_end = last_tp->step_range_end;
struct frame_id step_frame_id = last_tp->step_frame_id;
-
+ int attach_flag = find_inferior_pid (pid)->attach_flag;
+ struct inferior *inf;
struct thread_info *tp;
/* Otherwise, deleting the parent would get rid of this
/* Before detaching from the parent, remove all breakpoints from
it. */
- detach_breakpoints (pid);
+ remove_breakpoints ();
if (ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
perror_with_name (("ptrace"));
detach_inferior (pid);
/* Add the child. */
- add_inferior (fpid);
+ inf = add_inferior (fpid);
+ inf->attach_flag = attach_flag;
tp = add_thread_silent (inferior_ptid);
tp->step_resume_breakpoint = step_resume_breakpoint;
inferior_ptid = null_ptid;
detach_inferior (pid);
- unpush_target (ops);
+
+ if (!have_inferiors ())
+ unpush_target (ops);
}
/* Kill the inferior. */
static void
-inf_ptrace_kill (void)
+inf_ptrace_kill (struct target_ops *ops)
{
pid_t pid = ptid_get_pid (inferior_ptid);
int status;
that signal. */
static void
-inf_ptrace_resume (ptid_t ptid, int step, enum target_signal signal)
+inf_ptrace_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal signal)
{
pid_t pid = ptid_get_pid (ptid);
int request = PT_CONTINUE;
the status in *OURSTATUS. */
static ptid_t
-inf_ptrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
+inf_ptrace_wait (struct target_ops *ops,
+ ptid_t ptid, struct target_waitstatus *ourstatus)
{
pid_t pid;
int status, save_errno;
do
{
set_sigint_trap ();
- set_sigio_trap ();
do
{
}
while (pid == -1 && errno == EINTR);
- clear_sigio_trap ();
clear_sigint_trap ();
if (pid == -1)
/* Return non-zero if the thread specified by PTID is alive. */
static int
-inf_ptrace_thread_alive (ptid_t ptid)
+inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid)
{
/* ??? Is kill the right way to do this? */
return (kill (ptid_get_pid (ptid), 0) != -1);
target_pid_to_str (inferior_ptid));
}
+static char *
+inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
+{
+ return normal_pid_to_str (ptid);
+}
+
/* Create a prototype ptrace target. The client can override it with
local methods. */
#endif
t->to_mourn_inferior = inf_ptrace_mourn_inferior;
t->to_thread_alive = inf_ptrace_thread_alive;
- t->to_pid_to_str = normal_pid_to_str;
+ t->to_pid_to_str = inf_ptrace_pid_to_str;
t->to_stop = inf_ptrace_stop;
t->to_xfer_partial = inf_ptrace_xfer_partial;
for all registers. */
static void
-inf_ptrace_fetch_registers (struct regcache *regcache, int regnum)
+inf_ptrace_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;
/* Store register REGNUM back into the inferior. If REGNUM is -1, do
this for all registers. */
-void
-inf_ptrace_store_registers (struct regcache *regcache, int regnum)
+static void
+inf_ptrace_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regnum)
{
if (regnum == -1)
for (regnum = 0;