Added missing files to ChangeLog entry.
[deliverable/binutils-gdb.git] / gdb / linux-fork.c
index 7141637413da3a8bcff1cd88e2f43f7b3e144b2d..f80fe5fa0a8317d2e5d5d646988a0a1f0d51643e 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU/Linux native-dependent code for debugging multiple forks.
 
-   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "regcache.h"
 #include "gdbcmd.h"
 #include "infcall.h"
+#include "objfiles.h"
 #include "gdb_assert.h"
 #include "gdb_string.h"
 #include "linux-fork.h"
 #include "linux-nat.h"
 
 #include <sys/ptrace.h>
-#include <sys/wait.h>
+#include "gdb_wait.h"
 #include <sys/param.h>
-#include <dirent.h>
+#include "gdb_dirent.h"
 #include <ctype.h>
 
 struct fork_info *fork_list;
@@ -209,6 +210,7 @@ init_fork_list (void)
   for (fp = fork_list; fp; fp = fpnext)
     {
       fpnext = fp->next;
+      delete_inferior (ptid_get_pid (fp->ptid));
       free_fork (fp);
     }
 
@@ -337,7 +339,9 @@ linux_fork_killall (void)
     {
       pid = PIDGET (fp->ptid);
       do {
-       ptrace (PT_KILL, pid, 0, 0);
+       /* Use SIGKILL instead of PTRACE_KILL because the former works even
+          if the thread is running, while the later doesn't.  */
+       kill (pid, SIGKILL);
        ret = waitpid (pid, &status, 0);
        /* We might get a SIGCHLD instead of an exit status.  This is
         aggravated by the first kill above - a child has just
@@ -366,6 +370,8 @@ linux_fork_mourn_inferior (void)
      We need to delete that one from the fork_list, and switch
      to the next available fork.  */
   delete_fork (inferior_ptid);
+  /* Delete process from GDB's inferior list.  */
+  delete_inferior (ptid_get_pid (inferior_ptid));
 
   /* There should still be a fork - if there's only one left,
      delete_fork won't remove it, because we haven't updated
@@ -405,6 +411,8 @@ delete_fork_command (char *args, int from_tty)
     printf_filtered (_("Killed %s\n"), target_pid_to_str (ptid));
 
   delete_fork (ptid);
+  /* Delete process from GDB's inferior list.  */
+  delete_inferior (ptid_get_pid (ptid));
 }
 
 static void
@@ -429,6 +437,8 @@ detach_fork_command (char *args, int from_tty)
     printf_filtered (_("Detached %s\n"), target_pid_to_str (ptid));
 
   delete_fork (ptid);
+  /* Delete process from GDB's process table.  */
+  detach_inferior (ptid_get_pid (ptid));
 }
 
 /* Print information about currently known forks.  */
@@ -468,7 +478,7 @@ info_forks_command (char *arg, int from_tty)
       if (fp->num == 0)
        printf_filtered (_(" (main process)"));
       printf_filtered (_(" at "));
-      deprecated_print_address_numeric (pc, 1, gdb_stdout);
+      fputs_filtered (paddress (pc), gdb_stdout);
 
       sal = find_pc_line (pc, 0);
       if (sal.symtab)
@@ -526,6 +536,8 @@ save_detach_fork (int *saved_val)
 static void
 checkpoint_command (char *args, int from_tty)
 {
+  struct objfile *fork_objf;
+  struct gdbarch *gdbarch;
   struct target_waitstatus last_target_waitstatus;
   ptid_t last_target_ptid;
   struct value *fork_fn = NULL, *ret;
@@ -536,17 +548,22 @@ checkpoint_command (char *args, int from_tty)
   /* Make this temp var static, 'cause it's used in the error context.  */
   static int temp_detach_fork;
 
+  /* Remove breakpoints, so that they are not inserted
+     in the forked process.  */
+  remove_breakpoints ();
+
   /* Make the inferior fork, record its (and gdb's) state.  */
 
   if (lookup_minimal_symbol ("fork", NULL, NULL) != NULL)
-    fork_fn = find_function_in_inferior ("fork");
+    fork_fn = find_function_in_inferior ("fork", &fork_objf);
   if (!fork_fn)
     if (lookup_minimal_symbol ("_fork", NULL, NULL) != NULL)
-      fork_fn = find_function_in_inferior ("fork");
+      fork_fn = find_function_in_inferior ("fork", &fork_objf);
   if (!fork_fn)
     error (_("checkpoint: can't find fork function in inferior."));
 
-  ret = value_from_longest (builtin_type_int, 0);
+  gdbarch = get_objfile_arch (fork_objf);
+  ret = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);
   old_chain = save_detach_fork (&temp_detach_fork);
   detach_fork = 0;
   ret = call_function_by_hand (fork_fn, 0, &ret);
@@ -576,6 +593,7 @@ checkpoint_command (char *args, int from_tty)
   if (!fp)
     error (_("Failed to find new fork"));
   fork_save_infrun_state (fp, 1);
+  insert_breakpoints ();
 }
 
 static void
@@ -593,7 +611,9 @@ linux_fork_context (struct fork_info *newfp, int from_tty)
     oldfp = add_fork (ptid_get_pid (inferior_ptid));
 
   fork_save_infrun_state (oldfp, 1);
+  remove_breakpoints ();
   fork_load_infrun_state (newfp);
+  insert_breakpoints ();
 
   printf_filtered (_("Switching to %s\n"), 
                   target_pid_to_str (inferior_ptid));
This page took 0.025157 seconds and 4 git commands to generate.