]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2009-07-25 Michael Snyder <msnyder@vmware.com>
authorMichael Snyder <msnyder@vmware.com>
Sun, 26 Jul 2009 01:44:32 +0000 (01:44 +0000)
committerMichael Snyder <msnyder@vmware.com>
Sun, 26 Jul 2009 01:44:32 +0000 (01:44 +0000)
* inf-child.c (inf_child_target): Initialize target_ops only once.
* inf-ptrace.c (inf_ptrace_target): Ditto.
(inf_ptrace_trad_target): Ditto.
* linux-nat.c (linux_target): Ditto.
(linux_trad_target): Ditto.

* linux-fork.c (_initialize_linux_fork): Rather than calling
add_cmd to add checkpoint commands, use 'linux_target' to
get the target vector, add the checkpoint functions to it,
and call checkpoint_init to activate the user commands.
(linux_fork_killall): Add optional verbose output.

gdb/ChangeLog
gdb/inf-child.c
gdb/inf-ptrace.c
gdb/linux-fork.c
gdb/linux-nat.c

index 0bf1d40d6963b01ade21279405096a0642e64ccd..8b4a67bb44e46d4f9530a501ee462093cf0b2c00 100644 (file)
@@ -1,3 +1,17 @@
+2009-07-25  Michael Snyder  <msnyder@vmware.com>
+
+       * inf-child.c (inf_child_target): Initialize target_ops only once.
+       * inf-ptrace.c (inf_ptrace_target): Ditto.
+       (inf_ptrace_trad_target): Ditto.
+       * linux-nat.c (linux_target): Ditto.
+       (linux_trad_target): Ditto.
+
+       * linux-fork.c (_initialize_linux_fork): Rather than calling 
+       add_cmd to add checkpoint commands, use 'linux_target' to 
+       get the target vector, add the checkpoint functions to it, 
+       and call checkpoint_init to activate the user commands.
+       (linux_fork_killall): Add optional verbose output.
+
 2009-07-25  Michael Snyder  <msnyder@vmware.com>
 
        * checkpoint.c: New file, target-agnostic checkpoints.
