diff options
author | Pedro Alves <palves@redhat.com> | 2015-08-07 17:24:01 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-08-07 17:24:01 +0100 |
commit | fbea99ea8a062e5cd96e2d88336984ed3adc93d4 (patch) | |
tree | 8ddafd610809df1cec1e2aa60f0fabd4dbdf791e /gdb/target-delegates.c | |
parent | 372316f12874a30c62e6d71079ca3b86c786fb7e (diff) | |
download | gdb-fbea99ea8a062e5cd96e2d88336984ed3adc93d4.zip gdb-fbea99ea8a062e5cd96e2d88336984ed3adc93d4.tar.gz gdb-fbea99ea8a062e5cd96e2d88336984ed3adc93d4.tar.bz2 |
Implement all-stop on top of a target running non-stop mode
This finally implements user-visible all-stop mode running with the
target_ops backend always in non-stop mode. This is a stepping stone
towards finer-grained control of threads, being able to do interesting
things like thread groups, associating groups with breakpoints, etc.
From the user's perspective, all-stop mode is really just a special
case of being able to stop and resume specific sets of threads, so it
makes sense to do this step first.
With this, even in all-stop, the target is no longer in charge of
stopping all threads before reporting an event to the core -- the core
takes care of it when it sees fit. For example, when "next"- or
"step"-ing, we can avoid stopping and resuming all threads at each
internal single-step, and instead only stop all threads when we're
about to present the stop to the user.
The implementation is almost straight forward, as the heavy lifting
has been done already in previous patches. Basically, we replace
checks for "set non-stop on/off" (the non_stop global), with calls to
a new target_is_non_stop_p function. In a few places, if "set
non-stop off", we stop all threads explicitly, and in a few other
places we resume all threads explicitly, making use of existing
methods that were added for teaching non-stop to step over breakpoints
without displaced stepping.
This adds a new "maint set target-non-stop on/off/auto" knob that
allows both disabling the feature if we find problems, and
force-enable it for development (useful when teaching a target about
this. The default is "auto", which means the feature is enabled if a
new target method says it should be enabled. The patch implements the
method in linux-nat.c, just for illustration, because it still returns
false. We'll need a few follow up fixes before turning it on by
default. This is a separate target method from indicating regular
non-stop support, because e.g., while e.g., native linux-nat.c is
close to regression free with all-stop-non-stop (with following
patches will fixing the remaining regressions), remote.c+gdbserver
will still need more fixing, even though it supports "set non-stop
on".
Tested on x86_64 Fedora 20, native, with and without "set displaced
off", and with and without "maint set target-non-stop on"; and also
against gdbserver.
gdb/ChangeLog:
2015-08-07 Pedro Alves <palves@redhat.com>
* NEWS: Mention "maint set/show target-non-stop".
* breakpoint.c (update_global_location_list): Check
target_is_non_stop_p instead of non_stop.
* infcmd.c (attach_command_post_wait, attach_command): Likewise.
* infrun.c (show_can_use_displaced_stepping)
(can_use_displaced_stepping_p, start_step_over_inferior):
Likewise.
(internal_resume_ptid): New function.
(resume): Use it.
(proceed): Check target_is_non_stop_p instead of non_stop. If in
all-stop mode but the target is always in non-stop mode, start all
the other threads that are implicitly resumed too.
(for_each_just_stopped_thread, fetch_inferior_event)
(adjust_pc_after_break, stop_all_threads): Check
target_is_non_stop_p instead of non_stop.
(handle_inferior_event): Likewise. Handle detach-fork in all-stop
with the target always in non-stop mode.
(handle_signal_stop) <random signal>: Check target_is_non_stop_p
instead of non_stop.
(switch_back_to_stepped_thread): Check target_is_non_stop_p
instead of non_stop.
(keep_going_stepped_thread): Use internal_resume_ptid.
(stop_waiting): If in all-stop mode, and the target is in non-stop
mode, stop all threads.
(keep_going_pass): Likewise, when starting a new in-line step-over
sequence.
* linux-nat.c (get_pending_status, select_event_lwp)
(linux_nat_filter_event, linux_nat_wait_1, linux_nat_wait): Check
target_is_non_stop_p instead of non_stop.
(linux_nat_always_non_stop_p): New function.
(linux_nat_stop): Check target_is_non_stop_p instead of non_stop.
(linux_nat_add_target): Install linux_nat_always_non_stop_p.
* target-delegates.c: Regenerate.
* target.c (target_is_non_stop_p): New function.
(target_non_stop_enabled, target_non_stop_enabled_1): New globals.
(maint_set_target_non_stop_command)
(maint_show_target_non_stop_command): New functions.
(_initilize_target): Install "maint set/show target-non-stop"
commands.
* target.h (struct target_ops) <to_always_non_stop_p>: New field.
(target_non_stop_enabled): New declaration.
(target_is_non_stop_p): New declaration.
gdb/doc/ChangeLog:
2015-08-07 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Maintenance Commands): Document "maint set/show
target-non-stop".
Diffstat (limited to 'gdb/target-delegates.c')
-rw-r--r-- | gdb/target-delegates.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index d2d794f..64b86c2 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -1744,6 +1744,33 @@ debug_supports_non_stop (struct target_ops *self) } static int +delegate_always_non_stop_p (struct target_ops *self) +{ + self = self->beneath; + return self->to_always_non_stop_p (self); +} + +static int +tdefault_always_non_stop_p (struct target_ops *self) +{ + return 0; +} + +static int +debug_always_non_stop_p (struct target_ops *self) +{ + int result; + fprintf_unfiltered (gdb_stdlog, "-> %s->to_always_non_stop_p (...)\n", debug_target.to_shortname); + result = debug_target.to_always_non_stop_p (&debug_target); + fprintf_unfiltered (gdb_stdlog, "<- %s->to_always_non_stop_p (", debug_target.to_shortname); + target_debug_print_struct_target_ops_p (&debug_target); + fputs_unfiltered (") = ", gdb_stdlog); + target_debug_print_int (result); + fputs_unfiltered ("\n", gdb_stdlog); + return result; +} + +static int delegate_find_memory_regions (struct target_ops *self, find_memory_region_ftype arg1, void *arg2) { self = self->beneath; @@ -4005,6 +4032,8 @@ install_delegators (struct target_ops *ops) ops->to_async = delegate_async; if (ops->to_supports_non_stop == NULL) ops->to_supports_non_stop = delegate_supports_non_stop; + if (ops->to_always_non_stop_p == NULL) + ops->to_always_non_stop_p = delegate_always_non_stop_p; if (ops->to_find_memory_regions == NULL) ops->to_find_memory_regions = delegate_find_memory_regions; if (ops->to_make_corefile_notes == NULL) @@ -4232,6 +4261,7 @@ install_dummy_methods (struct target_ops *ops) 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_always_non_stop_p = tdefault_always_non_stop_p; 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; @@ -4380,6 +4410,7 @@ init_debug_target (struct target_ops *ops) ops->to_is_async_p = debug_is_async_p; ops->to_async = debug_async; ops->to_supports_non_stop = debug_supports_non_stop; + ops->to_always_non_stop_p = debug_always_non_stop_p; ops->to_find_memory_regions = debug_find_memory_regions; ops->to_make_corefile_notes = debug_make_corefile_notes; ops->to_get_bookmark = debug_get_bookmark; |