From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25311 invoked by alias); 28 Jun 2008 16:54:24 -0000 Received: (qmail 25294 invoked by uid 22791); 28 Jun 2008 16:54:22 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 28 Jun 2008 16:54:05 +0000 Received: (qmail 11138 invoked from network); 28 Jun 2008 16:54:03 -0000 Received: from unknown (HELO 172.16.unknown.plus.ru) (vladimir@127.0.0.2) by mail.codesourcery.com with ESMTPA; 28 Jun 2008 16:54:03 -0000 From: Vladimir Prus Date: Sat, 28 Jun 2008 16:57:00 -0000 Subject: [MI non-stop 06/11, RFA/RFC] Report non-stop availability, and allow to enable everything with one command. To: gdb-patches@sources.redhat.com X-TUID: 5cda09cdcb205c8a X-Length: 8997 X-UID: 265 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200806282054.03092.vladimir@codesourcery.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-06/txt/msg00545.txt.bz2 This patch allows MI frontend to query for non-stop support, like this: -gdb-show non-stop ^done,value="off",supported="1" and also allows to set non-stop support with a single command, "-gdb-set non-stop 1". The questionable bit of this patch is the cli-setshow.c change. Presently, -gdb-show basically is routed via CLI "show" command. The implementation, when uiout is MI, just outputs a field. For CLI, a show function hooked to that variable is invoked. I want to report, in addition to value, the supportedness of the variable. The only way I found was to output a field in the show function, and make cli-setshow.c always invoke the show function, even for MI. This will result in extra "~" output, which is not nice, but tolerable. Another issue is direct poking at linux async support. I do think that we need global 'async' variable to implement this cleanly. Comments? - Volodya * breakpoint.c (breakpoints_set_always_inserted_mode): New. * breakpoint.h (breakpoints_set_always_inserted_mode): New. * cli/cli-setshow.c (do_setshow_command): Call the setshow function even in MI mode. * infrun.c (set_non_stop): Auto-enable other necessary bits. (show_non_stop): Report if non-stop is supported. * linux-nat.c (enable_linux_async): New, extracted from ... (set_maintenance_linux_async_permitted): ...this. (linux_nat_supports_non_stop): New. (linux_nat_add_target): Register to_supports_non_stop. * linux-nat.h (enable_linux_async): Declare. * target.c (find_default_supports_non_stop) (target_supports_non_stop): New. (init_dummy_target): Register to_supports_non_stop. * target.h (struct target_ops): New field to_supports_non_stop. (target_supports_non_stop): New. --- gdb/breakpoint.c | 5 +++++ gdb/breakpoint.h | 1 + gdb/cli/cli-setshow.c | 19 +++++++++---------- gdb/infrun.c | 23 +++++++++++++++++++++++ gdb/linux-nat.c | 22 ++++++++++++++++++---- gdb/linux-nat.h | 3 +++ gdb/target.c | 24 ++++++++++++++++++++++++ gdb/target.h | 3 +++ 8 files changed, 86 insertions(+), 14 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 567e212..53b1438 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -8204,6 +8204,11 @@ int breakpoints_always_inserted_mode (void) return always_inserted_mode; } +void breakpoints_set_always_inserted_mode (int enable) +{ + always_inserted_mode = enable; +} + /* This help string is used for the break, hbreak, tbreak and thbreak commands. It is defined as a macro to prevent duplication. diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 70ab75f..442c9ac 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -875,6 +875,7 @@ void breakpoint_restore_shadows (gdb_byte *buf, ULONGEST memaddr, LONGEST len); extern int breakpoints_always_inserted_mode (void); +extern void breakpoints_set_always_inserted_mode (int enable); /* Called each time new event from target is processed. Retires previously deleted breakpoint locations that diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c index c5f86fe..0fb7b58 100644 --- a/gdb/cli/cli-setshow.c +++ b/gdb/cli/cli-setshow.c @@ -375,16 +375,15 @@ do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c) if (ui_out_is_mi_like_p (uiout)) ui_out_field_stream (uiout, "value", stb); - else - { - long length; - char *value = ui_file_xstrdup (stb->stream, &length); - make_cleanup (xfree, value); - if (c->show_value_func != NULL) - c->show_value_func (gdb_stdout, from_tty, c, value); - else - deprecated_show_value_hack (gdb_stdout, from_tty, c, value); - } + { + long length; + char *value = ui_file_xstrdup (stb->stream, &length); + make_cleanup (xfree, value); + if (c->show_value_func != NULL) + c->show_value_func (gdb_stdout, from_tty, c, value); + else + deprecated_show_value_hack (gdb_stdout, from_tty, c, value); + } do_cleanups (old_chain); } else diff --git a/gdb/infrun.c b/gdb/infrun.c index e803d1b..567fc2a 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -47,6 +47,9 @@ #include "main.h" #include "interps.h" +/* Oh, dirty! */ +#include "linux-nat.h" + #include "gdb_assert.h" #include "mi/mi-common.h" @@ -4798,13 +4801,33 @@ set_non_stop (char *args, int from_tty, error (_("Cannot change this setting while the inferior is running.")); } + if (!target_supports_non_stop ()) + { + non_stop_1 = non_stop; + error (_("Non-stop mode is not supported by the target")); + } + non_stop = non_stop_1; + if (non_stop) + { + /* Automatically enable a couple of features required for non-stop + to operate. + FIXME: what should we do if non-stop is disabled? Leave async + enabled, or disable it back? */ + breakpoints_set_always_inserted_mode (1); + /* This is dirty. I think we better have a global 'async' + flag that instructs an async-capable target to actually + be async. */ + enable_linux_async (1); + } } static void show_non_stop (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { + if (ui_out_is_mi_like_p (uiout)) + ui_out_field_int (uiout, "supported", target_supports_non_stop ()); fprintf_filtered (file, _("Controlling the inferior in non-stop mode is %s.\n"), value); diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 612fad4..9b2bbf2 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -3936,10 +3936,10 @@ static int linux_async_permitted = 0; executing, linux_nat_async_permitted is *not* updated. */ static int linux_async_permitted_1 = 0; -static void -set_maintenance_linux_async_permitted (char *args, int from_tty, - struct cmd_list_element *c) +void +enable_linux_async (int enable) { + linux_async_permitted_1 = enable; if (target_has_execution) { linux_async_permitted_1 = linux_async_permitted; @@ -3947,7 +3947,14 @@ set_maintenance_linux_async_permitted (char *args, int from_tty, } linux_async_permitted = linux_async_permitted_1; - linux_nat_set_async_mode (linux_async_permitted); + linux_nat_set_async_mode (linux_async_permitted); +} + +static void +set_maintenance_linux_async_permitted (char *args, int from_tty, + struct cmd_list_element *c) +{ + enable_linux_async (linux_async_permitted_1); } static void @@ -3988,6 +3995,12 @@ linux_nat_can_async_p (void) return linux_nat_async_mask_value; } +static int +linux_nat_supports_non_stop (void) +{ + return 1; +} + /* target_async_mask implementation. */ static int @@ -4371,6 +4384,7 @@ linux_nat_add_target (struct target_ops *t) t->to_can_async_p = linux_nat_can_async_p; t->to_is_async_p = linux_nat_is_async_p; + t->to_supports_non_stop = linux_nat_supports_non_stop; t->to_async = linux_nat_async; t->to_async_mask = linux_nat_async_mask; t->to_terminal_inferior = linux_nat_terminal_inferior; diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h index 3bdb48a..8d1eccc 100644 --- a/gdb/linux-nat.h +++ b/gdb/linux-nat.h @@ -135,3 +135,6 @@ void linux_nat_switch_fork (ptid_t new_ptid); /* Return the saved siginfo associated with PTID. */ struct siginfo *linux_nat_get_siginfo (ptid_t ptid); + +void enable_linux_async (int enable); + diff --git a/gdb/target.c b/gdb/target.c index 3ac3e30..9f49886 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -2113,6 +2113,29 @@ find_default_is_async_p (void) return 0; } +int +find_default_supports_non_stop (void) +{ + struct target_ops *t; + + t = find_default_run_target (NULL); + if (t && t->to_supports_non_stop) + return (t->to_supports_non_stop) (); + return 0; +} + +int +target_supports_non_stop () +{ + struct target_ops *t; + for (t = ¤t_target; t != NULL; t = t->beneath) + if (t->to_supports_non_stop) + return t->to_supports_non_stop (); + + return 0; +} + + static int default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) { @@ -2388,6 +2411,7 @@ init_dummy_target (void) dummy_target.to_create_inferior = find_default_create_inferior; dummy_target.to_can_async_p = find_default_can_async_p; dummy_target.to_is_async_p = find_default_is_async_p; + dummy_target.to_supports_non_stop = find_default_supports_non_stop; dummy_target.to_pid_to_str = normal_pid_to_str; dummy_target.to_stratum = dummy_stratum; dummy_target.to_find_memory_regions = dummy_find_memory_regions; diff --git a/gdb/target.h b/gdb/target.h index 81ced29..1f454e5 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -422,6 +422,7 @@ struct target_ops int (*to_is_async_p) (void); void (*to_async) (void (*) (enum inferior_event_type, void *), void *); int (*to_async_mask) (int); + int (*to_supports_non_stop) (void); int (*to_find_memory_regions) (int (*) (CORE_ADDR, unsigned long, int, int, int, @@ -961,6 +962,8 @@ int target_follow_fork (int follow_child); /* Is the target in asynchronous execution mode? */ #define target_is_async_p() (current_target.to_is_async_p ()) +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 ((CALLBACK), (CONTEXT))) -- 1.5.3.5