index 2ac702702a8cfdddb5c7195c8bef1dcfa332dbbc..9dfdc8ed359520e68d0302ff335e208abec75cc4 100644 (file)
@@ -164,40 +164,46 @@ inf_child_pid_to_exec_file (int pid)
 struct target_ops *
 inf_child_target (void)
 {
-  struct target_ops *t = XZALLOC (struct target_ops);
-  t->to_shortname = "child";
-  t->to_longname = "Unix child process";
-  t->to_doc = "Unix child process (started by the \"run\" command).";
-  t->to_open = inf_child_open;
-  t->to_post_attach = inf_child_post_attach;
-  t->to_fetch_registers = inf_child_fetch_inferior_registers;
-  t->to_store_registers = inf_child_store_inferior_registers;
-  t->to_prepare_to_store = inf_child_prepare_to_store;
-  t->to_insert_breakpoint = memory_insert_breakpoint;
-  t->to_remove_breakpoint = memory_remove_breakpoint;
-  t->to_terminal_init = terminal_init_inferior;
-  t->to_terminal_inferior = terminal_inferior;
-  t->to_terminal_ours_for_output = terminal_ours_for_output;
-  t->to_terminal_save_ours = terminal_save_ours;
-  t->to_terminal_ours = terminal_ours;
-  t->to_terminal_info = child_terminal_info;
-  t->to_post_startup_inferior = inf_child_post_startup_inferior;
-  t->to_acknowledge_created_inferior = inf_child_acknowledge_created_inferior;
-  t->to_insert_fork_catchpoint = inf_child_insert_fork_catchpoint;
-  t->to_remove_fork_catchpoint = inf_child_remove_fork_catchpoint;
-  t->to_insert_vfork_catchpoint = inf_child_insert_vfork_catchpoint;
-  t->to_remove_vfork_catchpoint = inf_child_remove_vfork_catchpoint;
-  t->to_follow_fork = inf_child_follow_fork;
-  t->to_insert_exec_catchpoint = inf_child_insert_exec_catchpoint;
-  t->to_remove_exec_catchpoint = inf_child_remove_exec_catchpoint;
-  t->to_can_run = inf_child_can_run;
-  t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
-  t->to_stratum = process_stratum;
-  t->to_has_all_memory = default_child_has_all_memory;
-  t->to_has_memory = default_child_has_memory;
-  t->to_has_stack = default_child_has_stack;
-  t->to_has_registers = default_child_has_registers;
-  t->to_has_execution = default_child_has_execution;
-  t->to_magic = OPS_MAGIC;
+  static struct target_ops *t;
+
+  if (t == NULL)       /* Actually init only once.  */
+    {
+      t = XZALLOC (struct target_ops);
+      t->to_shortname = "child";
+      t->to_longname = "Unix child process";
+      t->to_doc = "Unix child process (started by the \"run\" command).";
+      t->to_open = inf_child_open;
+      t->to_post_attach = inf_child_post_attach;
+      t->to_fetch_registers = inf_child_fetch_inferior_registers;
+      t->to_store_registers = inf_child_store_inferior_registers;
+      t->to_prepare_to_store = inf_child_prepare_to_store;
+      t->to_insert_breakpoint = memory_insert_breakpoint;
+      t->to_remove_breakpoint = memory_remove_breakpoint;
+      t->to_terminal_init = terminal_init_inferior;
+      t->to_terminal_inferior = terminal_inferior;
+      t->to_terminal_ours_for_output = terminal_ours_for_output;
+      t->to_terminal_save_ours = terminal_save_ours;
+      t->to_terminal_ours = terminal_ours;
+      t->to_terminal_info = child_terminal_info;
+      t->to_post_startup_inferior = inf_child_post_startup_inferior;
+      t->to_acknowledge_created_inferior 
+       = inf_child_acknowledge_created_inferior;
+      t->to_insert_fork_catchpoint = inf_child_insert_fork_catchpoint;
+      t->to_remove_fork_catchpoint = inf_child_remove_fork_catchpoint;
+      t->to_insert_vfork_catchpoint = inf_child_insert_vfork_catchpoint;
+      t->to_remove_vfork_catchpoint = inf_child_remove_vfork_catchpoint;
+      t->to_follow_fork = inf_child_follow_fork;
+      t->to_insert_exec_catchpoint = inf_child_insert_exec_catchpoint;
+      t->to_remove_exec_catchpoint = inf_child_remove_exec_catchpoint;
+      t->to_can_run = inf_child_can_run;
+      t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
+      t->to_stratum = process_stratum;
+      t->to_has_all_memory = default_child_has_all_memory;
+      t->to_has_memory = default_child_has_memory;
+      t->to_has_stack = default_child_has_stack;
+      t->to_has_registers = default_child_has_registers;
+      t->to_has_execution = default_child_has_execution;
+      t->to_magic = OPS_MAGIC;
+    }
   return t;
 }
