aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog42
-rw-r--r--gdb/aix-thread.c14
-rw-r--r--gdb/corelow.c2
-rw-r--r--gdb/exec.c2
-rw-r--r--gdb/inf-child.c13
-rw-r--r--gdb/infcmd.c34
-rw-r--r--gdb/record-btrace.c1
-rw-r--r--gdb/record-full.c19
-rw-r--r--gdb/target-delegates.c42
-rw-r--r--gdb/target.c129
-rw-r--r--gdb/target.h64
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.base/corefile.exp115
-rw-r--r--gdb/testsuite/gdb.reverse/break-precsave.exp115
14 files changed, 325 insertions, 274 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 45c5d65..6085aaa 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,45 @@
+2014-03-12 Tom Tromey <tromey@redhat.com>
+
+ * inf-child.c (return_zero): New function.
+ (inf_child_target): Set to_can_async_p, to_supports_non_stop.
+ * aix-thread.c (aix_thread_inferior_created): New function.
+ (aix_thread_attach): Remove.
+ (init_aix_thread_ops): Don't set to_attach.
+ (_initialize_aix_thread): Register inferior_created observer.
+ * corelow.c (init_core_ops): Don't set to_attach or
+ to_create_inferior.
+ * exec.c (init_exec_ops): Don't set to_attach or
+ to_create_inferior.
+ * infcmd.c (run_command_1): Use find_run_target. Make direct
+ target calls.
+ (attach_command): Use find_attach_target. Make direct target
+ calls.
+ * record-btrace.c (init_record_btrace_ops): Don't set
+ to_create_inferior.
+ * record-full.c (record_full_can_async_p, record_full_is_async_p):
+ Remove.
+ (init_record_full_ops, init_record_full_core_ops): Update. Don't
+ set to_create_inferior.
+ * target.c (complete_target_initialization): Add assertion.
+ (target_create_inferior): Remove.
+ (find_default_attach, find_default_create_inferior): Remove.
+ (find_attach_target, find_run_target): New functions.
+ (find_default_is_async_p, find_default_can_async_p)
+ (target_supports_non_stop, target_attach): Remove.
+ (init_dummy_target): Don't set to_create_inferior or
+ to_supports_non_stop.
+ * target.h (struct target_ops) <to_attach>: Add comment. Remove
+ TARGET_DEFAULT_FUNC.
+ <to_create_inferior>: Add comment.
+ <to_can_async_p, to_is_async_p, to_supports_non_stop>: Use
+ TARGET_DEFAULT_RETURN.
+ <to_can_async_p, to_supports_non_stop, to_can_run>: Add comments.
+ (find_attach_target, find_run_target): Declare.
+ (target_create_inferior): Remove.
+ (target_has_execution_1): Update comment.
+ (target_supports_non_stop): Remove.
+ * target-delegates.c: Rebuild.
+
2014-03-12 Pedro Alves <palves@redhat.com>
* inf-child.h: Update comment to not mention Unix.
diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 444a025..3865cba 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -959,12 +959,9 @@ new_objfile (struct objfile *objfile)
/* Attach to process specified by ARGS. */
static void
-aix_thread_attach (struct target_ops *ops, char *args, int from_tty)
+aix_thread_inferior_created (struct target_ops *ops, int from_tty)
{
- struct target_ops *beneath = find_target_beneath (ops);
-
- beneath->to_attach (beneath, args, from_tty);
- pd_activate (1);
+ pd_enable ();
}
/* Detach from the process attached to by aix_thread_attach(). */
@@ -1823,15 +1820,12 @@ init_aix_thread_ops (void)
aix_thread_ops.to_longname = _("AIX pthread support");
aix_thread_ops.to_doc = _("AIX pthread support");
- aix_thread_ops.to_attach = aix_thread_attach;
aix_thread_ops.to_detach = aix_thread_detach;
aix_thread_ops.to_resume = aix_thread_resume;
aix_thread_ops.to_wait = aix_thread_wait;
aix_thread_ops.to_fetch_registers = aix_thread_fetch_registers;
aix_thread_ops.to_store_registers = aix_thread_store_registers;
aix_thread_ops.to_xfer_partial = aix_thread_xfer_partial;
- /* No need for aix_thread_ops.to_create_inferior, because we activate thread
- debugging when the inferior reaches pd_brk_addr. */
aix_thread_ops.to_mourn_inferior = aix_thread_mourn_inferior;
aix_thread_ops.to_thread_alive = aix_thread_thread_alive;
aix_thread_ops.to_pid_to_str = aix_thread_pid_to_str;
@@ -1855,6 +1849,10 @@ _initialize_aix_thread (void)
/* Notice when object files get loaded and unloaded. */
observer_attach_new_objfile (new_objfile);
+ /* Add ourselves to inferior_created event chain.
+ This is needed to enable the thread target on "attach". */
+ observer_attach_inferior_created (aix_thread_inferior_created);
+
add_setshow_boolean_cmd ("aix-thread", class_maintenance, &debug_aix_thread,
_("Set debugging of AIX thread module."),
_("Show debugging of AIX thread module."),
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 05c3e4e..02caeef 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -999,14 +999,12 @@ init_core_ops (void)
"Use a core file as a target. Specify the filename of the core file.";
core_ops.to_open = core_open;
core_ops.to_close = core_close;
- core_ops.to_attach = find_default_attach;
core_ops.to_detach = core_detach;
core_ops.to_fetch_registers = get_core_registers;
core_ops.to_xfer_partial = core_xfer_partial;
core_ops.to_files_info = core_files_info;
core_ops.to_insert_breakpoint = ignore;
core_ops.to_remove_breakpoint = ignore;
- core_ops.to_create_inferior = find_default_create_inferior;
core_ops.to_thread_alive = core_thread_alive;
core_ops.to_read_description = core_read_description;
core_ops.to_pid_to_str = core_pid_to_str;
diff --git a/gdb/exec.c b/gdb/exec.c
index 908858e..ca59c72 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -959,13 +959,11 @@ init_exec_ops (void)
Specify the filename of the executable file.";
exec_ops.to_open = exec_open;
exec_ops.to_close = exec_close_1;
- exec_ops.to_attach = find_default_attach;
exec_ops.to_xfer_partial = exec_xfer_partial;
exec_ops.to_get_section_table = exec_get_section_table;
exec_ops.to_files_info = exec_files_info;
exec_ops.to_insert_breakpoint = ignore;
exec_ops.to_remove_breakpoint = ignore;
- exec_ops.to_create_inferior = find_default_create_inferior;
exec_ops.to_stratum = file_stratum;
exec_ops.to_has_memory = exec_has_memory;
exec_ops.to_make_corefile_notes = exec_make_note_section;
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index ee63dd1..c6483f9 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -392,6 +392,15 @@ inf_child_can_use_agent (struct target_ops *self)
return agent_loaded_p ();
}
+/* Default implementation of the to_can_async_p and
+ to_supports_non_stop methods. */
+
+static int
+return_zero (struct target_ops *ignore)
+{
+ return 0;
+}
+
struct target_ops *
inf_child_target (void)
{
@@ -416,6 +425,10 @@ inf_child_target (void)
t->to_post_startup_inferior = inf_child_post_startup_inferior;
t->to_follow_fork = inf_child_follow_fork;
t->to_can_run = inf_child_can_run;
+ /* We must default these because they must be implemented by any
+ target that can run. */
+ t->to_can_async_p = return_zero;
+ t->to_supports_non_stop = return_zero;
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;
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index c59d0be..75d37fd 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -503,6 +503,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
struct cleanup *old_chain;
ptid_t ptid;
struct ui_out *uiout = current_uiout;
+ struct target_ops *run_target;
dont_repeat ();
@@ -531,7 +532,9 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
exec_file = (char *) get_exec_file (0);
- if (non_stop && !target_supports_non_stop ())
+ run_target = find_run_target ();
+
+ if (non_stop && !run_target->to_supports_non_stop (run_target))
error (_("The target does not support running in non-stop mode."));
/* We keep symbols from add-symbol-file, on the grounds that the
@@ -544,7 +547,7 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
if (!args)
{
- if (target_can_async_p ())
+ if (run_target->to_can_async_p (run_target))
async_disable_stdin ();
}
else
@@ -553,12 +556,12 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
/* If we get a request for running in the bg but the target
doesn't support it, error out. */
- if (async_exec && !target_can_async_p ())
+ if (async_exec && !run_target->to_can_async_p (run_target))
error (_("Asynchronous execution not supported on this target."));
/* If we don't get a request of running in the bg, then we need
to simulate synchronous (fg) execution. */
- if (!async_exec && target_can_async_p ())
+ if (!async_exec && run_target->to_can_async_p (run_target))
{
/* Simulate synchronous execution. */
async_disable_stdin ();
@@ -585,9 +588,12 @@ run_command_1 (char *args, int from_tty, int tbreak_at_main)
/* We call get_inferior_args() because we might need to compute
the value now. */
- target_create_inferior (exec_file, get_inferior_args (),
- environ_vector (current_inferior ()->environment),
- from_tty);
+ run_target->to_create_inferior (run_target, exec_file, get_inferior_args (),
+ environ_vector (current_inferior ()->environment),
+ from_tty);
+ /* to_create_inferior should push the target, so after this point we
+ shouldn't refer to run_target again. */
+ run_target = NULL;
/* We're starting off a new process. When we get out of here, in
non-stop mode, finish the state of all threads of that process,
@@ -2515,6 +2521,7 @@ attach_command (char *args, int from_tty)
{
int async_exec = 0;
struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+ struct target_ops *attach_target;
dont_repeat (); /* Not for the faint of heart */
@@ -2534,7 +2541,9 @@ attach_command (char *args, int from_tty)
this function should probably be moved into target_pre_inferior. */
target_pre_inferior (from_tty);
- if (non_stop && !target_supports_non_stop ())
+ attach_target = find_attach_target ();
+
+ if (non_stop && !attach_target->to_supports_non_stop (attach_target))
error (_("Cannot attach to this target in non-stop mode"));
if (args)
@@ -2543,20 +2552,23 @@ attach_command (char *args, int from_tty)
/* If we get a request for running in the bg but the target
doesn't support it, error out. */
- if (async_exec && !target_can_async_p ())
+ if (async_exec && !attach_target->to_can_async_p (attach_target))
error (_("Asynchronous execution not supported on this target."));
}
/* If we don't get a request of running in the bg, then we need
to simulate synchronous (fg) execution. */
- if (!async_exec && target_can_async_p ())
+ if (!async_exec && attach_target->to_can_async_p (attach_target))
{
/* Simulate synchronous execution. */
async_disable_stdin ();
make_cleanup ((make_cleanup_ftype *)async_enable_stdin, NULL);
}
- target_attach (args, from_tty);
+ attach_target->to_attach (attach_target, args, from_tty);
+ /* to_attach should push the target, so after this point we
+ shouldn't refer to attach_target again. */
+ attach_target = NULL;
/* Set up the "saved terminal modes" of the inferior
based on what modes we are starting it with. */
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index d4c0d42..bcac165 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1893,7 +1893,6 @@ init_record_btrace_ops (void)
ops->to_disconnect = record_disconnect;
ops->to_mourn_inferior = record_mourn_inferior;
ops->to_kill = record_kill;
- ops->to_create_inferior = find_default_create_inferior;
ops->to_stop_recording = record_btrace_stop_recording;
ops->to_info_record = record_btrace_info;
ops->to_insn_history = record_btrace_insn_history;
diff --git a/gdb/record-full.c b/gdb/record-full.c
index d35165b..39db910 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -1750,20 +1750,6 @@ record_full_goto_bookmark (struct target_ops *self,
return;
}
-static int
-record_full_can_async_p (struct target_ops *ops)
-{
- /* We only enable async when the user specifically asks for it. */
- return target_async_permitted;
-}
-
-static int
-record_full_is_async_p (struct target_ops *ops)
-{
- /* We only enable async when the user specifically asks for it. */
- return target_async_permitted;
-}
-
static enum exec_direction_kind
record_full_execution_direction (struct target_ops *self)
{
@@ -1916,7 +1902,6 @@ init_record_full_ops (void)
record_full_ops.to_detach = record_detach;
record_full_ops.to_mourn_inferior = record_mourn_inferior;
record_full_ops.to_kill = record_kill;
- record_full_ops.to_create_inferior = find_default_create_inferior;
record_full_ops.to_store_registers = record_full_store_registers;
record_full_ops.to_xfer_partial = record_full_xfer_partial;
record_full_ops.to_insert_breakpoint = record_full_insert_breakpoint;
@@ -1928,8 +1913,6 @@ init_record_full_ops (void)
/* Add bookmark target methods. */
record_full_ops.to_get_bookmark = record_full_get_bookmark;
record_full_ops.to_goto_bookmark = record_full_goto_bookmark;
- record_full_ops.to_can_async_p = record_full_can_async_p;
- record_full_ops.to_is_async_p = record_full_is_async_p;
record_full_ops.to_execution_direction = record_full_execution_direction;
record_full_ops.to_info_record = record_full_info;
record_full_ops.to_save_record = record_full_save;
@@ -2174,8 +2157,6 @@ init_record_full_core_ops (void)
/* Add bookmark target methods. */
record_full_core_ops.to_get_bookmark = record_full_get_bookmark;
record_full_core_ops.to_goto_bookmark = record_full_goto_bookmark;
- record_full_core_ops.to_can_async_p = record_full_can_async_p;
- record_full_core_ops.to_is_async_p = record_full_is_async_p;
record_full_core_ops.to_execution_direction
= record_full_execution_direction;
record_full_core_ops.to_info_record = record_full_info;
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index 3ca24b7..87ce0d1 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -4,13 +4,6 @@
/* To regenerate this file, run:*/
/* make-target-delegates target.h > target-delegates.c */
static void
-delegate_attach (struct target_ops *self, char *arg1, int arg2)
-{
- self = self->beneath;
- self->to_attach (self, arg1, arg2);
-}
-
-static void
delegate_post_attach (struct target_ops *self, int arg1)
{
self = self->beneath;
@@ -690,12 +683,24 @@ delegate_can_async_p (struct target_ops *self)
}
static int
+tdefault_can_async_p (struct target_ops *self)
+{
+ return 0;
+}
+
+static int
delegate_is_async_p (struct target_ops *self)
{
self = self->beneath;
return self->to_is_async_p (self);
}
+static int
+tdefault_is_async_p (struct target_ops *self)
+{
+ return 0;
+}
+
static void
delegate_async (struct target_ops *self, async_callback_ftype *arg1, void *arg2)
{
@@ -710,6 +715,19 @@ tdefault_async (struct target_ops *self, async_callback_ftype *arg1, void *arg2)
}
static int
+delegate_supports_non_stop (struct target_ops *self)
+{
+ self = self->beneath;
+ return self->to_supports_non_stop (self);
+}
+
+static int
+tdefault_supports_non_stop (struct target_ops *self)
+{
+ return 0;
+}
+
+static int
delegate_find_memory_regions (struct target_ops *self, find_memory_region_ftype arg1, void *arg2)
{
self = self->beneath;
@@ -1608,8 +1626,6 @@ delegate_decr_pc_after_break (struct target_ops *self, struct gdbarch *arg1)
static void
install_delegators (struct target_ops *ops)
{
- if (ops->to_attach == NULL)
- ops->to_attach = delegate_attach;
if (ops->to_post_attach == NULL)
ops->to_post_attach = delegate_post_attach;
if (ops->to_detach == NULL)
@@ -1730,6 +1746,8 @@ install_delegators (struct target_ops *ops)
ops->to_is_async_p = delegate_is_async_p;
if (ops->to_async == NULL)
ops->to_async = delegate_async;
+ if (ops->to_supports_non_stop == NULL)
+ ops->to_supports_non_stop = delegate_supports_non_stop;
if (ops->to_find_memory_regions == NULL)
ops->to_find_memory_regions = delegate_find_memory_regions;
if (ops->to_make_corefile_notes == NULL)
@@ -1881,7 +1899,6 @@ install_delegators (struct target_ops *ops)
static void
install_dummy_methods (struct target_ops *ops)
{
- ops->to_attach = find_default_attach;
ops->to_post_attach = tdefault_post_attach;
ops->to_detach = tdefault_detach;
ops->to_disconnect = tdefault_disconnect;
@@ -1939,9 +1956,10 @@ install_dummy_methods (struct target_ops *ops)
ops->to_pid_to_exec_file = tdefault_pid_to_exec_file;
ops->to_log_command = tdefault_log_command;
ops->to_get_section_table = tdefault_get_section_table;
- ops->to_can_async_p = find_default_can_async_p;
- ops->to_is_async_p = find_default_is_async_p;
+ ops->to_can_async_p = tdefault_can_async_p;
+ ops->to_is_async_p = tdefault_is_async_p;
ops->to_async = tdefault_async;
+ ops->to_supports_non_stop = tdefault_supports_non_stop;
ops->to_find_memory_regions = dummy_find_memory_regions;
ops->to_make_corefile_notes = dummy_make_corefile_notes;
ops->to_get_bookmark = tdefault_get_bookmark;
diff --git a/gdb/target.c b/gdb/target.c
index f7868c0..0d22297 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -95,10 +95,6 @@ static char *dummy_make_corefile_notes (struct target_ops *self,
static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
-static int find_default_can_async_p (struct target_ops *ignore);
-
-static int find_default_is_async_p (struct target_ops *ignore);
-
static enum exec_direction_kind default_execution_direction
(struct target_ops *self);
@@ -387,6 +383,12 @@ complete_target_initialization (struct target_ops *t)
if (t->to_has_execution == NULL)
t->to_has_execution = return_zero_has_execution;
+ /* These methods can be called on an unpushed target and so require
+ a default implementation if the target might plausibly be the
+ default run target. */
+ gdb_assert (t->to_can_run == NULL || (t->to_can_async_p != NULL
+ && t->to_supports_non_stop != NULL));
+
install_delegators (t);
}
@@ -473,29 +475,6 @@ target_load (char *arg, int from_tty)
}
void
-target_create_inferior (char *exec_file, char *args,
- char **env, int from_tty)
-{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_create_inferior != NULL)
- {
- t->to_create_inferior (t, exec_file, args, env, from_tty);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_create_inferior (%s, %s, xxx, %d)\n",
- exec_file, args, from_tty);
- return;
- }
- }
-
- internal_error (__FILE__, __LINE__,
- _("could not find a target to create inferior"));
-}
-
-void
target_terminal_inferior (void)
{
/* A background resume (``run&'') should leave GDB in control of the
@@ -2632,79 +2611,46 @@ find_default_run_target (char *do_mesg)
return runable;
}
-void
-find_default_attach (struct target_ops *ops, char *args, int from_tty)
-{
- struct target_ops *t;
-
- t = find_default_run_target ("attach");
- (t->to_attach) (t, args, from_tty);
- return;
-}
+/* See target.h. */
-void
-find_default_create_inferior (struct target_ops *ops,
- char *exec_file, char *allargs, char **env,
- int from_tty)
+struct target_ops *
+find_attach_target (void)
{
struct target_ops *t;
- t = find_default_run_target ("run");
- (t->to_create_inferior) (t, exec_file, allargs, env, from_tty);
- return;
-}
+ /* If a target on the current stack can attach, use it. */
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_attach != NULL)
+ break;
+ }
-static int
-find_default_can_async_p (struct target_ops *ignore)
-{
- struct target_ops *t;
+ /* Otherwise, use the default run target for attaching. */
+ if (t == NULL)
+ t = find_default_run_target ("attach");
- /* This may be called before the target is pushed on the stack;
- look for the default process stratum. If there's none, gdb isn't
- configured with a native debugger, and target remote isn't
- connected yet. */
- t = find_default_run_target (NULL);
- if (t && t->to_can_async_p != delegate_can_async_p)
- return (t->to_can_async_p) (t);
- return 0;
+ return t;
}
-static int
-find_default_is_async_p (struct target_ops *ignore)
-{
- struct target_ops *t;
-
- /* This may be called before the target is pushed on the stack;
- look for the default process stratum. If there's none, gdb isn't
- configured with a native debugger, and target remote isn't
- connected yet. */
- t = find_default_run_target (NULL);
- if (t && t->to_is_async_p != delegate_is_async_p)
- return (t->to_is_async_p) (t);
- return 0;
-}
+/* See target.h. */
-static int
-find_default_supports_non_stop (struct target_ops *self)
+struct target_ops *
+find_run_target (void)
{
struct target_ops *t;
- t = find_default_run_target (NULL);
- if (t && t->to_supports_non_stop)
- return (t->to_supports_non_stop) (t);
- return 0;
-}
-
-int
-target_supports_non_stop (void)
-{
- struct target_ops *t;
+ /* If a target on the current stack can attach, use it. */
+ for (t = current_target.beneath; t != NULL; t = t->beneath)
+ {
+ if (t->to_create_inferior != NULL)
+ break;
+ }
- for (t = &current_target; t != NULL; t = t->beneath)
- if (t->to_supports_non_stop)
- return t->to_supports_non_stop (t);
+ /* Otherwise, use the default run target. */
+ if (t == NULL)
+ t = find_default_run_target ("run");
- return 0;
+ return t;
}
/* Implement the "info proc" command. */
@@ -3256,8 +3202,6 @@ init_dummy_target (void)
dummy_target.to_shortname = "None";
dummy_target.to_longname = "None";
dummy_target.to_doc = "";
- dummy_target.to_create_inferior = find_default_create_inferior;
- dummy_target.to_supports_non_stop = find_default_supports_non_stop;
dummy_target.to_supports_disable_randomization
= find_default_supports_disable_randomization;
dummy_target.to_stratum = dummy_stratum;
@@ -3293,15 +3237,6 @@ target_close (struct target_ops *targ)
fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
}
-void
-target_attach (char *args, int from_tty)
-{
- current_target.to_attach (&current_target, args, from_tty);
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog, "target_attach (%s, %d)\n",
- args, from_tty);
-}
-
int
target_thread_alive (ptid_t ptid)
{
diff --git a/gdb/target.h b/gdb/target.h
index 0d4e5ff..d7c6c3d 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -401,8 +401,15 @@ struct target_ops
to xfree everything (including the "struct target_ops"). */
void (*to_xclose) (struct target_ops *targ);
void (*to_close) (struct target_ops *);
- void (*to_attach) (struct target_ops *ops, char *, int)
- TARGET_DEFAULT_FUNC (find_default_attach);
+ /* Attaches to a process on the target side. Arguments are as
+ passed to the `attach' command by the user. This routine can
+ be called when the target is not on the target-stack, if the
+ target_can_run routine returns 1; in that case, it must push
+ itself onto the stack. Upon exit, the target should be ready
+ for normal operations, and should be ready to deliver the
+ status of the process immediately (without waiting) to an
+ upcoming target_wait call. */
+ void (*to_attach) (struct target_ops *ops, char *, int);
void (*to_post_attach) (struct target_ops *, int)
TARGET_DEFAULT_IGNORE ();
void (*to_detach) (struct target_ops *ops, const char *, int)
@@ -494,6 +501,11 @@ struct target_ops
TARGET_DEFAULT_NORETURN (noprocess ());
void (*to_load) (struct target_ops *, char *, int)
TARGET_DEFAULT_NORETURN (tcomplain ());
+ /* Start an inferior process and set inferior_ptid to its pid.
+ EXEC_FILE is the file to run.
+ ALLARGS is a string containing the arguments to the program.
+ ENV is the environment vector to pass. Errors reported with error().
+ On VxWorks and various standalone systems, we ignore exec_file. */
void (*to_create_inferior) (struct target_ops *,
char *, char *, char **, int);
void (*to_post_startup_inferior) (struct target_ops *, ptid_t)
@@ -519,6 +531,9 @@ struct target_ops
TARGET_DEFAULT_RETURN (0);
void (*to_mourn_inferior) (struct target_ops *)
TARGET_DEFAULT_FUNC (default_mourn_inferior);
+ /* Note that to_can_run is special and can be invoked on an
+ unpushed target. Targets defining this method must also define
+ to_can_async_p and to_supports_non_stop. */
int (*to_can_run) (struct target_ops *)
TARGET_DEFAULT_RETURN (0);
@@ -561,14 +576,18 @@ struct target_ops
int (*to_has_execution) (struct target_ops *, ptid_t);
int to_has_thread_control; /* control thread execution */
int to_attach_no_wait;
- /* ASYNC target controls */
+ /* This method must be implemented in some situations. See the
+ comment on 'to_can_run'. */
int (*to_can_async_p) (struct target_ops *)
- TARGET_DEFAULT_FUNC (find_default_can_async_p);
+ TARGET_DEFAULT_RETURN (0);
int (*to_is_async_p) (struct target_ops *)
- TARGET_DEFAULT_FUNC (find_default_is_async_p);
+ TARGET_DEFAULT_RETURN (0);
void (*to_async) (struct target_ops *, async_callback_ftype *, void *)
TARGET_DEFAULT_NORETURN (tcomplain ());
- int (*to_supports_non_stop) (struct target_ops *);
+ /* This method must be implemented in some situations. See the
+ comment on 'to_can_run'. */
+ int (*to_supports_non_stop) (struct target_ops *)
+ TARGET_DEFAULT_RETURN (0);
/* find_memory_regions support method for gcore */
int (*to_find_memory_regions) (struct target_ops *,
find_memory_region_ftype func, void *data)
@@ -1117,15 +1136,17 @@ extern struct target_ops current_target;
void target_close (struct target_ops *targ);
-/* Attaches to a process on the target side. Arguments are as passed
- to the `attach' command by the user. This routine can be called
- when the target is not on the target-stack, if the target_can_run
- routine returns 1; in that case, it must push itself onto the stack.
- Upon exit, the target should be ready for normal operations, and
- should be ready to deliver the status of the process immediately
- (without waiting) to an upcoming target_wait call. */
+/* Find the correct target to use for "attach". If a target on the
+ current stack supports attaching, then it is returned. Otherwise,
+ the default run target is returned. */
+
+extern struct target_ops *find_attach_target (void);
-void target_attach (char *, int);
+/* Find the correct target to use for "run". If a target on the
+ current stack supports creating a new inferior, then it is
+ returned. Otherwise, the default run target is returned. */
+
+extern struct target_ops *find_run_target (void);
/* Some targets don't generate traps when attaching to the inferior,
or their target_attach implementation takes care of the waiting.
@@ -1393,15 +1414,6 @@ extern void target_kill (void);
extern void target_load (char *arg, int from_tty);
-/* Start an inferior process and set inferior_ptid to its pid.
- EXEC_FILE is the file to run.
- ALLARGS is a string containing the arguments to the program.
- ENV is the environment vector to pass. Errors reported with error().
- On VxWorks and various standalone systems, we ignore exec_file. */
-
-void target_create_inferior (char *exec_file, char *args,
- char **env, int from_tty);
-
/* Some targets (such as ttrace-based HPUX) don't allow us to request
notification of inferior events such as fork and vork immediately
after the inferior is created. (This because of how gdb gets an
@@ -1579,8 +1591,8 @@ extern int target_has_registers_1 (void);
target is currently executing; for some targets, that's the same as
whether or not the target is capable of execution, but there are
also targets which can be current while not executing. In that
- case this will become true after target_create_inferior or
- target_attach. */
+ case this will become true after to_create_inferior or
+ to_attach. */
extern int target_has_execution_1 (ptid_t);
@@ -1616,8 +1628,6 @@ extern int target_async_permitted;
/* Is the target in asynchronous execution mode? */
#define target_is_async_p() (current_target.to_is_async_p (&current_target))
-int target_supports_non_stop (void);
-
/* Put the target in async mode with the specified callback function. */
#define target_async(CALLBACK,CONTEXT) \
(current_target.to_async (&current_target, (CALLBACK), (CONTEXT)))
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 56275a3..5180a25 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2014-03-12 Tom Tromey <tromey@redhat.com>
+
+ * gdb.base/corefile.exp (corefile_test_run, corefile_test_attach):
+ New procs. Add target-async tests.
+ * gdb.reverse/break-precsave.exp (precsave_tests): New proc.
+ Add target-async tests.
+
2014-03-12 Andreas Arnez <arnez@linux.vnet.ibm.com>
* gdb.dwarf2/dw2-ifort-parameter.c (func): Define labels
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
index 61c13c4..6eb1f02 100644
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -185,35 +185,41 @@ gdb_test "core" "No core file now."
# Test a run (start) command will clear any loaded core file.
-gdb_test "core-file $corefile" "Core was generated by .*" "run: load core again"
-gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "run: sanity check we see the core file"
-
-set test "run: with core"
-if [runto_main] {
- pass $test
-} else {
- fail $test
-}
+proc corefile_test_run {} {
+ global corefile gdb_prompt
+
+ gdb_test "core-file $corefile" "Core was generated by .*" "run: load core again"
+ gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "run: sanity check we see the core file"
-set test "run: core file is cleared"
-gdb_test_multiple "info files" $test {
- -re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
+ set test "run: with core"
+ if [runto_main] {
+ pass $test
+ } else {
fail $test
}
- -re "\r\n$gdb_prompt $" {
- pass $test
+
+ set test "run: core file is cleared"
+ gdb_test_multiple "info files" $test {
+ -re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
+ fail $test
+ }
+ -re "\r\n$gdb_prompt $" {
+ pass $test
+ }
}
-}
-set test "quit with a process"
-gdb_test_multiple "quit" $test {
- -re "A debugging session is active.\r\n.*\r\nQuit anyway\\? \\(y or n\\) $" {
- pass $test
- gdb_test "n" {Not confirmed\.} "quit with processes: n"
+ set test "quit with a process"
+ gdb_test_multiple "quit" $test {
+ -re "A debugging session is active.\r\n.*\r\nQuit anyway\\? \\(y or n\\) $" {
+ pass $test
+ gdb_test "n" {Not confirmed\.} "quit with processes: n"
+ }
}
+
+ gdb_exit
}
-gdb_exit
+corefile_test_run
# Verify there is no question if only a core file is loaded.
@@ -235,37 +241,48 @@ gdb_exit
# Test an attach command will clear any loaded core file.
-if ![is_remote target] {
- set test "attach: spawn sleep"
- set res [remote_spawn host "$binfile sleep"]
- if { $res < 0 || $res == "" } {
- fail $test
- return
- }
- set pid [exp_pid -i $res]
- # We don't care whether the program is still in the startup phase when we
- # attach.
-
- gdb_start
+proc corefile_test_attach {{async 0}} {
+ global binfile corefile gdb_prompt
- gdb_test "core-file $corefile" "Core was generated by .*" "attach: load core again"
- gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "attach: sanity check we see the core file"
+ if ![is_remote target] {
+ set test "attach: spawn sleep"
+ set res [remote_spawn host "$binfile sleep"]
+ if { $res < 0 || $res == "" } {
+ fail $test
+ return
+ }
+ set pid [exp_pid -i $res]
+ # We don't care whether the program is still in the startup phase when we
+ # attach.
- gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach: with core"
+ gdb_start
- set test "attach: core file is cleared"
- gdb_test_multiple "info files" $test {
- -re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
- fail $test
+ if {$async} {
+ gdb_test_no_output "set target-async on" \
+ "enable target-async for attach tests"
}
- -re "\r\n$gdb_prompt $" {
- pass $test
+
+ gdb_test "core-file $corefile" "Core was generated by .*" "attach: load core again"
+ gdb_test "info files" "\r\nLocal core dump file:\r\n.*" "attach: sanity check we see the core file"
+
+ gdb_test "attach $pid" "Attaching to process $pid\r\n.*" "attach: with core"
+
+ set test "attach: core file is cleared"
+ gdb_test_multiple "info files" $test {
+ -re "\r\nLocal core dump file:\r\n.*\r\n$gdb_prompt $" {
+ fail $test
+ }
+ -re "\r\n$gdb_prompt $" {
+ pass $test
+ }
}
- }
- gdb_exit
+ gdb_exit
+ }
}
+corefile_test_attach
+
# Test warning-free core file load. E.g., a Linux vDSO used to
# trigger this warning:
# warning: Can't read pathname for load map: Input/output error.
@@ -281,3 +298,13 @@ gdb_test_multiple "core-file $corefile" $test {
pass $test
}
}
+
+
+# Try a couple tests again with target-async.
+with_test_prefix "target-async" {
+ clean_restart ${testfile}
+
+ gdb_test_no_output "set target-async on"
+ corefile_test_run
+ corefile_test_attach 1
+}
diff --git a/gdb/testsuite/gdb.reverse/break-precsave.exp b/gdb/testsuite/gdb.reverse/break-precsave.exp
index cc05d43..f1e6c69 100644
--- a/gdb/testsuite/gdb.reverse/break-precsave.exp
+++ b/gdb/testsuite/gdb.reverse/break-precsave.exp
@@ -33,73 +33,86 @@ set bar_location [gdb_get_line_number "break in bar" ]
set main_location [gdb_get_line_number "break in main"]
set end_location [gdb_get_line_number "end of main" ]
-runto main
+proc precsave_tests {} {
+ global foo_location bar_location main_location end_location
+ global decimal srcfile precsave gdb_prompt
-if [supports_process_record] {
- # Activate process record/replay
- gdb_test_no_output "record" "Turn on process record"
-}
+ runto main
-gdb_test "break $end_location" \
- "Breakpoint $decimal at .*/$srcfile, line $end_location\." \
- "BP at end of main"
+ if [supports_process_record] {
+ # Activate process record/replay
+ gdb_test_no_output "record" "Turn on process record"
+ }
-gdb_test "continue" "Breakpoint .* end of main .*" "run to end of main"
+ gdb_test "break $end_location" \
+ "Breakpoint $decimal at .*/$srcfile, line $end_location\." \
+ "BP at end of main"
-gdb_test "record save $precsave" \
- "Saved core file $precsave with execution log\." \
- "save process recfile"
+ gdb_test "continue" "Breakpoint .* end of main .*" "run to end of main"
-gdb_test "kill" "" "Kill process, prepare to debug log file" \
- "Kill the program being debugged\\? \\(y or n\\) " "y"
+ gdb_test "record save $precsave" \
+ "Saved core file $precsave with execution log\." \
+ "save process recfile"
-gdb_test "record restore $precsave" \
- "Program terminated with signal .*" \
- "reload precord save file"
+ gdb_test "kill" "" "Kill process, prepare to debug log file" \
+ "Kill the program being debugged\\? \\(y or n\\) " "y"
-gdb_test "break foo" \
- "Breakpoint $decimal at .* line $foo_location\." \
- "set breakpoint on foo"
+ gdb_test "record restore $precsave" \
+ "Program terminated with signal .*" \
+ "reload precord save file"
-gdb_test "break bar" \
- "Breakpoint $decimal at .* line $bar_location\." \
- "set breakpoint on bar"
+ gdb_test "break foo" \
+ "Breakpoint $decimal at .* line $foo_location\." \
+ "set breakpoint on foo"
-gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
-gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
-gdb_test_multiple "continue" "go to end of main forward" {
- -re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $" {
- pass "go to end of main forward"
- }
- -re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
- pass "go to end of main forward"
+ gdb_test "break bar" \
+ "Breakpoint $decimal at .* line $bar_location\." \
+ "set breakpoint on bar"
+
+ gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
+ gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
+ gdb_test_multiple "continue" "go to end of main forward" {
+ -re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $" {
+ pass "go to end of main forward"
+ }
+ -re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
+ pass "go to end of main forward"
+ }
}
-}
-gdb_test_no_output "set exec-direction reverse" "set reverse"
+ gdb_test_no_output "set exec-direction reverse" "set reverse"
-gdb_continue_to_breakpoint "bar backward" ".*/$srcfile:$bar_location.*"
-gdb_continue_to_breakpoint "foo backward" ".*/$srcfile:$foo_location.*"
+ gdb_continue_to_breakpoint "bar backward" ".*/$srcfile:$bar_location.*"
+ gdb_continue_to_breakpoint "foo backward" ".*/$srcfile:$foo_location.*"
-gdb_test_multiple "continue" "main backward" {
- -re ".*Breakpoint $decimal,.*/$srcfile:$main_location.*$gdb_prompt $" {
- pass "main backward"
- }
- -re "No more reverse-execution history.* break in main .*$gdb_prompt $" {
- pass "main backward"
+ gdb_test_multiple "continue" "main backward" {
+ -re ".*Breakpoint $decimal,.*/$srcfile:$main_location.*$gdb_prompt $" {
+ pass "main backward"
+ }
+ -re "No more reverse-execution history.* break in main .*$gdb_prompt $" {
+ pass "main backward"
+ }
}
-}
-gdb_test_no_output "set exec-direction forward" "set forward"
+ gdb_test_no_output "set exec-direction forward" "set forward"
-gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
-gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
+ gdb_continue_to_breakpoint "foo" ".*/$srcfile:$foo_location.*"
+ gdb_continue_to_breakpoint "bar" ".*/$srcfile:$bar_location.*"
-gdb_test_multiple "continue" "end of record log" {
- -re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $" {
- pass "end of record log"
- }
- -re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
- pass "end of record log"
+ gdb_test_multiple "continue" "end of record log" {
+ -re ".*Breakpoint $decimal,.*/$srcfile:$end_location.*$gdb_prompt $" {
+ pass "end of record log"
+ }
+ -re "No more reverse-execution history.* end of main .*$gdb_prompt $" {
+ pass "end of record log"
+ }
}
}
+
+precsave_tests
+
+with_test_prefix "target-async" {
+ clean_restart $testfile
+ gdb_test_no_output "set target-async on"
+ precsave_tests
+}