*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / inf-ptrace.c
index ba9d8a8aec9e863cf6c416744b7569a4c47f2f63..b5e1744b1faf6721473f23373e8854f2ccf902c1 100644 (file)
@@ -1,7 +1,7 @@
 /* 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, 2009, 2010
+   1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -121,17 +121,23 @@ inf_ptrace_create_inferior (struct target_ops *ops,
 {
   int pid;
 
-  pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
-                      NULL, NULL);
+  /* Do not change either targets above or the same target if already present.
+     The reason is the target stack is shared across multiple inferiors.  */
+  int ops_already_pushed = target_is_pushed (ops);
+  struct cleanup *back_to = NULL;
 
-  push_target (ops);
+  if (! ops_already_pushed)
+    {
+      /* Clear possible core file with its process_stratum.  */
+      push_target (ops);
+      back_to = make_cleanup_unpush_target (ops);
+    }
 
-  /* 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.  */
+  pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
+                      NULL, NULL);
 
-  target_acknowledge_created_inferior (pid);
+  if (! ops_already_pushed)
+    discard_cleanups (back_to);
 
   /* 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
@@ -189,11 +195,24 @@ inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
   pid_t pid;
   struct inferior *inf;
 
+  /* Do not change either targets above or the same target if already present.
+     The reason is the target stack is shared across multiple inferiors.  */
+  int ops_already_pushed = target_is_pushed (ops);
+  struct cleanup *back_to = NULL;
+
   pid = parse_pid_to_attach (args);
 
   if (pid == getpid ())                /* Trying to masturbate?  */
     error (_("I refuse to debug myself!"));
 
+  if (! ops_already_pushed)
+    {
+      /* target_pid_to_str already uses the target.  Also clear possible core
+        file with its process_stratum.  */
+      push_target (ops);
+      back_to = make_cleanup_unpush_target (ops);
+    }
+
   if (from_tty)
     {
       exec_file = get_exec_file (0);
@@ -226,7 +245,8 @@ inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
      target, it should decorate the ptid later with more info.  */
   add_thread_silent (inferior_ptid);
 
-  push_target(ops);
+  if (! ops_already_pushed)
+    discard_cleanups (back_to);
 }
 
 #ifdef PT_GET_PROCESS_STATE
This page took 0.024546 seconds and 4 git commands to generate.