index 89a37a6db9bf8d5d4c77547452f994111fa56a5b..fec36be7e4f523ea98f0e8d5163ae38ea5084f5a 100644 (file)
@@ -606,26 +606,30 @@ inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
 struct target_ops *
 inf_ptrace_target (void)
 {
-  struct target_ops *t = inf_child_target ();
-
-  t->to_attach = inf_ptrace_attach;
-  t->to_detach = inf_ptrace_detach;
-  t->to_resume = inf_ptrace_resume;
-  t->to_wait = inf_ptrace_wait;
-  t->to_files_info = inf_ptrace_files_info;
-  t->to_kill = inf_ptrace_kill;
-  t->to_create_inferior = inf_ptrace_create_inferior;
+  static struct target_ops *t;
+
+  if (t == NULL)       /* Actually init only once.  */
+    {
+      t = inf_child_target ();
+
+      t->to_attach = inf_ptrace_attach;
+      t->to_detach = inf_ptrace_detach;
+      t->to_resume = inf_ptrace_resume;
+      t->to_wait = inf_ptrace_wait;
+      t->to_files_info = inf_ptrace_files_info;
+      t->to_kill = inf_ptrace_kill;
+      t->to_create_inferior = inf_ptrace_create_inferior;
 #ifdef PT_GET_PROCESS_STATE
-  t->to_follow_fork = inf_ptrace_follow_fork;
-  t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
-  t->to_post_attach = inf_ptrace_post_attach;
+      t->to_follow_fork = inf_ptrace_follow_fork;
+      t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
+      t->to_post_attach = inf_ptrace_post_attach;
 #endif
-  t->to_mourn_inferior = inf_ptrace_mourn_inferior;
-  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_xfer_partial = inf_ptrace_xfer_partial;
-
+      t->to_mourn_inferior = inf_ptrace_mourn_inferior;
+      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_xfer_partial = inf_ptrace_xfer_partial;
+    }
   return t;
 }
 \f
@@ -759,14 +763,17 @@ inf_ptrace_store_registers (struct target_ops *ops,
 
 struct target_ops *
 inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)
-                                       (struct gdbarch *, int, int))
+                       (struct gdbarch *, int, int))
 {
-  struct target_ops *t = inf_ptrace_target();
-
-  gdb_assert (register_u_offset);
-  inf_ptrace_register_u_offset = register_u_offset;
-  t->to_fetch_registers = inf_ptrace_fetch_registers;
-  t->to_store_registers = inf_ptrace_store_registers;
+  static struct target_ops *t;
 
+  if (t == NULL)
+    {
+      t = inf_ptrace_target();
+      gdb_assert (register_u_offset);
+      inf_ptrace_register_u_offset = register_u_offset;
+      t->to_fetch_registers = inf_ptrace_fetch_registers;
+      t->to_store_registers = inf_ptrace_store_registers;
+    }
   return t;
 }
index 35ca389867efba605c8b7cd5b9a27fc56bcdadf7..fb7c6b4d3f56c64ea757b653773d0d866e8a1c08 100644 (file)
@@ -28,6 +28,7 @@
 #include "gdb_string.h"
 #include "linux-fork.h"
 #include "linux-nat.h"
+#include "checkpoint.h"
 
 #include <sys/ptrace.h>
 #include "gdb_wait.h"
