From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7321 invoked by alias); 10 Jun 2008 09:36:54 -0000 Received: (qmail 7306 invoked by uid 22791); 10 Jun 2008 09:36:50 -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; Tue, 10 Jun 2008 09:36:32 +0000 Received: (qmail 3405 invoked from network); 10 Jun 2008 09:36:28 -0000 Received: from unknown (HELO localhost) (vladimir@127.0.0.2) by mail.codesourcery.com with ESMTPA; 10 Jun 2008 09:36:28 -0000 From: Vladimir Prus To: Daniel Jacobowitz Subject: Re: [RFA] Use observers to report stop events. Date: Tue, 10 Jun 2008 11:58:00 -0000 User-Agent: KMail/1.9.9 Cc: Joel Brobecker , gdb-patches@sources.redhat.com References: <200804112145.58456.vladimir@codesourcery.com> <200805041225.54416.vladimir@codesourcery.com> <20080605154111.GA29085@caradoc.them.org> In-Reply-To: <20080605154111.GA29085@caradoc.them.org> MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_YskTIhoAql4tLyF" Message-Id: <200806101336.24223.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/msg00197.txt.bz2 --Boundary-00=_YskTIhoAql4tLyF Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 2557 On Thursday 05 June 2008 19:41:11 Daniel Jacobowitz wrote: > On Sun, May 04, 2008 at 12:25:54PM +0400, Vladimir Prus wrote: > > Are those two new patches, together with the previously posted one > > (changing stop_observer not to always fire) OK? > > For this patch, if an error occurs during proceed (i.e. if the > cleanup restoring suppress_normal_stop_observer is run), will the > normal_stop observer ever be called? Is that a problem? You mean this block: old_cleanups2 = make_cleanup_restore_integer (&suppress_normal_stop_observer, 1); proceed (real_pc, TARGET_SIGNAL_0, 0); do_cleanups (old_cleanups2); If proceed throws, before calling normal_stop, we'll get back to event loop, and run cleanup. We won't call the observer. It's an issue if we've printed "*running" and thrown after after. However, it's the issue we have now, as well -- we print ^running even before calling proceed, and if something later throws, we'll never print *stopped. Possible solutions are: - Require that frontend refresh thread state on ^error - Emit *stopped if exception is thrown (this requires checking that the target is actually stopped, if exception is thrown). > > + If the argument is pointer to allocated memory, then you need to > > is a pointer > > > struct cleanup * > > -make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, > > - void *arg) > > +make_cleanup_restore_integer (int *variable, int value) > > +{ > > + struct restore_integer_closure *c = > > + xmalloc (sizeof (struct restore_integer_closure)); > > + struct cleanup *cleanup = make_cleanup (restore_integer, (void *) c); > > + c->variable = variable; > > + c->value = *variable; > > + *variable = value; > > + cleanup_chain->free_arg = xfree; > > + return cleanup; > > +} > > Could you use make_my_cleanup2 here to avoid poking around in > cleanup_chain, please? Done. > > Also, the only thing value is used for is to set *variable. I > suggest not setting the variable in a function named > "make_cleanup_restore_integer", which doesn't say anything about > setting. So I would prefer this: > > old_cleanup = make_cleanup_restore_integer (some_var); > some_var = 0; Done. > > > * infrun.c (finish_command): Don't pass cleanup > > to continuation. > > (finish_command_continuation): Don't grab cleanup from > > the passed data, as we don't use, and cannot, use it anyway. > > OK. Thanks, checked in. Since there were some adjustment, I attach the final versions of the patches as checked in. - Volodya --Boundary-00=_YskTIhoAql4tLyF Content-Type: text/x-diff; charset="iso-8859-1"; name="0001-Introduce-common-cleanup-for-restoring-integers.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0001-Introduce-common-cleanup-for-restoring-integers.patch" Content-length: 5740 =46rom d354ec6250185a3083636b349acebb89faafe359 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Tue, 29 Apr 2008 21:31:59 +0400 Subject: [RFA] Introduce common cleanup for restoring integers. To: gdb-patches@sources.redhat.com X-KMail-Transport: CodeSourcery X-KMail-Identity: 901867920 * defs.h (make_cleanup_restore_integer): New declaration. (struct cleanup): New field free_arg. (make_my_cleanup_2): New. * utils.c (restore_integer_closure, restore_integer) (make_cleanup_restore_integer): New. (make_my_cleanup): Initialize the free_arg field and renamed to make_my_cleanup_2. (do_my_cleanups): Call free_arg. (discard_cleanups): Call free_arg. * breakpoint.c (restore_always_inserted_mode): Remove. (update_breakpoints_after_exec): Use make_cleanup_restore_integer. --- gdb/breakpoint.c | 9 +-------- gdb/defs.h | 14 +++++++++++++- gdb/utils.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 051b753..dd7bf12 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -1435,12 +1435,6 @@ reattach_breakpoints (int pid) return 0; } =20 -static void -restore_always_inserted_mode (void *p) -{ - always_inserted_mode =3D (uintptr_t) p; -} - void update_breakpoints_after_exec (void) { @@ -1456,8 +1450,7 @@ update_breakpoints_after_exec (void) /* The binary we used to debug is now gone, and we're updating breakpoints for the new binary. Until we're done, we should not try to insert breakpoints. */ - cleanup =3D make_cleanup (restore_always_inserted_mode,=20 - (void *) (uintptr_t) always_inserted_mode); + cleanup =3D make_cleanup_restore_integer (&always_inserted_mode); always_inserted_mode =3D 0; =20 ALL_BREAKPOINTS_SAFE (b, temp) diff --git a/gdb/defs.h b/gdb/defs.h index 9069156..ca3fad8 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -230,12 +230,18 @@ enum return_value_convention Use make_cleanup to add an element to the cleanup chain. Use do_cleanups to do all cleanup actions back to a given point in the chain. Use discard_cleanups to remove cleanups - from the chain back to a given point, not doing them. */ + from the chain back to a given point, not doing them.=20=20 + + If the argument is pointer to allocated memory, then you need to + to additionally set the 'free_arg' member to a function that will + free that memory. This function will be called both when the cleanup + is executed and when it's discarded. */ =20 struct cleanup { struct cleanup *next; void (*function) (void *); + void (*free_arg) (void *); void *arg; }; =20 @@ -339,11 +345,17 @@ extern struct cleanup *make_cleanup_close (int fd); =20 extern struct cleanup *make_cleanup_bfd_close (bfd *abfd); =20 +extern struct cleanup *make_cleanup_restore_integer (int *variable); + extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); =20 extern struct cleanup *make_my_cleanup (struct cleanup **, make_cleanup_ftype *, void *); =20 +extern struct cleanup *make_my_cleanup2 (struct cleanup **, + make_cleanup_ftype *, void *, + void (*free_arg) (void *)); + extern struct cleanup *save_cleanups (void); extern struct cleanup *save_final_cleanups (void); extern struct cleanup *save_my_cleanups (struct cleanup **); diff --git a/gdb/utils.c b/gdb/utils.c index 76ea6b1..cdea5a6 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -277,10 +277,36 @@ make_cleanup_free_section_addr_info (struct section_a= ddr_info *addrs) return make_my_cleanup (&cleanup_chain, do_free_section_addr_info, addrs= ); } =20 +struct restore_integer_closure +{ + int *variable; + int value; +}; + +static void +restore_integer (void *p) +{ + struct restore_integer_closure *closure =3D p; + *(closure->variable) =3D closure->value; +} =20 +/* Remember the current value of *VARIABLE and make it restored when the c= leanup + is run. */ struct cleanup * -make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg) +make_cleanup_restore_integer (int *variable) +{ + struct restore_integer_closure *c =3D + xmalloc (sizeof (struct restore_integer_closure)); + c->variable =3D variable; + c->value =3D *variable; + + return make_my_cleanup2 (&cleanup_chain, restore_integer, (void *)c, + xfree); +} + +struct cleanup * +make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg, void (*free_arg) (void *)) { struct cleanup *new =3D (struct cleanup *) xmalloc (sizeof (struct cleanup)); @@ -288,12 +314,20 @@ make_my_cleanup (struct cleanup **pmy_chain, make_cle= anup_ftype *function, =20 new->next =3D *pmy_chain; new->function =3D function; + new->free_arg =3D free_arg; new->arg =3D arg; *pmy_chain =3D new; =20 return old_chain; } =20 +struct cleanup * +make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg) +{ + return make_my_cleanup2 (pmy_chain, function, arg, NULL); +} + /* Discard cleanups and do the actions they describe until we get back to the point OLD_CHAIN in the cleanup_chain. */ =20 @@ -318,6 +352,8 @@ do_my_cleanups (struct cleanup **pmy_chain, { *pmy_chain =3D ptr->next; /* Do this first incase recursion */ (*ptr->function) (ptr->arg); + if (ptr->free_arg) + (*ptr->free_arg) (ptr->arg); xfree (ptr); } } @@ -345,6 +381,8 @@ discard_my_cleanups (struct cleanup **pmy_chain, while ((ptr =3D *pmy_chain) !=3D old_chain) { *pmy_chain =3D ptr->next; + if (ptr->free_arg) + (*ptr->free_arg) (ptr->arg); xfree (ptr); } } --=20 1.5.3.5 --Boundary-00=_YskTIhoAql4tLyF Content-Type: text/x-diff; charset="iso-8859-1"; name="0003-Suppress-normal-stop-observer-when-it-s-problematic.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0003-Suppress-normal-stop-observer-when-it-s-problematic.patch" Content-length: 4159 =46rom 85eda1b65c61be67f9098f001a5f52f70f44c33f Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Mon, 9 Jun 2008 21:14:33 +0400 Subject: [RFA] Suppress normal stop observer when it's problematic. To: gdb-patches@sources.redhat.com X-KMail-Transport: CodeSourcery X-KMail-Identity: 901867920 * inferior.h (suppress_normal_stop_observer): New. * infcall.c (call_function_by_hand): Disable stop events when doing function calls. * infmcd.c (suppress_normal_stop_observer): New. (finish_command_continuation): Call normal_stop observer explicitly. (finish_command): Disable stop events inside proceed. * infrun.c (normal_stop): Don't call normal stop observer if suppressed of if multi-step is in progress. --- gdb/infcall.c | 7 ++++++- gdb/infcmd.c | 10 ++++++++++ gdb/inferior.h | 3 +++ gdb/infrun.c | 3 ++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/gdb/infcall.c b/gdb/infcall.c index c065b59..ded3211 100644 --- a/gdb/infcall.c +++ b/gdb/infcall.c @@ -706,6 +706,7 @@ call_function_by_hand (struct value *function, int narg= s, struct value **args) =20 { struct cleanup *old_cleanups =3D make_cleanup (null_cleanup, 0); + struct cleanup *old_cleanups2; int saved_async =3D 0; =20 /* If all error()s out of proceed ended up calling normal_stop @@ -718,8 +719,12 @@ call_function_by_hand (struct value *function, int nar= gs, struct value **args) =20 if (target_can_async_p ()) saved_async =3D target_async_mask (0); -=20=20=20=20 + + old_cleanups2 =3D make_cleanup_restore_integer=20 + (&suppress_normal_stop_observer); + suppress_normal_stop_observer =3D 1; proceed (real_pc, TARGET_SIGNAL_0, 0); + do_cleanups (old_cleanups2); =20=20=20=20=20 if (saved_async) target_async_mask (saved_async); diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 30858f1..a844b7d 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -206,6 +206,9 @@ int step_multi; in format described in environ.h. */ =20 struct gdb_environ *inferior_environ; + +/* When set, normal_stop will not call the normal_stop observer. */ +int suppress_normal_stop_observer =3D 0; =0C /* Accessor routines. */ =20 @@ -1294,8 +1297,13 @@ finish_command_continuation (struct continuation_arg= *arg, int error_p) if (TYPE_CODE (value_type) !=3D TYPE_CODE_VOID) print_return_value (SYMBOL_TYPE (function), value_type);=20 } + + /* We suppress normal call of normal_stop observer and do it here so= that + that *stopped notification includes the return value. */ + observer_notify_normal_stop (stop_bpstat); } =20 + suppress_normal_stop_observer =3D 0; delete_breakpoint (breakpoint); } =20 @@ -1362,6 +1370,8 @@ finish_command (char *arg, int from_tty) } =20 proceed_to_finish =3D 1; /* We want stop_registers, please... */ + make_cleanup_restore_integer (&suppress_normal_stop_observer); + suppress_normal_stop_observer =3D 1; proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); =20 arg1 =3D diff --git a/gdb/inferior.h b/gdb/inferior.h index 1dd152a..7f85507 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -391,6 +391,9 @@ extern int debug_displaced; void displaced_step_dump_bytes (struct ui_file *file, const gdb_byte *buf, size_t len); =20 + +/* When set, normal_stop will not call the normal_stop observer. */ +extern int suppress_normal_stop_observer; =0C /* Possible values for gdbarch_call_dummy_location. */ #define ON_STACK 1 diff --git a/gdb/infrun.c b/gdb/infrun.c index 2960acb..1e10ecc 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3772,7 +3772,8 @@ Further execution is probably impossible.\n")); =20 done: annotate_stopped (); - observer_notify_normal_stop (stop_bpstat); + if (!suppress_normal_stop_observer && !step_multi) + observer_notify_normal_stop (stop_bpstat); /* Delete the breakpoint we stopped at, if it wants to be deleted. Delete any breakpoint that is to be deleted at the next stop. */ breakpoint_auto_delete (stop_bpstat); --=20 1.5.3.5 --Boundary-00=_YskTIhoAql4tLyF Content-Type: text/x-diff; charset="iso-8859-1"; name="0002-Remove-stale-code.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0002-Remove-stale-code.patch" Content-length: 1647 =46rom 36e76ca870e36e406b1c301b28d6e95f514b0974 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Sun, 4 May 2008 12:09:45 +0400 Subject: [RFA] Remove stale code. To: gdb-patches@sources.redhat.com X-KMail-Transport: CodeSourcery X-KMail-Identity: 901867920 * infrun.c (finish_command): Don't pass cleanup to continuation. (finish_command_continuation): Don't grab cleanup from the passed data, as we don't use, and cannot, use it anyway. --- gdb/infcmd.c | 7 +------ 1 files changed, 1 insertions(+), 6 deletions(-) diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 2397c30..30858f1 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1278,7 +1278,6 @@ finish_command_continuation (struct continuation_arg = *arg, int error_p) =20 breakpoint =3D (struct breakpoint *) arg->data.pointer; function =3D (struct symbol *) arg->next->data.pointer; - cleanups =3D (struct cleanup *) arg->next->next->data.pointer; =20 if (!error_p) { @@ -1369,14 +1368,10 @@ finish_command (char *arg, int from_tty) (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); arg2 =3D (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); - arg3 =3D - (struct continuation_arg *) xmalloc (sizeof (struct continuation_arg)); arg1->next =3D arg2; - arg2->next =3D arg3; - arg3->next =3D NULL; + arg2->next =3D NULL; arg1->data.pointer =3D breakpoint; arg2->data.pointer =3D function; - arg3->data.pointer =3D old_chain; add_continuation (finish_command_continuation, arg1); =20 /* Do this only if not running asynchronously or if the target --=20 1.5.3.5 --Boundary-00=_YskTIhoAql4tLyF Content-Type: text/x-diff; charset="iso-8859-1"; name="0004-Use-observers-to-report-stop-events-in-MI.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="0004-Use-observers-to-report-stop-events-in-MI.patch" Content-length: 16860 =46rom 8b8a8557c8b1c34395053105a420fbc252c4fb61 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Mon, 9 Jun 2008 21:18:28 +0400 Subject: [RFA] Use observers to report stop events in MI. To: gdb-patches@sources.redhat.com X-KMail-Transport: CodeSourcery X-KMail-Identity: 901867920 * mi/mi-interp.c (mi_on_normal_stop): New. (mi_interpreter_init): Register mi_on_normal_stop. (mi_interpreter_exec_continuation): Remove. (mi_cmd_interpreter_exec): Don't register the above. * mi/mi-main.c (captured_mi_execute_command): Don't care about sync_execution. (mi_execute_async_cli_command): Don't install continuation. Don't print *stopped. (mi_exec_async_cli_cmd_continuation): Remove. [gdb/testsuite] * gdb.mi/mi-break.exp (test_ignore_count): Adjust stopped pattern. * gdb.mi/mi-syn-frame.exp: Use mi_expect_stop instead of direct testing of stopped. * gdb.mi/mi2-syn-frame.exp: Likewise. * lib/mi-support.exp (default_mi_gdb_start): Call detect_async. (async, detect_async): New. (mi_expect_stop, mi_continue_to_line): Adjust expectation depending on if we're running in sync or async mode. --- gdb/infcmd.c | 5 +-- gdb/mi/mi-interp.c | 40 +++++++++----------- gdb/mi/mi-main.c | 37 +----------------- gdb/testsuite/gdb.mi/mi-break.exp | 2 +- gdb/testsuite/gdb.mi/mi-syn-frame.exp | 6 +-- gdb/testsuite/gdb.mi/mi2-syn-frame.exp | 25 +++--------- gdb/testsuite/lib/mi-support.exp | 64 ++++++++++++++++++++++++++++= +--- 7 files changed, 90 insertions(+), 89 deletions(-) diff --git a/gdb/infcmd.c b/gdb/infcmd.c index a844b7d..01e1ebe 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1383,10 +1383,7 @@ finish_command (char *arg, int from_tty) arg1->data.pointer =3D breakpoint; arg2->data.pointer =3D function; add_continuation (finish_command_continuation, arg1); - - /* Do this only if not running asynchronously or if the target - cannot do async execution. Otherwise, complete this command when - the target actually stops, in fetch_inferior_event. */ +=20=20 discard_cleanups (old_chain); if (!target_can_async_p ()) do_all_continuations (0); diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index 8b0d909..583c288 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -65,6 +65,7 @@ static void mi1_command_loop (void); =20 static void mi_insert_notify_hooks (void); static void mi_remove_notify_hooks (void); +static void mi_on_normal_stop (struct bpstats *bs); =20 static void mi_new_thread (struct thread_info *t); static void mi_thread_exit (struct thread_info *t); @@ -92,6 +93,7 @@ mi_interpreter_init (int top_level) { observer_attach_new_thread (mi_new_thread); observer_attach_thread_exit (mi_thread_exit); + observer_attach_normal_stop (mi_on_normal_stop); } =20 return mi; @@ -171,26 +173,6 @@ mi_interpreter_prompt_p (void *data) return 0; } =20 -static void -mi_interpreter_exec_continuation (struct continuation_arg *arg, int error_= p) -{ - bpstat_do_actions (&stop_bpstat); - /* It's not clear what to do in the case of errror -- should we assume t= hat - the target is stopped, or that it still runs? */ - if (!target_executing) - { - fputs_unfiltered ("*stopped", raw_stdout); - mi_out_put (uiout, raw_stdout); - fputs_unfiltered ("\n", raw_stdout); - fputs_unfiltered ("(gdb) \n", raw_stdout); - gdb_flush (raw_stdout); - } - else if (target_can_async_p ()) - { - add_continuation (mi_interpreter_exec_continuation, NULL); - } -} - enum mi_cmd_result mi_cmd_interpreter_exec (char *command, char **argv, int argc) { @@ -241,7 +223,6 @@ mi_cmd_interpreter_exec (char *command, char **argv, in= t argc) if (target_can_async_p () && target_executing) { fputs_unfiltered ("^running\n", raw_stdout); - add_continuation (mi_interpreter_exec_continuation, NULL); } =20 if (mi_error_message !=3D NULL) @@ -325,12 +306,27 @@ static void mi_thread_exit (struct thread_info *t) { struct mi_interp *mi =3D top_level_interpreter_data (); - target_terminal_ours (); fprintf_unfiltered (mi->event_channel, "thread-exited,id=3D\"%d\"", t->n= um); gdb_flush (mi->event_channel); } =20 +static void +mi_on_normal_stop (struct bpstats *bs) +{ + /* Since this can be called when CLI command is executing, + using cli interpreter, be sure to use MI uiout for output, + not the current one. */ + struct ui_out *uiout =3D interp_ui_out (top_level_interpreter ()); + struct mi_interp *mi =3D top_level_interpreter_data (); + + fputs_unfiltered ("*stopped", raw_stdout); + mi_out_put (uiout, raw_stdout); + mi_out_rewind (uiout); + fputs_unfiltered ("\n", raw_stdout); + gdb_flush (raw_stdout); +} + extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototype= s */ =20 void diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c index 4ae509e..6dc7609 100644 --- a/gdb/mi/mi-main.c +++ b/gdb/mi/mi-main.c @@ -103,10 +103,6 @@ static void mi_execute_cli_command (const char *cmd, i= nt args_p, const char *args); static enum mi_cmd_result mi_execute_async_cli_command (char *cli_command,= =20 char **argv, int argc); - -static void mi_exec_async_cli_cmd_continuation (struct continuation_arg *a= rg,=20 - int error_p); - static int register_changed_p (int regnum, struct regcache *, struct regcache *); static void get_register (int regnum, int format); @@ -1087,15 +1083,11 @@ captured_mi_execute_command (struct ui_out *uiout, = void *data) fputs_unfiltered ("\n", raw_stdout); } else + /* The command does not want anything to be printed. In that + case, the command probably should not have written anything + to uiout, but in case it has written something, discard it. */ mi_out_rewind (uiout); } - else if (sync_execution) - { - /* Don't print the prompt. We are executing the target in - synchronous mode. */ - args->action =3D EXECUTE_COMMAND_SUPPRESS_PROMPT; - return; - } break; =20 case CLI_COMMAND: @@ -1311,12 +1303,6 @@ mi_execute_async_cli_command (char *cli_command, cha= r **argv, int argc) fputs_unfiltered (current_token, raw_stdout); fputs_unfiltered ("^running\n", raw_stdout); =20 - /* Ideally, we should be intalling continuation only when - the target is already running. However, this will break right now, - because continuation installed by the 'finish' command must be after - the continuation that prints *stopped. This issue will be - fixed soon. */ - add_continuation (mi_exec_async_cli_cmd_continuation, NULL); } =20 execute_command ( /*ui */ run, 0 /*from_tty */ ); @@ -1332,31 +1318,14 @@ mi_execute_async_cli_command (char *cli_command, ch= ar **argv, int argc) /* Do this before doing any printing. It would appear that some print code leaves garbage around in the buffer. */ do_cleanups (old_cleanups); - /* If the target was doing the operation synchronously we fake - the stopped message. */ - fputs_unfiltered ("*stopped", raw_stdout); - mi_out_put (uiout, raw_stdout); - mi_out_rewind (uiout); if (do_timings) print_diff_now (current_command_ts); - fputs_unfiltered ("\n", raw_stdout); return MI_CMD_QUIET; }=20=20=20=20 return MI_CMD_DONE; } =20 void -mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg, int erro= r_p) -{ - /* Assume 'error' means that target is stopped, too. */ - fputs_unfiltered ("*stopped", raw_stdout); - mi_out_put (uiout, raw_stdout); - fputs_unfiltered ("\n", raw_stdout); - fputs_unfiltered ("(gdb) \n", raw_stdout); - gdb_flush (raw_stdout); -} - -void mi_load_progress (const char *section_name, unsigned long sent_so_far, unsigned long total_section, diff --git a/gdb/testsuite/gdb.mi/mi-break.exp b/gdb/testsuite/gdb.mi/mi-br= eak.exp index f2f5b03..2798569 100644 --- a/gdb/testsuite/gdb.mi/mi-break.exp +++ b/gdb/testsuite/gdb.mi/mi-break.exp @@ -159,7 +159,7 @@ proc test_ignore_count {} { mi_run_cmd =20 gdb_expect { - -re ".*func=3D\"callme\".*args=3D\\\[\{name=3D\"i\",value=3D\"2\"\= }\\\].*\r\n$mi_gdb_prompt$" { + -re ".*\\*stopped.*func=3D\"callme\".*args=3D\\\[\{name=3D\"i\",va= lue=3D\"2\"\}\\\].*\r\n($mi_gdb_prompt)?$" { pass "run to breakpoint with ignore count" } -re ".*$mi_gdb_prompt$" { diff --git a/gdb/testsuite/gdb.mi/mi-syn-frame.exp b/gdb/testsuite/gdb.mi/m= i-syn-frame.exp index 2f2ca02..208678b 100644 --- a/gdb/testsuite/gdb.mi/mi-syn-frame.exp +++ b/gdb/testsuite/gdb.mi/mi-syn-frame.exp @@ -58,9 +58,7 @@ mi_gdb_test "403-exec-continue" \ "403\\^running" \ "testing exec continue" =20 -# Presently, the *stopped notification for this case does not include -# any information. This can be considered a bug. -mi_gdb_test "" "\\*stopped" "finished exec continue" +mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 mi_gdb_test "404-stack-list-frames 0 0" \ "404\\^done,stack=3D\\\[frame=3D\{level=3D\"0\",addr=3D\"$hex\",func=3D\= "main\",file=3D\".*mi-syn-frame.c\",fullname=3D\"${fullname_syntax}${srcfil= e}\",line=3D\"$decimal\"\}.*\\\]" \ @@ -88,7 +86,7 @@ mi_gdb_test "407-stack-list-frames" \ =20 mi_gdb_test "408-exec-continue" "408\\^running" =20 -mi_gdb_test "" ".*\\*stopped.*" "finished exec continue" +mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 mi_gdb_test "409-stack-list-frames 0 0" \ "409\\^done,stack=3D\\\[frame=3D\{level=3D\"0\",addr=3D\"$hex\",func=3D\= "main\",file=3D\".*mi-syn-frame.c\",fullname=3D\"${fullname_syntax}${srcfil= e}\",line=3D\"$decimal\"\}.*\\\]" \ diff --git a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp b/gdb/testsuite/gdb.mi/= mi2-syn-frame.exp index c447404..b69812f 100644 --- a/gdb/testsuite/gdb.mi/mi2-syn-frame.exp +++ b/gdb/testsuite/gdb.mi/mi2-syn-frame.exp @@ -56,15 +56,11 @@ mi_gdb_test "402-stack-list-frames" "402\\^done,stack= =3D\\\[frame=3D\{level=3D\"0\",ad # Continue back to main() # =20 -send_gdb "403-exec-continue\n" -gdb_expect { - -re "403\\^running\[\r\n\]+${my_mi_gdb_prompt}.*\\\*stopped\[\r\n\]+${my= _mi_gdb_prompt}$" { - pass "403-exec-continue" - } - timeout { - fail "403-exec-continue" - } -} +mi_gdb_test "403-exec-continue" \ + "403\\^running" \ + "testing exec continue" + +mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 mi_gdb_test "404-stack-list-frames 0 0" \ "404\\^done,stack=3D\\\[frame=3D\{level=3D\"0\",addr=3D\"$hex\",func=3D\= "main\",file=3D\".*mi-syn-frame.c\",fullname=3D\"${fullname_syntax}${srcfil= e}\",line=3D\"$decimal\"\}.*\\\]" \ @@ -89,16 +85,9 @@ mi_gdb_test "407-stack-list-frames" \ "407\\^done,stack=3D\\\[frame=3D\{level=3D\"0\",addr=3D\"$hex\",func=3D\= "subroutine\",file=3D\".*mi-syn-frame.c\",line=3D\"$decimal\"\},frame=3D\{l= evel=3D\"1\",addr=3D\"$hex\",func=3D\"handler\",file=3D\".*mi-syn-frame.c\"= ,line=3D\"$decimal\"\},frame=3D\{level=3D\"2\",addr=3D\"$hex\",func=3D\"\"\},.*frame=3D\{level=3D\"$decimal\",addr=3D\"$hex\",f= unc=3D\"have_a_very_merry_interrupt\",file=3D\".*mi-syn-frame.c\",line=3D\"= $decimal\"\},frame=3D\{level=3D\"$decimal\",addr=3D\"$hex\",func=3D\"\"\},frame=3D\{level=3D\"$decimal\",addr=3D\"$hex\",fun= c=3D\"main\",file=3D\".*mi-syn-frame.c\",line=3D\"$decimal\"\}.*\\\]" \ "list stack frames" =20 +mi_gdb_test "408-exec-continue" "408\\^running" =20 -send_gdb "408-exec-continue\n" -gdb_expect { - -re "408\\^running\[\r\n\]+${my_mi_gdb_prompt}.*\\\*stopped\[\r\n\]+${my= _mi_gdb_prompt}$" { - pass "408-exec-continue" - } - timeout { - fail "408-exec-continue" - } -} +mi_expect_stop "really-no-reason" "" "" "" "" "" "finished exec continue" =20 mi_gdb_test "409-stack-list-frames 0 0" \ "409\\^done,stack=3D\\\[frame=3D\{level=3D\"0\",addr=3D\"$hex\",func=3D\= "main\",file=3D\".*mi-syn-frame.c\",fullname=3D\"${fullname_syntax}${srcfil= e}\",line=3D\"$decimal\"\}.*\\\]" \ diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-suppor= t.exp index 6a52c88..23f3f07 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -227,6 +227,8 @@ proc default_mi_gdb_start { args } { } } =20 + detect_async + return 0; } =20 @@ -911,6 +913,30 @@ proc mi_step { test } { return [mi_step_to {.*} {.*} {.*} {.*} $test] } =20 +set async "unknown" + +proc detect_async {} { + global async + global mi_gdb_prompt + + if { $async =3D=3D "unknown" } { + send_gdb "maint show linux-async\n" +=20=20=20=20=20=20=20=20 + gdb_expect { + -re ".*Controlling the GNU/Linux inferior in asynchronous mode is on.= ..*$mi_gdb_prompt$" { + set async 1 + } + -re ".*$mi_gdb_prompt$" { + set async 0 + } + timeout { + set async 0 + } + } + } + return $async +} + # Wait for MI *stopped notification to appear. # The REASON, FUNC, ARGS, FILE and LINE are regular expressions # to match against whatever is output in *stopped. ARGS should @@ -933,6 +959,7 @@ proc mi_expect_stop { reason func args file line extra = test } { global hex global decimal global fullname_syntax + global async =20 set after_stopped "" set after_reason "" @@ -944,10 +971,28 @@ proc mi_expect_stop { reason func args file line extr= a test } { set after_stopped [lindex $extra 0] } =20 + if {$async} { + set prompt_re "" + } else { + set prompt_re "$mi_gdb_prompt" + } + + if { $reason =3D=3D "really-no-reason" } { + gdb_expect { + -re "\\*stopped\r\n$prompt_re$" { + pass "$test" + } + timeout { + fail "$test (unknown output after running)" + } + } + return + } +=20=20=20=20 if { $reason =3D=3D "exited-normally" } { =20 gdb_expect { - -re "\\*stopped,reason=3D\"exited-normally\"\r\n$mi_gdb_prompt$"= { + -re "\\*stopped,reason=3D\"exited-normally\"\r\n$prompt_re$" { pass "$test" } -re ".*$mi_gdb_prompt$" {fail "continue to end (2)"} @@ -973,17 +1018,17 @@ proc mi_expect_stop { reason func args file line ext= ra test } { =20 set a $after_reason =20 - verbose -log "mi_expect_stop: expecting: .*\\*stopped,${r}${a}${bn}thr= ead-id=3D\"$decimal\",frame=3D\{addr=3D\"$hex\",func=3D\"$func\",args=3D$ar= gs,file=3D\".*$file\",fullname=3D\"${fullname_syntax}$file\",line=3D\"$line= \"\}$after_stopped\r\n$mi_gdb_prompt$" + verbose -log "mi_expect_stop: expecting: .*\\*stopped,${r}${a}${bn}thr= ead-id=3D\"$decimal\",frame=3D\{addr=3D\"$hex\",func=3D\"$func\",args=3D$ar= gs,file=3D\".*$file\",fullname=3D\"${fullname_syntax}$file\",line=3D\"$line= \"\}$after_stopped\r\n$prompt_re$" gdb_expect { - -re ".*\\*stopped,${r}${a}${bn}thread-id=3D\"$decimal\",frame=3D\{addr=3D= \"$hex\",func=3D\"$func\",args=3D$args,file=3D\".*$file\",fullname=3D\"${fu= llname_syntax}$file\",line=3D\"($line)\"\}$after_stopped\r\n$mi_gdb_prompt$= " { + -re ".*\\*stopped,${r}${a}${bn}thread-id=3D\"$decimal\",frame=3D\{addr=3D= \"$hex\",func=3D\"$func\",args=3D$args,file=3D\".*$file\",fullname=3D\"${fu= llname_syntax}$file\",line=3D\"($line)\"\}$after_stopped\r\n$prompt_re$" { pass "$test" return $expect_out(2,string) } - -re ".*\\*stopped,${r}${a}${bn}thread-id=3D\"$decimal\",frame=3D\{addr=3D= \"$hex\",func=3D\".*\",args=3D\[\\\[\{\].*\[\\\]\}\],file=3D\".*\",fullname= =3D\"${fullname_syntax}.*\",line=3D\"\[0-9\]*\"\}.*\r\n$mi_gdb_prompt$" { + -re ".*\\*stopped,${r}${a}${bn}thread-id=3D\"$decimal\",frame=3D\{addr=3D= \"$hex\",func=3D\".*\",args=3D\[\\\[\{\].*\[\\\]\}\],file=3D\".*\",fullname= =3D\"${fullname_syntax}.*\",line=3D\"\[0-9\]*\"\}.*\r\n$prompt_re$" { fail "$test (stopped at wrong place)" return -1 } - -re ".*\r\n${mi_gdb_prompt}$" { + -re ".*\r\n$mi_gdb_prompt$" { fail "$test (unknown output after running)" return -1 } @@ -1388,9 +1433,16 @@ proc mi_continue_to_line {location test} { proc mi_get_stop_line {test} { =20 global mi_gdb_prompt + global async + + if {$async} { + set prompt_re "" + } else { + set prompt_re "$mi_gdb_prompt" + } =20 gdb_expect { - -re ".*line=3D\"(.*)\".*\r\n$mi_gdb_prompt$" { + -re ".*line=3D\"(.*)\".*\r\n$prompt_re$" { return $expect_out(1,string) } -re ".*$mi_gdb_prompt$" { --=20 1.5.3.5 --Boundary-00=_YskTIhoAql4tLyF--