From: Michael Snyder Date: Sun, 26 Jul 2009 01:44:32 +0000 (+0000) Subject: 2009-07-25 Michael Snyder X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=74ed219893ce5c02b87860b2e979db03c9afba7c;p=thirdparty%2Fbinutils-gdb.git 2009-07-25 Michael Snyder * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0bf1d40d696..8b4a67bb44e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2009-07-25 Michael Snyder + + * 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 * checkpoint.c: New file, target-agnostic checkpoints. diff --git a/gdb/inf-child.c b/gdb/inf-child.c index 2ac702702a8..9dfdc8ed359 100644 --- a/gdb/inf-child.c +++ b/gdb/inf-child.c @@ -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; } diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c index 89a37a6db9b..fec36be7e4f 100644 --- a/gdb/inf-ptrace.c +++ b/gdb/inf-ptrace.c @@ -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; } @@ -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; } diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index 35ca389867e..fb7c6b4d3f5 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -28,6 +28,7 @@ #include "gdb_string.h" #include "linux-fork.h" #include "linux-nat.h" +#include "checkpoint.h" #include #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 : 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. + */ } diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index d91c6be5c22..6d1cf3a6989 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -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; }