@@ -334,8 +335,10 @@ linux_fork_killall (void)
     {
       pid = PIDGET (fp->ptid);
       do {
-       /* Use SIGKILL instead of PTRACE_KILL because the former works even
-          if the thread is running, while the later doesn't.  */
+       /* Use SIGKILL instead of PTRACE_KILL because the former works
+          even if the thread is running, while the later doesn't.  */
+       if (info_verbose)
+         printf_filtered (_("Killing checkpoint/fork %d.\n"), pid);
        kill (pid, SIGKILL);
        ret = waitpid (pid, &status, 0);
        /* We might get a SIGCHLD instead of an exit status.  This is
@@ -414,6 +417,9 @@ linux_fork_detach (char *args, int from_tty)
 
 /* Fork list <-> user interface.  */
 
+/* Delete checkpoint command: kill the process and remove it from
+   the fork list.  */
+
 static void
 delete_checkpoint_command (char *args, int from_tty)
 {
@@ -464,7 +470,8 @@ Please switch to another checkpoint before detaching the current one"));
   delete_fork (ptid);
 }
 
-/* Print information about currently known checkpoints.  */
+/* Info checkpoints command: list all forks/checkpoints
+   currently under gdb's control.  */
 
 static void
 info_checkpoints_command (char *arg, int from_tty)
@@ -545,6 +552,9 @@ linux_fork_checkpointing_p (int pid)
   return (checkpointing_pid == pid);
 }
 
+/* checkpoint_command: create a fork of the inferior process
+   and set it aside for later debugging.  */
+
 static void
 checkpoint_command (char *args, int from_tty)
 {
@@ -629,6 +639,7 @@ linux_fork_context (struct fork_info *newfp, int from_tty)
 }
 
 /* Switch inferior process (checkpoint) context, by checkpoint id.  */
+
 static void
 restart_command (char *args, int from_tty)
 {
@@ -646,6 +657,8 @@ restart_command (char *args, int from_tty)
 void
 _initialize_linux_fork (void)
 {
+  struct target_ops *t;
+
   init_fork_list ();
 
   /* Set/show detach-on-fork: user-settable mode.  */
@@ -656,26 +669,6 @@ Show whether gdb will detach the child of a fork."), _("\
 Tells gdb whether to detach the child of a fork."),
                           NULL, NULL, &setlist, &showlist);
 
-  /* Checkpoint command: create a fork of the inferior process
-     and set it aside for later debugging.  */
-
-  add_com ("checkpoint", class_obscure, checkpoint_command, _("\
-Fork a duplicate process (experimental)."));
-
-  /* Restart command: restore the context of a specified checkpoint
-     process.  */
-
-  add_com ("restart", class_obscure, restart_command, _("\
-restart <n>: restore program context from a checkpoint.\n\
-Argument 'n' is checkpoint ID, as displayed by 'info checkpoints'."));
-
-  /* Delete checkpoint command: kill the process and remove it from
-     the fork list.  */
-
-  add_cmd ("checkpoint", class_obscure, delete_checkpoint_command, _("\
-Delete a checkpoint (experimental)."),
-          &deletelist);
-
   /* Detach checkpoint command: release the process to run independently,
      and remove it from the fork list.  */
 
@@ -683,9 +676,28 @@ Delete a checkpoint (experimental)."),
 Detach from a checkpoint (experimental)."),
           &detachlist);
 
-  /* Info checkpoints command: list all forks/checkpoints
-     currently under gdb's control.  */
-
-  add_info ("checkpoints", info_checkpoints_command,
-           _("IDs of currently known checkpoints."));
+  /* Get the linux target vector.  */
+  t = linux_target ();
+  /* Add checkpoint target methods.  */
+  t->to_set_checkpoint = checkpoint_command;
+  t->to_unset_checkpoint = delete_checkpoint_command;
+  t->to_restore_checkpoint = restart_command;
+  t->to_info_checkpoints = info_checkpoints_command;
+
+  /* Activate the checkpoint module.  */
+  checkpoint_init ();
+
+  /* XXX mvs call linux_target and add checkpoint methods.  
+         to_set_checkpoint
+         to_unset_checkpoint
+        to_info_checkpoints (maybe this could be common?  Maybe not?
+        to_detach_checkpoint (esoteric?)
+        to_restore_checkpoint.
+
+     Make a new module called checkpoint.c, include it always, but
+     don't make it auto-initialize like most modules.  Instead, 
+     give it a global entry point checkpoint_init, which has to be
+     called explicitly by targets that want to activate the 
+     checkpoint commands.
+  */
 }
index d91c6be5c222b87559ae44fa335137a2f9086e63..6d1cf3a69897b370f356af8277324c289cbcfcc8 100644 (file)
@@ -4306,22 +4306,26 @@ linux_target_install_ops (struct target_ops *t)
 struct target_ops *
 linux_target (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  linux_target_install_ops (t);
+  static struct target_ops *t;
 
+  if (t == NULL)
+    {
+      t = inf_ptrace_target ();
+      linux_target_install_ops (t);
+    }
   return t;
 }
 
 struct target_ops *
 linux_trad_target (CORE_ADDR (*register_u_offset)(struct gdbarch *, int, int))
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_trad_target (register_u_offset);
-  linux_target_install_ops (t);
+  static struct target_ops *t;
 
+  if (t == NULL)
+    {
+      t = inf_ptrace_trad_target (register_u_offset);
+      linux_target_install_ops (t);
+    }
   return t;
 }