public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v6 1/2] Make display_gdb_prompt CLI-only.
  2014-05-23 20:59 [PATCH v6 0/2] enable target-async by default Pedro Alves
  2014-05-23 20:59 ` [PATCH v6 2/2] enable target async by default; separate MI and target notions of async Pedro Alves
@ 2014-05-23 20:59 ` Pedro Alves
  2014-05-29 13:44 ` [pushed] Re: [PATCH v6 0/2] enable target-async by default Pedro Alves
  2 siblings, 0 replies; 42+ messages in thread
From: Pedro Alves @ 2014-05-23 20:59 UTC (permalink / raw)
  To: gdb-patches

Enabling target-async by default will require implementing sync
execution on top of an async target, much like foreground command are
implemented on the CLI in async mode.

In order to do that, we will need better control of when to print the
MI prompt.  Currently the interp->display_prompt_p hook is all we
have, and MI just always returns false, meaning, make
display_gdb_prompt a no-op.  We'll need to be able to know to print
the MI prompt in some of the conditions that display_gdb_prompt is
called from the core, but not all.

This is all a litte twisted currently.  As we can see,
display_gdb_prompt is really CLI specific, so make the console
interpreters (console/tui) themselves call it.  To be able to do that,
and add a few different observers that the interpreters can use to
distinguish when or why the the prompt is being printed:

#1 - one called whenever a command is cancelled due to an error.
#2 - another for when a foreground command just finished.

In both cases, CLI wants to print the prompt, while MI doesn't.

MI will want to print the prompt in the second case when in a special
MI mode.

The display_gdb_prompt call in interp_set made me pause.  The comment
there reads:

  /* Finally, put up the new prompt to show that we are indeed here.
     Also, display_gdb_prompt for the console does some readline magic
     which is needed for the console interpreter, at least...  */

But, that looks very much like a no-op to me currently:

 - the MI interpreter always return false in the prompt hook, meaning
   actually display no prompt.

 - the interpreter used at that point is still quiet.  And the
   console/tui interpreters return false in the prompt hook if they're
   quiet, meaning actually display no prompt.

The only remaining possible use would then be the readline magic.  But
whatever that might have been, it's not reacheable today either,
because display_gdb_prompt returns early, before touching readline if
the interpreter returns false in the display_prompt_p hook.

Tested on x86_64 Fedora 20, sync and async modes.

gdb/
2014-05-23  Pedro Alves  <palves@redhat.com>

	* cli/cli-interp.c (cli_interpreter_display_prompt_p): Delete.
	(_initialize_cli_interp): Adjust.
	* event-loop.c: Include "observer.h".
	(start_event_loop): Notify 'command_error' observers instead of
	calling display_gdb_prompt.  Remove FIXME comment.
	* event-top.c (display_gdb_prompt): Remove call into the
	interpreters.
	* inf-loop.c: Include "observer.h".
	(inferior_event_handler): Notify 'command_error' observers instead
	of calling display_gdb_prompt.
	* infrun.c (fetch_inferior_event): Notify 'sync_execution_done'
	observers instead of calling display_gdb_prompt.
	* interps.c (interp_set): Don't call display_gdb_prompt.
	(current_interp_display_prompt_p): Delete.
	* interps.h (interp_prompt_p): Delete declaration.
	(interp_prompt_p_ftype): Delete.
	(struct interp_procs) <prompt_proc_p>: Delete field.
	(current_interp_display_prompt_p): Delete declaration.
	* mi-interp.c (mi_interpreter_prompt_p): Delete.
	(_initialize_mi_interp): Adjust.
	* tui-interp.c (tui_init): Install 'sync_execution_done' and
	'command_error' observers.
	(tui_on_sync_execution_done, tui_on_command_error): New
	functions.
	(tui_display_prompt_p): Delete.
	(_initialize_tui_interp): Adjust.

gdb/doc/
2014-05-23  Pedro Alves  <palves@redhat.com>

	* observer.texi (synchronous_command_done, command_error): New
	subjects.
---
 gdb/cli/cli-interp.c  | 31 ++++++++++++++++++++-----------
 gdb/doc/observer.texi |  8 ++++++++
 gdb/event-loop.c      |  6 ++----
 gdb/event-top.c       |  5 -----
 gdb/inf-loop.c        |  3 ++-
 gdb/infrun.c          |  2 +-
 gdb/interps.c         | 30 ++++--------------------------
 gdb/interps.h         |  5 +----
 gdb/mi/mi-interp.c    |  9 ---------
 gdb/tui/tui-interp.c  | 32 ++++++++++++++++++++------------
 10 files changed, 58 insertions(+), 73 deletions(-)

diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index d3badcd..dc09b24 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -87,6 +87,24 @@ cli_on_no_history (void)
     print_no_history_reason (cli_uiout);
 }
 
+/* Observer for the sync_execution_done notification.  */
+
+static void
+cli_on_sync_execution_done (void)
+{
+  if (!interp_quiet_p (cli_interp))
+    display_gdb_prompt (NULL);
+}
+
+/* Observer for the command_error notification.  */
+
+static void
+cli_on_command_error (void)
+{
+  if (!interp_quiet_p (cli_interp))
+    display_gdb_prompt (NULL);
+}
+
 /* These implement the cli out interpreter: */
 
 static void *
@@ -98,6 +116,8 @@ cli_interpreter_init (struct interp *self, int top_level)
   observer_attach_signal_exited (cli_on_signal_exited);
   observer_attach_exited (cli_on_exited);
   observer_attach_no_history (cli_on_no_history);
+  observer_attach_sync_execution_done (cli_on_sync_execution_done);
+  observer_attach_command_error (cli_on_command_error);
 
   return NULL;
 }
@@ -135,16 +155,6 @@ cli_interpreter_suspend (void *data)
   return 1;
 }
 
-/* Don't display the prompt if we are set quiet.  */
-static int
-cli_interpreter_display_prompt_p (void *data)
-{
-  if (interp_quiet_p (NULL))
-    return 0;
-  else
-    return 1;
-}
-
 static struct gdb_exception
 cli_interpreter_exec (void *data, const char *command_str)
 {
@@ -209,7 +219,6 @@ _initialize_cli_interp (void)
     cli_interpreter_resume,	/* resume_proc */
     cli_interpreter_suspend,	/* suspend_proc */
     cli_interpreter_exec,	/* exec_proc */
-    cli_interpreter_display_prompt_p,	/* prompt_proc_p */
     cli_ui_out,			/* ui_out_proc */
     NULL,                       /* set_logging_proc */
     cli_command_loop            /* command_loop_proc */
diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
index ee43fc5..2757587 100644
--- a/gdb/doc/observer.texi
+++ b/gdb/doc/observer.texi
@@ -114,6 +114,14 @@ The inferior program is finished.
 Reverse execution: target ran out of history info.
 @end deftypefun
 
+@deftypefun void sync_execution_done (void)
+A synchronous command finished.
+@end deftypefun
+
+@deftypefun void command_error (void)
+An error was caught while executing a command.
+@end deftypefun
+
 @deftypefun void target_changed (struct target_ops *@var{target})
 The target's register contents have changed.
 @end deftypefun
diff --git a/gdb/event-loop.c b/gdb/event-loop.c
index 7939739..5999c97 100644
--- a/gdb/event-loop.c
+++ b/gdb/event-loop.c
@@ -37,6 +37,7 @@
 #include "exceptions.h"
 #include "gdb_assert.h"
 #include "gdb_select.h"
+#include "observer.h"
 
 /* Tell create_file_handler what events we are interested in.
    This is used by the select version of the event loop.  */
@@ -441,10 +442,7 @@ start_event_loop (void)
 	  /* If we long-jumped out of do_one_event, we probably didn't
 	     get around to resetting the prompt, which leaves readline
 	     in a messed-up state.  Reset it here.  */
-	  /* FIXME: this should really be a call to a hook that is
-	     interface specific, because interfaces can display the
-	     prompt in their own way.  */
-	  display_gdb_prompt (0);
+	  observer_notify_command_error ();
 	  /* This call looks bizarre, but it is required.  If the user
 	     entered a command that caused an error,
 	     after_char_processing_hook won't be called from
diff --git a/gdb/event-top.c b/gdb/event-top.c
index f690bc6..833f49d 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -243,11 +243,6 @@ display_gdb_prompt (char *new_prompt)
   /* Reset the nesting depth used when trace-commands is set.  */
   reset_command_nest_depth ();
 
-  /* Each interpreter has its own rules on displaying the command
-     prompt.  */
-  if (!current_interp_display_prompt_p ())
-    return;
-
   old_chain = make_cleanup (free_current_contents, &actual_gdb_prompt);
 
   /* Do not call the python hook on an explicit prompt change as
diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c
index f5293ae..247e9d6 100644
--- a/gdb/inf-loop.c
+++ b/gdb/inf-loop.c
@@ -31,6 +31,7 @@
 #include "continuations.h"
 #include "interps.h"
 #include "top.h"
+#include "observer.h"
 
 static int fetch_inferior_event_wrapper (gdb_client_data client_data);
 
@@ -58,7 +59,7 @@ inferior_event_handler (enum inferior_event_type event_type,
 	  do_all_intermediate_continuations (1);
 	  do_all_continuations (1);
 	  async_enable_stdin ();
-	  display_gdb_prompt (0);
+	  observer_notify_command_error ();
 	}
       break;
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 461f6e7..25626d9 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2938,7 +2938,7 @@ fetch_inferior_event (void *client_data)
      restore the prompt (a synchronous execution command has finished,
      and we're ready for input).  */
   if (interpreter_async && was_sync && !sync_execution)
-    display_gdb_prompt (0);
+    observer_notify_sync_execution_done ();
 
   if (cmd_done
       && !was_sync
diff --git a/gdb/interps.c b/gdb/interps.c
index f6b941c..5a93095 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -204,19 +204,11 @@ interp_set (struct interp *interp, int top_level)
       return 0;
     }
 
-  /* Finally, put up the new prompt to show that we are indeed here. 
-     Also, display_gdb_prompt for the console does some readline magic
-     which is needed for the console interpreter, at least...  */
-
-  if (!first_time)
+  if (!first_time && !interp_quiet_p (interp))
     {
-      if (!interp_quiet_p (interp))
-	{
-	  xsnprintf (buffer, sizeof (buffer),
-		     "Switching to interpreter \"%.24s\".\n", interp->name);
-	  ui_out_text (current_uiout, buffer);
-	}
-      display_gdb_prompt (NULL);
+      xsnprintf (buffer, sizeof (buffer),
+		 "Switching to interpreter \"%.24s\".\n", interp->name);
+      ui_out_text (current_uiout, buffer);
     }
 
   return 1;
@@ -304,20 +296,6 @@ current_interp_named_p (const char *interp_name)
   return 0;
 }
 
-/* This is called in display_gdb_prompt.  If the proc returns a zero
-   value, display_gdb_prompt will return without displaying the
-   prompt.  */
-int
-current_interp_display_prompt_p (void)
-{
-  if (current_interpreter == NULL
-      || current_interpreter->procs->prompt_proc_p == NULL)
-    return 0;
-  else
-    return current_interpreter->procs->prompt_proc_p (current_interpreter->
-						      data);
-}
-
 /* The interpreter that is active while `interp_exec' is active, NULL
    at all other times.  */
 static struct interp *command_interpreter;
diff --git a/gdb/interps.h b/gdb/interps.h
index 13edf42..197fa55 100644
--- a/gdb/interps.h
+++ b/gdb/interps.h
@@ -29,7 +29,6 @@ struct interp;
 
 extern int interp_resume (struct interp *interp);
 extern int interp_suspend (struct interp *interp);
-extern int interp_prompt_p (struct interp *interp);
 extern struct gdb_exception interp_exec (struct interp *interp,
 					 const char *command);
 extern int interp_quiet_p (struct interp *interp);
@@ -37,7 +36,6 @@ extern int interp_quiet_p (struct interp *interp);
 typedef void *(interp_init_ftype) (struct interp *self, int top_level);
 typedef int (interp_resume_ftype) (void *data);
 typedef int (interp_suspend_ftype) (void *data);
-typedef int (interp_prompt_p_ftype) (void *data);
 typedef struct gdb_exception (interp_exec_ftype) (void *data,
 						  const char *command);
 typedef void (interp_command_loop_ftype) (void *data);
@@ -53,7 +51,6 @@ struct interp_procs
   interp_resume_ftype *resume_proc;
   interp_suspend_ftype *suspend_proc;
   interp_exec_ftype *exec_proc;
-  interp_prompt_p_ftype *prompt_proc_p;
 
   /* Returns the ui_out currently used to collect results for this
      interpreter.  It can be a formatter for stdout, as is the case
@@ -79,7 +76,7 @@ extern const char *interp_name (struct interp *interp);
 extern struct interp *interp_set_temp (const char *name);
 
 extern int current_interp_named_p (const char *name);
-extern int current_interp_display_prompt_p (void);
+
 extern void current_interp_command_loop (void);
 
 /* Call this function to give the current interpreter an opportunity
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index e8e30e2..e1dd97f 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -223,14 +223,6 @@ mi_interpreter_exec (void *data, const char *command)
   return exception_none;
 }
 
-/* Never display the default GDB prompt in MI case.  */
-
-static int
-mi_interpreter_prompt_p (void *data)
-{
-  return 0;
-}
-
 void
 mi_cmd_interpreter_exec (char *command, char **argv, int argc)
 {
@@ -1142,7 +1134,6 @@ _initialize_mi_interp (void)
       mi_interpreter_resume,	/* resume_proc */
       mi_interpreter_suspend,	/* suspend_proc */
       mi_interpreter_exec,	/* exec_proc */
-      mi_interpreter_prompt_p,	/* prompt_proc_p */
       mi_ui_out, 		/* ui_out_proc */
       mi_set_logging,		/* set_logging_proc */
       mi_command_loop		/* command_loop_proc */
diff --git a/gdb/tui/tui-interp.c b/gdb/tui/tui-interp.c
index cd11148..147a424 100644
--- a/gdb/tui/tui-interp.c
+++ b/gdb/tui/tui-interp.c
@@ -104,6 +104,24 @@ tui_on_no_history (void)
     print_no_history_reason (tui_ui_out (tui_interp));
 }
 
+/* Observer for the sync_execution_done notification.  */
+
+static void
+tui_on_sync_execution_done (void)
+{
+  if (!interp_quiet_p (tui_interp))
+    display_gdb_prompt (NULL);
+}
+
+/* Observer for the command_error notification.  */
+
+static void
+tui_on_command_error (void)
+{
+  if (!interp_quiet_p (tui_interp))
+    display_gdb_prompt (NULL);
+}
+
 /* These implement the TUI interpreter.  */
 
 static void *
@@ -127,6 +145,8 @@ tui_init (struct interp *self, int top_level)
   observer_attach_signal_exited (tui_on_signal_exited);
   observer_attach_exited (tui_on_exited);
   observer_attach_no_history (tui_on_no_history);
+  observer_attach_sync_execution_done (tui_on_sync_execution_done);
+  observer_attach_command_error (tui_on_command_error);
 
   return NULL;
 }
@@ -177,17 +197,6 @@ tui_suspend (void *data)
   return 1;
 }
 
-/* Display the prompt if we are silent.  */
-
-static int
-tui_display_prompt_p (void *data)
-{
-  if (interp_quiet_p (NULL))
-    return 0;
-  else
-    return 1;
-}
-
 static struct ui_out *
 tui_ui_out (struct interp *self)
 {
@@ -214,7 +223,6 @@ _initialize_tui_interp (void)
     tui_resume,
     tui_suspend,
     tui_exec,
-    tui_display_prompt_p,
     tui_ui_out,
     NULL,
     cli_command_loop
-- 
1.9.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v6 2/2] enable target async by default; separate MI and target notions of async
  2014-05-23 20:59 [PATCH v6 0/2] enable target-async by default Pedro Alves
@ 2014-05-23 20:59 ` Pedro Alves
  2014-05-24  7:03   ` Eli Zaretskii
  2014-05-23 20:59 ` [PATCH v6 1/2] Make display_gdb_prompt CLI-only Pedro Alves
  2014-05-29 13:44 ` [pushed] Re: [PATCH v6 0/2] enable target-async by default Pedro Alves
  2 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-05-23 20:59 UTC (permalink / raw)
  To: gdb-patches

This finally makes background execution commands possible by default.

However, in order to do that, there's one last thing we need to do --
we need to separate the MI and target notions of "async".  Unlike the
CLI, where the user explicitly requests foreground vs background
execution in the execution command itself (c vs c&), MI chose to treat
"set target-async" specially -- setting it changes the default
behavior of execution commands.

So, we can't simply "set target-async" default to on, as that would
affect MI frontends.  Instead we have to make the setting MI-specific,
and teach MI about sync commands on top of an async target.

Because the "target" word in "set target-async" ends up as a potential
source of confusion, the patch adds a "set mi-async" option, and makes
"set target-async" a deprecated alias.

Rather than make the targets always async, this patch introduces a new
"maint set target-async" option so that the GDB developer can control
whether the target is async.  This makes it simpler to debug issues
arising only in the synchronous mode; important because sync mode
seems unlikely to go away.

Unlike in previous revisions, "set target-async" does not affect this
new maint parameter.  The rationale for this is that then one can
easily run the test suite in the "maint set target-async off" mode and
have tests that enable mi-async fail just like they fail on
non-async-capable targets.  This emulation is exactly the point of the
maint option.

I had asked Tom in a previous iteration to split the actual change of
the target async default to a separate patch, but it turns out that
that is quite awkward in this version of the patch, because with MI
async and target async decoupled (unlike in previous versions), if we
don't flip the default at the same time, then just "set target-async
on" alone never actually manages to do anything.  It's best to not
have that transitory state in the tree.

Given "set target-async on" now only has effect for MI, the patch goes
through the testsuite removing it from non-MI tests.  MI tests are
adjusted to use the new and less confusing "mi-async" spelling.

2014-05-23  Pedro Alves  <palves@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* NEWS: Mention "maint set target-async", "set mi-async", and that
	background execution commands are now always available.
	* target.h (target_async_permitted): Update comment.
	* target.c (target_async_permitted, target_async_permitted_1):
	Default to 1.
	(set_target_async_command): Rename to ...
	(maint_set_target_async_command): ... this.
	(show_target_async_command): Rename to ...
	(maint_show_target_async_command): ... this.
	(_initialize_target): Adjust.
	* infcmd.c (prepare_execution_command): Make extern.
	* inferior.h (prepare_execution_command): Declare.
	* infrun.c (set_observer_mode): Leave target async alone.
	* mi/mi-interp.c (mi_interpreter_init): Install
	mi_on_synchronous_command_done as synchronous_command_done
	observer.
	(mi_on_synchronous_command_done): New function.
	(mi_execute_command_input_handler): Don't print the prompt if we
	just started a synchronous command with an async target.
	(mi_on_resume): Check sync_execution before printing prompt.
	* mi/mi-main.h (mi_async_p): Declare.
	* mi/mi-main.c: Include gdbcmd.h.
	(mi_async_p): New function.
	(mi_async, mi_async_1): New globals.
	(set_mi_async_command, show_mi_async_command, mi_async): New
	functions.
	(exec_continue): Call prepare_execution_command.
	(run_one_inferior, mi_cmd_exec_run, mi_cmd_list_target_features)
	(mi_execute_async_cli_command): Use mi_async_p.
	(_initialize_mi_main): Install "set mi-async".  Make
	"target-async" a deprecated alias.

2014-02-26  Pedro Alves  <palves@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (Non-Stop Mode): Remove "set target-async 1"
	from example.
	(Asynchronous and non-stop modes): Document '-gdb-set mi-async'.
	Mention that target-async is now deprecated.
	(Maintenance Commands): Document maint set/show target-async.

2013-10-30  Pedro Alves  <palves@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* gdb.base/async-shell.exp: Don't enable target-async.
	* gdb.base/async.exp
	* gdb.base/corefile.exp (corefile_test_attach): Remove 'async'
	parameter.  Adjust.
	(top level): Don't test with "target-async".
	* gdb.base/dprintf-non-stop.exp: Don't enable target-async.
	* gdb.base/gdb-sigterm.exp: Don't test with "target-async".
	* gdb.base/inferior-died.exp: Don't enable target-async.
	* gdb.base/interrupt-noterm.exp: Likewise.
	* gdb.mi/mi-async.exp: Use "mi-async" instead of "target-async".
	* gdb.mi/mi-nonstop-exit.exp: Likewise.
	* gdb.mi/mi-nonstop.exp: Likewise.
	* gdb.mi/mi-ns-stale-regcache.exp: Likewise.
	* gdb.mi/mi-nsintrall.exp: Likewise.
	* gdb.mi/mi-nsmoribund.exp: Likewise.
	* gdb.mi/mi-nsthrexec.exp: Likewise.
	* gdb.mi/mi-watch-nonstop.exp: Likewise.
	* gdb.multi/watchpoint-multi.exp: Adjust comment.
	* gdb.python/py-evsignal.exp: Don't enable target-async.
	* gdb.python/py-evthreads.exp: Likewise.
	* gdb.python/py-prompt.exp: Likewise.
	* gdb.reverse/break-precsave.exp: Don't test with "target-async".
	* gdb.server/solib-list.exp: Don't enable target-async.
	* gdb.threads/thread-specific-bp.exp: Likewise.
	* lib/mi-support.exp: Adjust to use mi-async.
---
 gdb/NEWS                                         | 31 ++++++++++
 gdb/doc/gdb.texinfo                              | 54 +++++++++++------
 gdb/infcmd.c                                     |  6 +-
 gdb/inferior.h                                   |  7 +++
 gdb/infrun.c                                     |  1 -
 gdb/mi/mi-interp.c                               | 52 ++++++++++++++--
 gdb/mi/mi-main.c                                 | 77 +++++++++++++++++++++---
 gdb/mi/mi-main.h                                 |  4 ++
 gdb/target.c                                     | 25 ++++----
 gdb/target.h                                     |  3 +-
 gdb/testsuite/gdb.base/async-shell.exp           |  1 -
 gdb/testsuite/gdb.base/async.exp                 |  2 -
 gdb/testsuite/gdb.base/corefile.exp              | 17 +-----
 gdb/testsuite/gdb.base/dprintf-non-stop.exp      |  1 -
 gdb/testsuite/gdb.base/gdb-sigterm.exp           | 12 +---
 gdb/testsuite/gdb.base/inferior-died.exp         |  1 -
 gdb/testsuite/gdb.base/interrupt-noterm.exp      |  1 -
 gdb/testsuite/gdb.mi/mi-async.exp                |  2 +-
 gdb/testsuite/gdb.mi/mi-nonstop-exit.exp         |  2 +-
 gdb/testsuite/gdb.mi/mi-nonstop.exp              |  2 +-
 gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp    |  2 +-
 gdb/testsuite/gdb.mi/mi-nsintrall.exp            |  2 +-
 gdb/testsuite/gdb.mi/mi-nsmoribund.exp           |  2 +-
 gdb/testsuite/gdb.mi/mi-nsthrexec.exp            |  2 +-
 gdb/testsuite/gdb.mi/mi-watch-nonstop.exp        |  2 +-
 gdb/testsuite/gdb.multi/watchpoint-multi.exp     |  2 +-
 gdb/testsuite/gdb.python/py-evsignal.exp         |  1 -
 gdb/testsuite/gdb.python/py-evthreads.exp        |  1 -
 gdb/testsuite/gdb.python/py-prompt.exp           |  6 +-
 gdb/testsuite/gdb.reverse/break-precsave.exp     |  6 --
 gdb/testsuite/gdb.server/solib-list.exp          |  1 -
 gdb/testsuite/gdb.threads/thread-specific-bp.exp |  1 -
 gdb/testsuite/lib/mi-support.exp                 |  4 +-
 33 files changed, 224 insertions(+), 109 deletions(-)

diff --git a/gdb/NEWS b/gdb/NEWS
index 4663650..30c8c41 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -67,6 +67,26 @@ set auto-connect-native-target
   native target for the run, attach, etc. commands when not connected
   to any target yet.  See also "target native" below.
 
+maint set target-async (on|off)
+maint show target-async
+  This controls whether GDB targets operate in syncronous or
+  asyncronous mode.  Normally the default is asyncronous, if it is
+  available; but this can be changed to more easily debug problems
+  occurring only in syncronous mode.
+
+set mi-async (on|off)
+show mi-async
+  Control whether MI asynchronous mode is preferred.  This supersedes
+  "set target-async" of previous GDB versions.
+
+* "set target-async" is deprecated as a CLI option and is now an alias
+  for "set mi-async" (only puts MI into async mode).
+
+* Background execution commands (e.g., "c&", "s&", etc.) are now
+  possible ``out of the box'' if the target supports them.  Previously
+  the user would need to explicitly enable the possibility with the
+  "set target-async on" command.
+
 * New features in the GDB remote stub, GDBserver
 
   ** New option --debug-format=option1[,option2,...] allows one to add
@@ -137,6 +157,17 @@ PowerPC64 GNU/Linux little-endian	powerpc64le-*-linux*
   and "assf"), have been deprecated.  Use the "sharedlibrary" command, or
   its alias "share", instead.
 
+* MI changes
+
+  ** A new option "-gdb-set mi-async" replaces "-gdb-set
+     target-async".  The latter is left as a deprecated alias of the
+     former for backward compatibility.  If the target supports it,
+     CLI background execution commands are now always possible by
+     default, independently of whether the frontend stated a
+     preference for asynchronous execution with "-gdb-set mi-async".
+     Previously "-gdb-set target-async off" affected both MI execution
+     commands and CLI execution commands.
+
 *** Changes in GDB 7.7
 
 * Improved support for process record-replay and reverse debugging on
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 47d4bb7..77deff4 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -5778,9 +5778,6 @@ To enter non-stop mode, use this sequence of commands before you run
 or attach to your program:
 
 @smallexample
-# Enable the async interface.
-set target-async 1
-
 # If using the CLI, pagination breaks non-stop.
 set pagination off
 
@@ -5850,21 +5847,6 @@ the program to report that some thread has stopped before prompting for
 another command.  In background execution, @value{GDBN} immediately gives
 a command prompt so that you can issue other commands while your program runs.
 
-You need to explicitly enable asynchronous mode before you can use
-background execution commands.  You can use these commands to
-manipulate the asynchronous mode setting:
-
-@table @code
-@kindex set target-async
-@item set target-async on
-Enable asynchronous mode.
-@item set target-async off
-Disable asynchronous mode.
-@kindex show target-async
-@item show target-async
-Show the current target-async setting.
-@end table
-
 If the target doesn't support async mode, @value{GDBN} issues an error
 message if you attempt to use the background execution commands.
 
@@ -24794,12 +24776,37 @@ On some targets, @value{GDBN} is capable of processing MI commands
 even while the target is running.  This is called @dfn{asynchronous
 command execution} (@pxref{Background Execution}).  The frontend may
 specify a preferrence for asynchronous execution using the
-@code{-gdb-set target-async 1} command, which should be emitted before
+@code{-gdb-set mi-async 1} command, which should be emitted before
 either running the executable or attaching to the target.  After the
 frontend has started the executable or attached to the target, it can
 find if asynchronous execution is enabled using the
 @code{-list-target-features} command.
 
+@table @code
+@item -gdb-set mi-async on
+@item -gdb-set mi-async off
+Set whether MI is in asynchronous mode.
+
+When @code{off}, which is the default, MI execution commands (e.g.,
+@code{-exec-continue}) are foreground commands, and @value{GDBN} waits
+for the program to stop before processing further commands.
+
+When @code{on}, MI execution commands are background execution
+commands (e.g., @code{-exec-continue} becomes the equivalent of the
+@code{c&} CLI command), and so @value{GDBN} is capable of processing
+MI commands even while the target is running.
+
+@item -gdb-show mi-async
+Show whether MI asynchronous mode is enabled.
+@end table
+
+Note: In previous @value{GDBN} versions this option was called
+@code{target-async} instead of @code{mi-async}, and it had the effect
+of both putting MI in asynchronous mode and making CLI background
+commands possible.  CLI background commands are now always possible
+``out of the box'' if the target supports them.  The old spelling is
+kept as a deprecated alias for backwards compatibility.
+
 Even if @value{GDBN} can accept a command while target is running,
 many commands that access the target do not work when the target is
 running.  Therefore, asynchronous command execution is most useful
@@ -33508,6 +33515,15 @@ Control whether to show all non zero areas within a 1k block starting
 at thread local base, when using the @samp{info w32 thread-information-block}
 command.
 
+@kindex maint set target-async
+@kindex maint show target-async
+@item maint set target-async
+@itemx maint show target-async
+This controls whether @value{GDBN} targets operate in synchronous or
+asynchronous mode (@pxref{Background Execution}).  Normally the
+default is asynchronous, if it is available; but this can be changed
+to more easily debug problems occurring only in synchronous mode.
+
 @kindex maint set per-command
 @kindex maint show per-command
 @item maint set per-command
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 6511d64..df4fd40 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -497,11 +497,9 @@ Start it from the beginning? ")))
     }
 }
 
-/* Prepare for execution command.  TARGET is the target that will run
-   the command.  BACKGROUND determines whether this is a foreground
-   (synchronous) or background (asynchronous) command.  */
+/* See inferior.h.  */
 
-static void
+void
 prepare_execution_command (struct target_ops *target, int background)
 {
   /* If we get a request for running in the bg but the target
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 14f4ec8..668c888 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -164,6 +164,13 @@ extern void notice_new_inferior (ptid_t, int, int);
 extern struct value *get_return_value (struct value *function,
                                        struct type *value_type);
 
+/* Prepare for execution command.  TARGET is the target that will run
+   the command.  BACKGROUND determines whether this is a foreground
+   (synchronous) or background (asynchronous) command.  */
+
+extern void prepare_execution_command (struct target_ops *target,
+				       int background);
+
 /* Whether to start up the debuggee under a shell.
 
    If startup-with-shell is set, GDB's "run" will attempt to start up
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 25626d9..5172c13 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -235,7 +235,6 @@ set_observer_mode (char *args, int from_tty,
      going out we leave it that way.  */
   if (observer_mode)
     {
-      target_async_permitted = 1;
       pagination_enabled = 0;
       non_stop = non_stop_1 = 1;
     }
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index e1dd97f..1ce0f60 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -85,6 +85,7 @@ static void mi_breakpoint_modified (struct breakpoint *b);
 static void mi_command_param_changed (const char *param, const char *value);
 static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
 			       ssize_t len, const bfd_byte *myaddr);
+static void mi_on_synchronous_command_done (void);
 
 static int report_initial_inferior (struct inferior *inf, void *closure);
 
@@ -158,6 +159,7 @@ mi_interpreter_init (struct interp *interp, int top_level)
       observer_attach_breakpoint_modified (mi_breakpoint_modified);
       observer_attach_command_param_changed (mi_command_param_changed);
       observer_attach_memory_changed (mi_memory_changed);
+      observer_attach_synchronous_command_done (mi_on_synchronous_command_done);
 
       /* The initial inferior is created before this function is
 	 called, so we need to report it explicitly.  Use iteration in
@@ -304,6 +306,28 @@ mi_execute_command_wrapper (const char *cmd)
   mi_execute_command (cmd, stdin == instream);
 }
 
+/* Observer for the synchronous_command_done notification.  */
+
+static void
+mi_on_synchronous_command_done (void)
+{
+  /* MI generally prints a prompt after a command, indicating it's
+     ready for further input.  However, due to an historical wart, if
+     MI async, and a (CLI) synchronous command was issued, then we
+     will print the prompt right after printing "^running", even if we
+     cannot actually accept any input until the target stops.  See
+     mi_on_resume.  However, if the target is async but MI is sync,
+     then we need to output the MI prompt now, to replicate gdb's
+     behavior when neither the target nor MI are async.  (Note this
+     observer is only called by the asynchronous target event handling
+     code.)  */
+  if (!mi_async_p ())
+    {
+      fputs_unfiltered ("(gdb) \n", raw_stdout);
+      gdb_flush (raw_stdout);
+    }
+}
+
 /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER.  */
 
 static void
@@ -311,8 +335,24 @@ mi_execute_command_input_handler (char *cmd)
 {
   mi_execute_command_wrapper (cmd);
 
-  fputs_unfiltered ("(gdb) \n", raw_stdout);
-  gdb_flush (raw_stdout);
+  /* MI generally prints a prompt after a command, indicating it's
+     ready for further input.  However, due to an historical wart, if
+     MI is async, and a synchronous command was issued, then we will
+     print the prompt right after printing "^running", even if we
+     cannot actually accept any input until the target stops.  See
+     mi_on_resume.
+
+     If MI is not async, then we print the prompt when the command
+     finishes.  If the target is sync, that means output the prompt
+     now, as in that case executing a command doesn't return until the
+     command is done.  However, if the target is async, we go back to
+     the event loop and output the prompt in the
+     'synchronous_command_done' observer.  */
+  if (!target_is_async_p () || !sync_execution)
+    {
+      fputs_unfiltered ("(gdb) \n", raw_stdout);
+      gdb_flush (raw_stdout);
+    }
 }
 
 static void
@@ -928,10 +968,10 @@ mi_on_resume (ptid_t ptid)
       running_result_record_printed = 1;
       /* This is what gdb used to do historically -- printing prompt even if
 	 it cannot actually accept any input.  This will be surely removed
-	 for MI3, and may be removed even earler.  */
-      /* FIXME: review the use of target_is_async_p here -- is that
-	 what we want? */
-      if (!target_is_async_p ())
+	 for MI3, and may be removed even earlier.  SYNC_EXECUTION is
+	 checked here because we only need to emit a prompt if a
+	 synchronous command was issued when the target is async.  */
+      if (!target_is_async_p () || sync_execution)
 	fputs_unfiltered ("(gdb) \n", raw_stdout);
     }
   gdb_flush (raw_stdout);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 9ab4886..96dfc71 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -54,6 +54,7 @@
 #include "ada-lang.h"
 #include "linespec.h"
 #include "extension.h"
+#include "gdbcmd.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -105,6 +106,45 @@ static int register_changed_p (int regnum, struct regcache *,
 static void output_register (struct frame_info *, int regnum, int format,
 			     int skip_unavailable);
 
+/* Controls whether the frontend wants MI in async mode.  */
+static int mi_async = 0;
+
+/* The set command writes to this variable.  If the inferior is
+   executing, mi_async is *not* updated.  */
+static int mi_async_1 = 0;
+
+static void
+set_mi_async_command (char *args, int from_tty,
+		      struct cmd_list_element *c)
+{
+  if (have_live_inferiors ())
+    {
+      mi_async_1 = mi_async;
+      error (_("Cannot change this setting while the inferior is running."));
+    }
+
+  mi_async = mi_async_1;
+}
+
+static void
+show_mi_async_command (struct ui_file *file, int from_tty,
+		       struct cmd_list_element *c,
+		       const char *value)
+{
+  fprintf_filtered (file,
+		    _("Whether MI is in asynchronous mode is %s.\n"),
+		    value);
+}
+
+/* A wrapper for target_can_async_p that takes the MI setting into
+   account.  */
+
+int
+mi_async_p (void)
+{
+  return mi_async && target_can_async_p ();
+}
+
 /* Command implementations.  FIXME: Is this libgdb?  No.  This is the MI
    layer that calls libgdb.  Any operation used in the below should be
    formalized.  */
@@ -229,6 +269,8 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
 static void
 exec_continue (char **argv, int argc)
 {
+  prepare_execution_command (&current_target, mi_async_p ());
+
   if (non_stop)
     {
       /* In non-stop mode, 'resume' always resumes a single thread.
@@ -395,8 +437,8 @@ run_one_inferior (struct inferior *inf, void *arg)
       switch_to_thread (null_ptid);
       set_current_program_space (inf->pspace);
     }
-  mi_execute_cli_command (run_cmd, target_can_async_p (),
-			  target_can_async_p () ? "&" : NULL);
+  mi_execute_cli_command (run_cmd, mi_async_p (),
+			  mi_async_p () ? "&" : NULL);
   return 0;
 }
 
@@ -450,8 +492,8 @@ mi_cmd_exec_run (char *command, char **argv, int argc)
     {
       const char *run_cmd = start_p ? "start" : "run";
 
-      mi_execute_cli_command (run_cmd, target_can_async_p (),
-			      target_can_async_p () ? "&" : NULL);
+      mi_execute_cli_command (run_cmd, mi_async_p (),
+			      mi_async_p () ? "&" : NULL);
     }
 }
 
@@ -1838,11 +1880,10 @@ mi_cmd_list_target_features (char *command, char **argv, int argc)
       struct ui_out *uiout = current_uiout;
 
       cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
-      if (target_can_async_p ())
+      if (mi_async_p ())
 	ui_out_field_string (uiout, NULL, "async");
       if (target_can_execute_reverse)
 	ui_out_field_string (uiout, NULL, "reverse");
-
       do_cleanups (cleanup);
       return;
     }
@@ -2269,7 +2310,7 @@ mi_execute_async_cli_command (char *cli_command, char **argv, int argc)
   struct cleanup *old_cleanups;
   char *run;
 
-  if (target_can_async_p ())
+  if (mi_async_p ())
     run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
   else
     run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
@@ -2920,3 +2961,25 @@ mi_cmd_trace_frame_collected (char *command, char **argv, int argc)
 
   do_cleanups (old_chain);
 }
+
+void
+_initialize_mi_main (void)
+{
+  struct cmd_list_element *c;
+
+  add_setshow_boolean_cmd ("mi-async", class_run,
+			   &mi_async_1, _("\
+Set whether MI asynchronous mode is enabled."), _("\
+Show whether MI asynchronous mode is enabled."), _("\
+Tells GDB whether MI should be in asynchronous mode."),
+			   set_mi_async_command,
+			   show_mi_async_command,
+			   &setlist,
+			   &showlist);
+
+  /* Alias old "target-async" to "mi-async".  */
+  c = add_alias_cmd ("target-async", "mi-async", class_run, 0, &setlist);
+  deprecate_cmd (c, "set mi-async");
+  c = add_alias_cmd ("target-async", "mi-async", class_run, 0, &showlist);
+  deprecate_cmd (c, "show mi-async");
+}
diff --git a/gdb/mi/mi-main.h b/gdb/mi/mi-main.h
index c32845d..530aeb7 100644
--- a/gdb/mi/mi-main.h
+++ b/gdb/mi/mi-main.h
@@ -28,6 +28,10 @@ extern void mi_load_progress (const char *section_name,
 
 extern void mi_print_timing_maybe (void);
 
+/* Whether MI is in async mode.  */
+
+extern int mi_async_p (void);
+
 extern char *current_token;
 
 extern int running_result_record_printed;
diff --git a/gdb/target.c b/gdb/target.c
index cf86e73..2fe3269 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -4104,16 +4104,17 @@ maintenance_print_target_stack (char *cmd, int from_tty)
     }
 }
 
-/* Controls if async mode is permitted.  */
-int target_async_permitted = 0;
+/* Controls if targets can report that they can/are async.  This is
+   just for maintainers to use when debugging gdb.  */
+int target_async_permitted = 1;
 
 /* The set command writes to this variable.  If the inferior is
    executing, target_async_permitted is *not* updated.  */
-static int target_async_permitted_1 = 0;
+static int target_async_permitted_1 = 1;
 
 static void
-set_target_async_command (char *args, int from_tty,
-			  struct cmd_list_element *c)
+maint_set_target_async_command (char *args, int from_tty,
+				struct cmd_list_element *c)
 {
   if (have_live_inferiors ())
     {
@@ -4125,9 +4126,9 @@ set_target_async_command (char *args, int from_tty,
 }
 
 static void
-show_target_async_command (struct ui_file *file, int from_tty,
-			   struct cmd_list_element *c,
-			   const char *value)
+maint_show_target_async_command (struct ui_file *file, int from_tty,
+				 struct cmd_list_element *c,
+				 const char *value)
 {
   fprintf_filtered (file,
 		    _("Controlling the inferior in "
@@ -4232,10 +4233,10 @@ result in significant performance improvement for remote targets."),
 Set whether gdb controls the inferior in asynchronous mode."), _("\
 Show whether gdb controls the inferior in asynchronous mode."), _("\
 Tells gdb whether to control the inferior in asynchronous mode."),
-			   set_target_async_command,
-			   show_target_async_command,
-			   &setlist,
-			   &showlist);
+			   maint_set_target_async_command,
+			   maint_show_target_async_command,
+			   &maintenance_set_cmdlist,
+			   &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd ("may-write-registers", class_support,
 			   &may_write_registers_1, _("\
diff --git a/gdb/target.h b/gdb/target.h
index 9371529..face210 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1619,8 +1619,7 @@ extern int default_child_has_execution (struct target_ops *ops,
 #define target_can_lock_scheduler \
      (current_target.to_has_thread_control & tc_schedlock)
 
-/* Should the target enable async mode if it is supported?  Temporary
-   cludge until async mode is a strict superset of sync mode.  */
+/* Controls whether async mode is permitted.  */
 extern int target_async_permitted;
 
 /* Can the target support asynchronous execution?  */
diff --git a/gdb/testsuite/gdb.base/async-shell.exp b/gdb/testsuite/gdb.base/async-shell.exp
index 4890a59..f0550bc 100644
--- a/gdb/testsuite/gdb.base/async-shell.exp
+++ b/gdb/testsuite/gdb.base/async-shell.exp
@@ -31,7 +31,6 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} $srcfile] } {
 
 set gdbindex_warning_re "warning: Skipping \[^\r\n\]+ \\.gdb_index section \[^\r\n\]*\r\nDo \"set use-deprecated-index-sections on\" before the file is read\r\nto use the section anyway\\."
 
-gdb_test_no_output "set target-async on "
 gdb_test_no_output "set non-stop on"
 gdb_test "run &" "Starting program: \[^\r\n\]*(\r\n$gdbindex_warning_re)?"
 
diff --git a/gdb/testsuite/gdb.base/async.exp b/gdb/testsuite/gdb.base/async.exp
index f0a18e8..0f99b01 100644
--- a/gdb/testsuite/gdb.base/async.exp
+++ b/gdb/testsuite/gdb.base/async.exp
@@ -25,8 +25,6 @@ if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} {
     return -1
 }
 
-gdb_test_no_output "set target-async on"
-
 #
 # set it up at a breakpoint so we can play with it
 #
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
index 6eb1f02..bde2de8 100644
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -241,7 +241,7 @@ gdb_exit
 
 # Test an attach command will clear any loaded core file.
 
-proc corefile_test_attach {{async 0}} {
+proc corefile_test_attach {} {
     global binfile corefile gdb_prompt
 
     if ![is_remote target] {
@@ -257,11 +257,6 @@ proc corefile_test_attach {{async 0}} {
 
 	gdb_start
 
-	if {$async} {
-	    gdb_test_no_output "set target-async on" \
-		"enable target-async for attach tests"
-	}
-
 	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"
 
@@ -298,13 +293,3 @@ 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.base/dprintf-non-stop.exp b/gdb/testsuite/gdb.base/dprintf-non-stop.exp
index fdaa5c1..df1e270 100644
--- a/gdb/testsuite/gdb.base/dprintf-non-stop.exp
+++ b/gdb/testsuite/gdb.base/dprintf-non-stop.exp
@@ -26,7 +26,6 @@ if [prepare_for_testing "failed to prepare for dprintf with non-stop" \
     return -1
 }
 
-gdb_test_no_output "set target-async on"
 gdb_test_no_output "set non-stop on"
 
 if ![runto main] {
diff --git a/gdb/testsuite/gdb.base/gdb-sigterm.exp b/gdb/testsuite/gdb.base/gdb-sigterm.exp
index f52517c..df0de42 100644
--- a/gdb/testsuite/gdb.base/gdb-sigterm.exp
+++ b/gdb/testsuite/gdb.base/gdb-sigterm.exp
@@ -79,17 +79,7 @@ proc do_test { pass } {
 # 50 runs should be approx. a safe number to be sure it is fixed now.
 
 for {set pass 0} {$pass < 50} {incr pass} {
-
     clean_restart ${testfile}
-    gdb_test_no_output "set target-async off" ""
-    with_test_prefix "sync" {
-        do_test $pass
-    }
-
-    clean_restart ${testfile}
-    gdb_test_no_output "set target-async on" ""
-    with_test_prefix "async" {
-        do_test $pass
-    }
+    do_test $pass
 }
 pass "$pass SIGTERM passes"
diff --git a/gdb/testsuite/gdb.base/inferior-died.exp b/gdb/testsuite/gdb.base/inferior-died.exp
index 33f92e9..152bdd8 100644
--- a/gdb/testsuite/gdb.base/inferior-died.exp
+++ b/gdb/testsuite/gdb.base/inferior-died.exp
@@ -38,7 +38,6 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c] } {
 }
 
 gdb_test_no_output "set detach-on-fork off"
-gdb_test_no_output "set target-async on"
 gdb_test_no_output "set non-stop on"
 
 if ![runto_main] {
diff --git a/gdb/testsuite/gdb.base/interrupt-noterm.exp b/gdb/testsuite/gdb.base/interrupt-noterm.exp
index a22acd2..5c92b97 100644
--- a/gdb/testsuite/gdb.base/interrupt-noterm.exp
+++ b/gdb/testsuite/gdb.base/interrupt-noterm.exp
@@ -22,7 +22,6 @@ if [prepare_for_testing "failed to prepare for testing" \
 
 # Pretend there's no terminal.
 gdb_test_no_output "set interactive-mode off"
-gdb_test_no_output "set target-async on"
 
 if ![runto main] {
     fail "Can't run to main"
diff --git a/gdb/testsuite/gdb.mi/mi-async.exp b/gdb/testsuite/gdb.mi/mi-async.exp
index e41701d..0df4c98 100644
--- a/gdb/testsuite/gdb.mi/mi-async.exp
+++ b/gdb/testsuite/gdb.mi/mi-async.exp
@@ -27,7 +27,7 @@ if { !([isnative] && [istarget *-linux*]) } then {
 
 # The plan is for async mode to become the default but toggle for now.
 set saved_gdbflags $GDBFLAGS
-set GDBFLAGS [concat $GDBFLAGS " -ex \"set target-async on\""]
+set GDBFLAGS [concat $GDBFLAGS " -ex \"set mi-async on\""]
 
 load_lib mi-support.exp
 
diff --git a/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp b/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp
index 3727d81..5187b40 100644
--- a/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp
+++ b/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp
@@ -40,7 +40,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nonstop.exp b/gdb/testsuite/gdb.mi/mi-nonstop.exp
index 5ef74ed..ba7dfd4 100644
--- a/gdb/testsuite/gdb.mi/mi-nonstop.exp
+++ b/gdb/testsuite/gdb.mi/mi-nonstop.exp
@@ -50,7 +50,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp
index 754689c..ae9e5f2 100644
--- a/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp
+++ b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp
@@ -53,7 +53,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nsintrall.exp b/gdb/testsuite/gdb.mi/mi-nsintrall.exp
index f613e7f..ac1209e 100644
--- a/gdb/testsuite/gdb.mi/mi-nsintrall.exp
+++ b/gdb/testsuite/gdb.mi/mi-nsintrall.exp
@@ -40,7 +40,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp
index 350c060..0ff04ca 100644
--- a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp
+++ b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp
@@ -40,7 +40,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nsthrexec.exp b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp
index 85617d0..008a831 100644
--- a/gdb/testsuite/gdb.mi/mi-nsthrexec.exp
+++ b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp
@@ -50,7 +50,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp b/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp
index 3dbf4c7..44371c8 100644
--- a/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp
+++ b/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp
@@ -52,7 +52,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
index b7fb0a9..e6a8957 100644
--- a/gdb/testsuite/gdb.multi/watchpoint-multi.exp
+++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
@@ -37,7 +37,7 @@ if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executa
 
 clean_restart $executable
 
-# Simulate non-stop+target-async which also uses breakpoint always-inserted.
+# Simulate non-stop which also uses breakpoint always-inserted.
 gdb_test_no_output "set breakpoint always-inserted on"
 # displaced-stepping is also needed as other GDB sometimes still removes the
 # breakpoints, even with always-inserted on.
diff --git a/gdb/testsuite/gdb.python/py-evsignal.exp b/gdb/testsuite/gdb.python/py-evsignal.exp
index af3d53c..530fd07 100644
--- a/gdb/testsuite/gdb.python/py-evsignal.exp
+++ b/gdb/testsuite/gdb.python/py-evsignal.exp
@@ -35,7 +35,6 @@ gdb_test_no_output "python exec (open ('${pyfile}').read ())" ""
 
 gdb_test "test-events" "Event testers registered."
 gdb_test_no_output "set non-stop on"
-gdb_test_no_output "set target-async on"
 
 gdb_run_cmd
 gdb_test_multiple "" "Signal Thread 3"  {
diff --git a/gdb/testsuite/gdb.python/py-evthreads.exp b/gdb/testsuite/gdb.python/py-evthreads.exp
index ffa322f..d62624e 100644
--- a/gdb/testsuite/gdb.python/py-evthreads.exp
+++ b/gdb/testsuite/gdb.python/py-evthreads.exp
@@ -40,7 +40,6 @@ gdb_test_no_output "python exec (open ('${pyfile}').read ())" ""
 
 gdb_test "test-events" "Event testers registered."
 gdb_test_no_output "set non-stop on"
-gdb_test_no_output "set target-async on"
 
 gdb_breakpoint "main"
 gdb_breakpoint "thread2"
diff --git a/gdb/testsuite/gdb.python/py-prompt.exp b/gdb/testsuite/gdb.python/py-prompt.exp
index e376c05..ebe4cb6 100644
--- a/gdb/testsuite/gdb.python/py-prompt.exp
+++ b/gdb/testsuite/gdb.python/py-prompt.exp
@@ -90,8 +90,7 @@ if { [istarget "*-*-cygwin*"] } {
     set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
 }
 
-set GDBFLAGS [concat $tmp_gdbflags " -ex \"set target-async on\""]
-set GDBFLAGS [concat $GDBFLAGS " -ex \"set pagination off\""]
+set GDBFLAGS [concat $tmp_gdbflags " -ex \"set pagination off\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"attach $testpid\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"continue&\""]
@@ -107,8 +106,7 @@ gdb_test "python print (\"'\" + str(p\[0\]) + \"'\")" "'$gdb_prompt_fail '" \
 	 "prompt_hook argument is default prompt. 3"
 gdb_exit
 
-set GDBFLAGS [concat $tmp_gdbflags " -ex \"set target-async on\""]
-set GDBFLAGS [concat $GDBFLAGS " -ex \"set pagination off\""]
+set GDBFLAGS [concat $tmp_gdbflags " -ex \"set pagination off\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"attach $testpid\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"interrupt\""]
diff --git a/gdb/testsuite/gdb.reverse/break-precsave.exp b/gdb/testsuite/gdb.reverse/break-precsave.exp
index f1e6c69..3206e3c 100644
--- a/gdb/testsuite/gdb.reverse/break-precsave.exp
+++ b/gdb/testsuite/gdb.reverse/break-precsave.exp
@@ -110,9 +110,3 @@ proc precsave_tests {} {
 }
 
 precsave_tests
-
-with_test_prefix "target-async" {
-    clean_restart $testfile
-    gdb_test_no_output "set target-async on"
-    precsave_tests
-}
diff --git a/gdb/testsuite/gdb.server/solib-list.exp b/gdb/testsuite/gdb.server/solib-list.exp
index 8cc3edc..4504a23 100644
--- a/gdb/testsuite/gdb.server/solib-list.exp
+++ b/gdb/testsuite/gdb.server/solib-list.exp
@@ -66,7 +66,6 @@ foreach nonstop { 0 1 } { with_test_prefix "non-stop $nonstop" {
     gdb_test "disconnect" ".*"
 
     gdb_test "set non-stop $nonstop"
-    gdb_test "set target-async $nonstop"
 
     # It is required for the non-stop mode, GDB would try to step over
     # _dl_debug_state breakpoint will still only ld.so loaded in gdbserver.
diff --git a/gdb/testsuite/gdb.threads/thread-specific-bp.exp b/gdb/testsuite/gdb.threads/thread-specific-bp.exp
index b8416d7..4273e1d 100644
--- a/gdb/testsuite/gdb.threads/thread-specific-bp.exp
+++ b/gdb/testsuite/gdb.threads/thread-specific-bp.exp
@@ -122,6 +122,5 @@ check_thread_specific_breakpoint "all-stop"
 clean_restart ${binfile}
 
 # Test non-stop mode.
-gdb_test_no_output "set target-async on" "set async mode"
 gdb_test_no_output "set non-stop on" "set non-stop mode"
 check_thread_specific_breakpoint "non-stop"
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 09a514b..e5d2de3 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1002,10 +1002,10 @@ proc mi_detect_async {} {
     global async
     global mi_gdb_prompt
 
-    send_gdb "show target-async\n"
+    send_gdb "show mi-async\n"
 
     gdb_expect {
-	-re ".*Controlling the inferior in asynchronous mode is on...*$mi_gdb_prompt$" {
+	-re "asynchronous mode is on...*$mi_gdb_prompt$" {
 	    set async 1
 	}
 	-re ".*$mi_gdb_prompt$" {
-- 
1.9.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v6 0/2] enable target-async by default
@ 2014-05-23 20:59 Pedro Alves
  2014-05-23 20:59 ` [PATCH v6 2/2] enable target async by default; separate MI and target notions of async Pedro Alves
                   ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Pedro Alves @ 2014-05-23 20:59 UTC (permalink / raw)
  To: gdb-patches

This is version 6 of the patch series to enable target-async by
default.  Most of the series is now in.

There's actually a third patch this depends on, here:

  https://sourceware.org/ml/gdb-patches/2014-05/msg00590.html

As I had already posted it today, I figured moving it to the series
and posting it again would possibly confuse things.

Tested on x86_64 Fedora 20, with different permutations of target
async and mi async.  No regressions.

Pedro Alves (2):
  Make display_gdb_prompt CLI-only.
  enable target async by default; separate MI and target notions of
    async

 gdb/NEWS                                         | 31 ++++++++++
 gdb/cli/cli-interp.c                             | 31 ++++++----
 gdb/doc/gdb.texinfo                              | 54 +++++++++++------
 gdb/doc/observer.texi                            |  8 +++
 gdb/event-loop.c                                 |  6 +-
 gdb/event-top.c                                  |  5 --
 gdb/inf-loop.c                                   |  3 +-
 gdb/infcmd.c                                     |  6 +-
 gdb/inferior.h                                   |  7 +++
 gdb/infrun.c                                     |  3 +-
 gdb/interps.c                                    | 30 ++-------
 gdb/interps.h                                    |  5 +-
 gdb/mi/mi-interp.c                               | 61 ++++++++++++++-----
 gdb/mi/mi-main.c                                 | 77 +++++++++++++++++++++---
 gdb/mi/mi-main.h                                 |  4 ++
 gdb/target.c                                     | 25 ++++----
 gdb/target.h                                     |  3 +-
 gdb/testsuite/gdb.base/async-shell.exp           |  1 -
 gdb/testsuite/gdb.base/async.exp                 |  2 -
 gdb/testsuite/gdb.base/corefile.exp              | 17 +-----
 gdb/testsuite/gdb.base/dprintf-non-stop.exp      |  1 -
 gdb/testsuite/gdb.base/gdb-sigterm.exp           | 12 +---
 gdb/testsuite/gdb.base/inferior-died.exp         |  1 -
 gdb/testsuite/gdb.base/interrupt-noterm.exp      |  1 -
 gdb/testsuite/gdb.mi/mi-async.exp                |  2 +-
 gdb/testsuite/gdb.mi/mi-nonstop-exit.exp         |  2 +-
 gdb/testsuite/gdb.mi/mi-nonstop.exp              |  2 +-
 gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp    |  2 +-
 gdb/testsuite/gdb.mi/mi-nsintrall.exp            |  2 +-
 gdb/testsuite/gdb.mi/mi-nsmoribund.exp           |  2 +-
 gdb/testsuite/gdb.mi/mi-nsthrexec.exp            |  2 +-
 gdb/testsuite/gdb.mi/mi-watch-nonstop.exp        |  2 +-
 gdb/testsuite/gdb.multi/watchpoint-multi.exp     |  2 +-
 gdb/testsuite/gdb.python/py-evsignal.exp         |  1 -
 gdb/testsuite/gdb.python/py-evthreads.exp        |  1 -
 gdb/testsuite/gdb.python/py-prompt.exp           |  6 +-
 gdb/testsuite/gdb.reverse/break-precsave.exp     |  6 --
 gdb/testsuite/gdb.server/solib-list.exp          |  1 -
 gdb/testsuite/gdb.threads/thread-specific-bp.exp |  1 -
 gdb/testsuite/lib/mi-support.exp                 |  4 +-
 gdb/tui/tui-interp.c                             | 32 ++++++----
 41 files changed, 282 insertions(+), 182 deletions(-)

-- 
1.9.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v6 2/2] enable target async by default; separate MI and target notions of async
  2014-05-23 20:59 ` [PATCH v6 2/2] enable target async by default; separate MI and target notions of async Pedro Alves
@ 2014-05-24  7:03   ` Eli Zaretskii
  2014-05-29 13:49     ` Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Eli Zaretskii @ 2014-05-24  7:03 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

> From: Pedro Alves <palves@redhat.com>
> Date: Fri, 23 May 2014 21:59:13 +0100
> 
> This finally makes background execution commands possible by default.

Thanks.

> +Note: In previous @value{GDBN} versions this option was called

It is best to state here the last GDB version where that was true, as
in

  In @value{GDBN} version X.YZ and earlier, this option was called ...

That's because "previous versions" is a relative reference, which will
be inaccurate in the version after the one where this text will be
included.

The documentation parts are OK with this fixed.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [pushed] Re: [PATCH v6 0/2] enable target-async by default
  2014-05-23 20:59 [PATCH v6 0/2] enable target-async by default Pedro Alves
  2014-05-23 20:59 ` [PATCH v6 2/2] enable target async by default; separate MI and target notions of async Pedro Alves
  2014-05-23 20:59 ` [PATCH v6 1/2] Make display_gdb_prompt CLI-only Pedro Alves
@ 2014-05-29 13:44 ` Pedro Alves
  2014-07-01 16:28   ` Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
  2014-10-05 14:00   ` Crash regression for annota1.exp w/vDSO debuginfo [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
  2 siblings, 2 replies; 42+ messages in thread
From: Pedro Alves @ 2014-05-29 13:44 UTC (permalink / raw)
  To: gdb-patches

On 05/23/2014 09:59 PM, Pedro Alves wrote:

> There's actually a third patch this depends on, here:
> 
>   https://sourceware.org/ml/gdb-patches/2014-05/msg00590.html

I went ahead and pushed this all in, with Eli's comments addressed.

"set target-async" is dead, long live "set target-async"!

I think this is a significant milestone, which has been quite long
in the making, with several people on and off pushing for it
little by little.  Thanks everyone.

Apologies for the haste, but, the 7.8 branch point date is
approaching, and I'd like to get async-by-default into 7.8,
and I think the sooner this gets into the tree before the
branch, the better.

If something goes badly wrong, we can flip the default back
to target-async off, and make target-async depend on mi-async again
(make -gdb-set target-async flip both globals), which makes most of
the new MI code dead.  (Or we can always just revert.)

Thanks,
-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v6 2/2] enable target async by default; separate MI and target notions of async
  2014-05-24  7:03   ` Eli Zaretskii
@ 2014-05-29 13:49     ` Pedro Alves
  2014-07-30 18:40       ` Doug Evans
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-05-29 13:49 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

On 05/24/2014 08:03 AM, Eli Zaretskii wrote:
>> From: Pedro Alves <palves@redhat.com>
>> Date: Fri, 23 May 2014 21:59:13 +0100
>>
>> This finally makes background execution commands possible by default.
> 
> Thanks.
> 
>> +Note: In previous @value{GDBN} versions this option was called
> 
> It is best to state here the last GDB version where that was true, as
> in
> 
>   In @value{GDBN} version X.YZ and earlier, this option was called ...
> 
> That's because "previous versions" is a relative reference, which will
> be inaccurate in the version after the one where this text will be
> included.

Indeed, wholeheartedly agreed.  I'll often complain about the same.
It goes to show how easy it is to fall into the trap.

> 
> The documentation parts are OK with this fixed.

Thanks Eli.  I did that exactly:

 +Note: In @value{GDBN} version 7.7 and earlier, this option was called
 +@code{target-async} instead of @code{mi-async}, and it had the effect
 +of both putting MI in asynchronous mode and making CLI background

Below's what I pushed.

8<------------
Subject: [PATCH] enable target async by default; separate MI and target
 notions of async

This finally makes background execution commands possible by default.

However, in order to do that, there's one last thing we need to do --
we need to separate the MI and target notions of "async".  Unlike the
CLI, where the user explicitly requests foreground vs background
execution in the execution command itself (c vs c&), MI chose to treat
"set target-async" specially -- setting it changes the default
behavior of execution commands.

So, we can't simply "set target-async" default to on, as that would
affect MI frontends.  Instead we have to make the setting MI-specific,
and teach MI about sync commands on top of an async target.

Because the "target" word in "set target-async" ends up as a potential
source of confusion, the patch adds a "set mi-async" option, and makes
"set target-async" a deprecated alias.

Rather than make the targets always async, this patch introduces a new
"maint set target-async" option so that the GDB developer can control
whether the target is async.  This makes it simpler to debug issues
arising only in the synchronous mode; important because sync mode
seems unlikely to go away.

Unlike in previous revisions, "set target-async" does not affect this
new maint parameter.  The rationale for this is that then one can
easily run the test suite in the "maint set target-async off" mode and
have tests that enable mi-async fail just like they fail on
non-async-capable targets.  This emulation is exactly the point of the
maint option.

I had asked Tom in a previous iteration to split the actual change of
the target async default to a separate patch, but it turns out that
that is quite awkward in this version of the patch, because with MI
async and target async decoupled (unlike in previous versions), if we
don't flip the default at the same time, then just "set target-async
on" alone never actually manages to do anything.  It's best to not
have that transitory state in the tree.

Given "set target-async on" now only has effect for MI, the patch goes
through the testsuite removing it from non-MI tests.  MI tests are
adjusted to use the new and less confusing "mi-async" spelling.

2014-05-29  Pedro Alves  <palves@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* NEWS: Mention "maint set target-async", "set mi-async", and that
	background execution commands are now always available.
	* target.h (target_async_permitted): Update comment.
	* target.c (target_async_permitted, target_async_permitted_1):
	Default to 1.
	(set_target_async_command): Rename to ...
	(maint_set_target_async_command): ... this.
	(show_target_async_command): Rename to ...
	(maint_show_target_async_command): ... this.
	(_initialize_target): Adjust.
	* infcmd.c (prepare_execution_command): Make extern.
	* inferior.h (prepare_execution_command): Declare.
	* infrun.c (set_observer_mode): Leave target async alone.
	* mi/mi-interp.c (mi_interpreter_init): Install
	mi_on_sync_execution_done as sync_execution_done observer.
	(mi_on_sync_execution_done): New function.
	(mi_execute_command_input_handler): Don't print the prompt if we
	just started a synchronous command with an async target.
	(mi_on_resume): Check sync_execution before printing prompt.
	* mi/mi-main.h (mi_async_p): Declare.
	* mi/mi-main.c: Include gdbcmd.h.
	(mi_async_p): New function.
	(mi_async, mi_async_1): New globals.
	(set_mi_async_command, show_mi_async_command, mi_async): New
	functions.
	(exec_continue): Call prepare_execution_command.
	(run_one_inferior, mi_cmd_exec_run, mi_cmd_list_target_features)
	(mi_execute_async_cli_command): Use mi_async_p.
	(_initialize_mi_main): Install "set mi-async".  Make
	"target-async" a deprecated alias.

2014-05-29  Pedro Alves  <palves@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (Non-Stop Mode): Remove "set target-async 1"
	from example.
	(Asynchronous and non-stop modes): Document '-gdb-set mi-async'.
	Mention that target-async is now deprecated.
	(Maintenance Commands): Document maint set/show target-async.

2014-05-29  Pedro Alves  <palves@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* gdb.base/async-shell.exp: Don't enable target-async.
	* gdb.base/async.exp
	* gdb.base/corefile.exp (corefile_test_attach): Remove 'async'
	parameter.  Adjust.
	(top level): Don't test with "target-async".
	* gdb.base/dprintf-non-stop.exp: Don't enable target-async.
	* gdb.base/gdb-sigterm.exp: Don't test with "target-async".
	* gdb.base/inferior-died.exp: Don't enable target-async.
	* gdb.base/interrupt-noterm.exp: Likewise.
	* gdb.mi/mi-async.exp: Use "mi-async" instead of "target-async".
	* gdb.mi/mi-nonstop-exit.exp: Likewise.
	* gdb.mi/mi-nonstop.exp: Likewise.
	* gdb.mi/mi-ns-stale-regcache.exp: Likewise.
	* gdb.mi/mi-nsintrall.exp: Likewise.
	* gdb.mi/mi-nsmoribund.exp: Likewise.
	* gdb.mi/mi-nsthrexec.exp: Likewise.
	* gdb.mi/mi-watch-nonstop.exp: Likewise.
	* gdb.multi/watchpoint-multi.exp: Adjust comment.
	* gdb.python/py-evsignal.exp: Don't enable target-async.
	* gdb.python/py-evthreads.exp: Likewise.
	* gdb.python/py-prompt.exp: Likewise.
	* gdb.reverse/break-precsave.exp: Don't test with "target-async".
	* gdb.server/solib-list.exp: Don't enable target-async.
	* gdb.threads/thread-specific-bp.exp: Likewise.
	* lib/mi-support.exp: Adjust to use mi-async.
---
 gdb/ChangeLog                                    | 34 +++++++++++
 gdb/doc/ChangeLog                                |  9 +++
 gdb/testsuite/ChangeLog                          | 29 +++++++++
 gdb/NEWS                                         | 31 ++++++++++
 gdb/doc/gdb.texinfo                              | 54 +++++++++++------
 gdb/infcmd.c                                     |  6 +-
 gdb/inferior.h                                   |  7 +++
 gdb/infrun.c                                     |  1 -
 gdb/mi/mi-interp.c                               | 52 ++++++++++++++--
 gdb/mi/mi-main.c                                 | 77 +++++++++++++++++++++---
 gdb/mi/mi-main.h                                 |  4 ++
 gdb/target.c                                     | 25 ++++----
 gdb/target.h                                     |  3 +-
 gdb/testsuite/gdb.base/async-shell.exp           |  1 -
 gdb/testsuite/gdb.base/async.exp                 |  2 -
 gdb/testsuite/gdb.base/corefile.exp              | 17 +-----
 gdb/testsuite/gdb.base/dprintf-non-stop.exp      |  1 -
 gdb/testsuite/gdb.base/gdb-sigterm.exp           | 12 +---
 gdb/testsuite/gdb.base/inferior-died.exp         |  1 -
 gdb/testsuite/gdb.base/interrupt-noterm.exp      |  1 -
 gdb/testsuite/gdb.mi/mi-async.exp                |  2 +-
 gdb/testsuite/gdb.mi/mi-nonstop-exit.exp         |  2 +-
 gdb/testsuite/gdb.mi/mi-nonstop.exp              |  2 +-
 gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp    |  2 +-
 gdb/testsuite/gdb.mi/mi-nsintrall.exp            |  2 +-
 gdb/testsuite/gdb.mi/mi-nsmoribund.exp           |  2 +-
 gdb/testsuite/gdb.mi/mi-nsthrexec.exp            |  2 +-
 gdb/testsuite/gdb.mi/mi-watch-nonstop.exp        |  2 +-
 gdb/testsuite/gdb.multi/watchpoint-multi.exp     |  2 +-
 gdb/testsuite/gdb.python/py-evsignal.exp         |  1 -
 gdb/testsuite/gdb.python/py-evthreads.exp        |  1 -
 gdb/testsuite/gdb.python/py-prompt.exp           |  6 +-
 gdb/testsuite/gdb.reverse/break-precsave.exp     |  6 --
 gdb/testsuite/gdb.server/solib-list.exp          |  1 -
 gdb/testsuite/gdb.threads/thread-specific-bp.exp |  1 -
 gdb/testsuite/lib/mi-support.exp                 |  4 +-
 36 files changed, 296 insertions(+), 109 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f270c61..341698b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,4 +1,38 @@
 2014-05-29  Pedro Alves  <palves@redhat.com>
+	    Tom Tromey  <tromey@redhat.com>
+
+	* NEWS: Mention "maint set target-async", "set mi-async", and that
+	background execution commands are now always available.
+	* target.h (target_async_permitted): Update comment.
+	* target.c (target_async_permitted, target_async_permitted_1):
+	Default to 1.
+	(set_target_async_command): Rename to ...
+	(maint_set_target_async_command): ... this.
+	(show_target_async_command): Rename to ...
+	(maint_show_target_async_command): ... this.
+	(_initialize_target): Adjust.
+	* infcmd.c (prepare_execution_command): Make extern.
+	* inferior.h (prepare_execution_command): Declare.
+	* infrun.c (set_observer_mode): Leave target async alone.
+	* mi/mi-interp.c (mi_interpreter_init): Install
+	mi_on_sync_execution_done as sync_execution_done observer.
+	(mi_on_sync_execution_done): New function.
+	(mi_execute_command_input_handler): Don't print the prompt if we
+	just started a synchronous command with an async target.
+	(mi_on_resume): Check sync_execution before printing prompt.
+	* mi/mi-main.h (mi_async_p): Declare.
+	* mi/mi-main.c: Include gdbcmd.h.
+	(mi_async_p): New function.
+	(mi_async, mi_async_1): New globals.
+	(set_mi_async_command, show_mi_async_command, mi_async): New
+	functions.
+	(exec_continue): Call prepare_execution_command.
+	(run_one_inferior, mi_cmd_exec_run, mi_cmd_list_target_features)
+	(mi_execute_async_cli_command): Use mi_async_p.
+	(_initialize_mi_main): Install "set mi-async".  Make
+	"target-async" a deprecated alias.
+
+2014-05-29  Pedro Alves  <palves@redhat.com>
 
 	* cli/cli-interp.c (cli_interpreter_display_prompt_p): Delete.
 	(_initialize_cli_interp): Adjust.
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index f0e5804..18fb241 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,4 +1,13 @@
 2014-05-29  Pedro Alves  <palves@redhat.com>
+	    Tom Tromey  <tromey@redhat.com>
+
+	* gdb.texinfo (Non-Stop Mode): Remove "set target-async 1"
+	from example.
+	(Asynchronous and non-stop modes): Document '-gdb-set mi-async'.
+	Mention that target-async is now deprecated.
+	(Maintenance Commands): Document maint set/show target-async.
+
+2014-05-29  Pedro Alves  <palves@redhat.com>
 
 	* observer.texi (sync_execution_done, command_error): New
 	subjects.
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 3dc8f5f..0297ec6 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,4 +1,33 @@
 2014-05-29  Pedro Alves  <palves@redhat.com>
+	    Tom Tromey  <tromey@redhat.com>
+
+	* gdb.base/async-shell.exp: Don't enable target-async.
+	* gdb.base/async.exp
+	* gdb.base/corefile.exp (corefile_test_attach): Remove 'async'
+	parameter.  Adjust.
+	(top level): Don't test with "target-async".
+	* gdb.base/dprintf-non-stop.exp: Don't enable target-async.
+	* gdb.base/gdb-sigterm.exp: Don't test with "target-async".
+	* gdb.base/inferior-died.exp: Don't enable target-async.
+	* gdb.base/interrupt-noterm.exp: Likewise.
+	* gdb.mi/mi-async.exp: Use "mi-async" instead of "target-async".
+	* gdb.mi/mi-nonstop-exit.exp: Likewise.
+	* gdb.mi/mi-nonstop.exp: Likewise.
+	* gdb.mi/mi-ns-stale-regcache.exp: Likewise.
+	* gdb.mi/mi-nsintrall.exp: Likewise.
+	* gdb.mi/mi-nsmoribund.exp: Likewise.
+	* gdb.mi/mi-nsthrexec.exp: Likewise.
+	* gdb.mi/mi-watch-nonstop.exp: Likewise.
+	* gdb.multi/watchpoint-multi.exp: Adjust comment.
+	* gdb.python/py-evsignal.exp: Don't enable target-async.
+	* gdb.python/py-evthreads.exp: Likewise.
+	* gdb.python/py-prompt.exp: Likewise.
+	* gdb.reverse/break-precsave.exp: Don't test with "target-async".
+	* gdb.server/solib-list.exp: Don't enable target-async.
+	* gdb.threads/thread-specific-bp.exp: Likewise.
+	* lib/mi-support.exp: Adjust to use mi-async.
+
+2014-05-29  Pedro Alves  <palves@redhat.com>
 
 	PR gdb/13860
 	* gdb.mi/mi-cli.exp: Always expect "end-stepping-range" stop
diff --git a/gdb/NEWS b/gdb/NEWS
index 6683bc0..8b57bd9 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -71,6 +71,26 @@ set record btrace replay-memory-access (read-only|read-write)
 show record btrace replay-memory-access
   Control what memory accesses are allowed during replay.
 
+maint set target-async (on|off)
+maint show target-async
+  This controls whether GDB targets operate in syncronous or
+  asyncronous mode.  Normally the default is asyncronous, if it is
+  available; but this can be changed to more easily debug problems
+  occurring only in syncronous mode.
+
+set mi-async (on|off)
+show mi-async
+  Control whether MI asynchronous mode is preferred.  This supersedes
+  "set target-async" of previous GDB versions.
+
+* "set target-async" is deprecated as a CLI option and is now an alias
+  for "set mi-async" (only puts MI into async mode).
+
+* Background execution commands (e.g., "c&", "s&", etc.) are now
+  possible ``out of the box'' if the target supports them.  Previously
+  the user would need to explicitly enable the possibility with the
+  "set target-async on" command.
+
 * New features in the GDB remote stub, GDBserver
 
   ** New option --debug-format=option1[,option2,...] allows one to add
@@ -145,6 +165,17 @@ PowerPC64 GNU/Linux little-endian	powerpc64le-*-linux*
   supported.  Use "set serial baud" and "show serial baud" (respectively)
   instead.
 
+* MI changes
+
+  ** A new option "-gdb-set mi-async" replaces "-gdb-set
+     target-async".  The latter is left as a deprecated alias of the
+     former for backward compatibility.  If the target supports it,
+     CLI background execution commands are now always possible by
+     default, independently of whether the frontend stated a
+     preference for asynchronous execution with "-gdb-set mi-async".
+     Previously "-gdb-set target-async off" affected both MI execution
+     commands and CLI execution commands.
+
 *** Changes in GDB 7.7
 
 * Improved support for process record-replay and reverse debugging on
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 1ee62e0..9f7fa18 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -5778,9 +5778,6 @@ To enter non-stop mode, use this sequence of commands before you run
 or attach to your program:
 
 @smallexample
-# Enable the async interface.
-set target-async 1
-
 # If using the CLI, pagination breaks non-stop.
 set pagination off
 
@@ -5850,21 +5847,6 @@ the program to report that some thread has stopped before prompting for
 another command.  In background execution, @value{GDBN} immediately gives
 a command prompt so that you can issue other commands while your program runs.
 
-You need to explicitly enable asynchronous mode before you can use
-background execution commands.  You can use these commands to
-manipulate the asynchronous mode setting:
-
-@table @code
-@kindex set target-async
-@item set target-async on
-Enable asynchronous mode.
-@item set target-async off
-Disable asynchronous mode.
-@kindex show target-async
-@item show target-async
-Show the current target-async setting.
-@end table
-
 If the target doesn't support async mode, @value{GDBN} issues an error
 message if you attempt to use the background execution commands.
 
@@ -24818,12 +24800,37 @@ On some targets, @value{GDBN} is capable of processing MI commands
 even while the target is running.  This is called @dfn{asynchronous
 command execution} (@pxref{Background Execution}).  The frontend may
 specify a preferrence for asynchronous execution using the
-@code{-gdb-set target-async 1} command, which should be emitted before
+@code{-gdb-set mi-async 1} command, which should be emitted before
 either running the executable or attaching to the target.  After the
 frontend has started the executable or attached to the target, it can
 find if asynchronous execution is enabled using the
 @code{-list-target-features} command.
 
+@table @code
+@item -gdb-set mi-async on
+@item -gdb-set mi-async off
+Set whether MI is in asynchronous mode.
+
+When @code{off}, which is the default, MI execution commands (e.g.,
+@code{-exec-continue}) are foreground commands, and @value{GDBN} waits
+for the program to stop before processing further commands.
+
+When @code{on}, MI execution commands are background execution
+commands (e.g., @code{-exec-continue} becomes the equivalent of the
+@code{c&} CLI command), and so @value{GDBN} is capable of processing
+MI commands even while the target is running.
+
+@item -gdb-show mi-async
+Show whether MI asynchronous mode is enabled.
+@end table
+
+Note: In @value{GDBN} version 7.7 and earlier, this option was called
+@code{target-async} instead of @code{mi-async}, and it had the effect
+of both putting MI in asynchronous mode and making CLI background
+commands possible.  CLI background commands are now always possible
+``out of the box'' if the target supports them.  The old spelling is
+kept as a deprecated alias for backwards compatibility.
+
 Even if @value{GDBN} can accept a command while target is running,
 many commands that access the target do not work when the target is
 running.  Therefore, asynchronous command execution is most useful
@@ -33532,6 +33539,15 @@ Control whether to show all non zero areas within a 1k block starting
 at thread local base, when using the @samp{info w32 thread-information-block}
 command.
 
+@kindex maint set target-async
+@kindex maint show target-async
+@item maint set target-async
+@itemx maint show target-async
+This controls whether @value{GDBN} targets operate in synchronous or
+asynchronous mode (@pxref{Background Execution}).  Normally the
+default is asynchronous, if it is available; but this can be changed
+to more easily debug problems occurring only in synchronous mode.
+
 @kindex maint set per-command
 @kindex maint show per-command
 @item maint set per-command
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 6511d64..df4fd40 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -497,11 +497,9 @@ Start it from the beginning? ")))
     }
 }
 
-/* Prepare for execution command.  TARGET is the target that will run
-   the command.  BACKGROUND determines whether this is a foreground
-   (synchronous) or background (asynchronous) command.  */
+/* See inferior.h.  */
 
-static void
+void
 prepare_execution_command (struct target_ops *target, int background)
 {
   /* If we get a request for running in the bg but the target
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 14f4ec8..668c888 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -164,6 +164,13 @@ extern void notice_new_inferior (ptid_t, int, int);
 extern struct value *get_return_value (struct value *function,
                                        struct type *value_type);
 
+/* Prepare for execution command.  TARGET is the target that will run
+   the command.  BACKGROUND determines whether this is a foreground
+   (synchronous) or background (asynchronous) command.  */
+
+extern void prepare_execution_command (struct target_ops *target,
+				       int background);
+
 /* Whether to start up the debuggee under a shell.
 
    If startup-with-shell is set, GDB's "run" will attempt to start up
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 9086cd2..e6540ad 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -235,7 +235,6 @@ set_observer_mode (char *args, int from_tty,
      going out we leave it that way.  */
   if (observer_mode)
     {
-      target_async_permitted = 1;
       pagination_enabled = 0;
       non_stop = non_stop_1 = 1;
     }
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index e1dd97f..52a3a62 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -85,6 +85,7 @@ static void mi_breakpoint_modified (struct breakpoint *b);
 static void mi_command_param_changed (const char *param, const char *value);
 static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
 			       ssize_t len, const bfd_byte *myaddr);
+static void mi_on_sync_execution_done (void);
 
 static int report_initial_inferior (struct inferior *inf, void *closure);
 
@@ -158,6 +159,7 @@ mi_interpreter_init (struct interp *interp, int top_level)
       observer_attach_breakpoint_modified (mi_breakpoint_modified);
       observer_attach_command_param_changed (mi_command_param_changed);
       observer_attach_memory_changed (mi_memory_changed);
+      observer_attach_sync_execution_done (mi_on_sync_execution_done);
 
       /* The initial inferior is created before this function is
 	 called, so we need to report it explicitly.  Use iteration in
@@ -304,6 +306,28 @@ mi_execute_command_wrapper (const char *cmd)
   mi_execute_command (cmd, stdin == instream);
 }
 
+/* Observer for the synchronous_command_done notification.  */
+
+static void
+mi_on_sync_execution_done (void)
+{
+  /* MI generally prints a prompt after a command, indicating it's
+     ready for further input.  However, due to an historical wart, if
+     MI async, and a (CLI) synchronous command was issued, then we
+     will print the prompt right after printing "^running", even if we
+     cannot actually accept any input until the target stops.  See
+     mi_on_resume.  However, if the target is async but MI is sync,
+     then we need to output the MI prompt now, to replicate gdb's
+     behavior when neither the target nor MI are async.  (Note this
+     observer is only called by the asynchronous target event handling
+     code.)  */
+  if (!mi_async_p ())
+    {
+      fputs_unfiltered ("(gdb) \n", raw_stdout);
+      gdb_flush (raw_stdout);
+    }
+}
+
 /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER.  */
 
 static void
@@ -311,8 +335,24 @@ mi_execute_command_input_handler (char *cmd)
 {
   mi_execute_command_wrapper (cmd);
 
-  fputs_unfiltered ("(gdb) \n", raw_stdout);
-  gdb_flush (raw_stdout);
+  /* MI generally prints a prompt after a command, indicating it's
+     ready for further input.  However, due to an historical wart, if
+     MI is async, and a synchronous command was issued, then we will
+     print the prompt right after printing "^running", even if we
+     cannot actually accept any input until the target stops.  See
+     mi_on_resume.
+
+     If MI is not async, then we print the prompt when the command
+     finishes.  If the target is sync, that means output the prompt
+     now, as in that case executing a command doesn't return until the
+     command is done.  However, if the target is async, we go back to
+     the event loop and output the prompt in the
+     'synchronous_command_done' observer.  */
+  if (!target_is_async_p () || !sync_execution)
+    {
+      fputs_unfiltered ("(gdb) \n", raw_stdout);
+      gdb_flush (raw_stdout);
+    }
 }
 
 static void
@@ -928,10 +968,10 @@ mi_on_resume (ptid_t ptid)
       running_result_record_printed = 1;
       /* This is what gdb used to do historically -- printing prompt even if
 	 it cannot actually accept any input.  This will be surely removed
-	 for MI3, and may be removed even earler.  */
-      /* FIXME: review the use of target_is_async_p here -- is that
-	 what we want? */
-      if (!target_is_async_p ())
+	 for MI3, and may be removed even earlier.  SYNC_EXECUTION is
+	 checked here because we only need to emit a prompt if a
+	 synchronous command was issued when the target is async.  */
+      if (!target_is_async_p () || sync_execution)
 	fputs_unfiltered ("(gdb) \n", raw_stdout);
     }
   gdb_flush (raw_stdout);
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 9ab4886..96dfc71 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -54,6 +54,7 @@
 #include "ada-lang.h"
 #include "linespec.h"
 #include "extension.h"
+#include "gdbcmd.h"
 
 #include <ctype.h>
 #include <sys/time.h>
@@ -105,6 +106,45 @@ static int register_changed_p (int regnum, struct regcache *,
 static void output_register (struct frame_info *, int regnum, int format,
 			     int skip_unavailable);
 
+/* Controls whether the frontend wants MI in async mode.  */
+static int mi_async = 0;
+
+/* The set command writes to this variable.  If the inferior is
+   executing, mi_async is *not* updated.  */
+static int mi_async_1 = 0;
+
+static void
+set_mi_async_command (char *args, int from_tty,
+		      struct cmd_list_element *c)
+{
+  if (have_live_inferiors ())
+    {
+      mi_async_1 = mi_async;
+      error (_("Cannot change this setting while the inferior is running."));
+    }
+
+  mi_async = mi_async_1;
+}
+
+static void
+show_mi_async_command (struct ui_file *file, int from_tty,
+		       struct cmd_list_element *c,
+		       const char *value)
+{
+  fprintf_filtered (file,
+		    _("Whether MI is in asynchronous mode is %s.\n"),
+		    value);
+}
+
+/* A wrapper for target_can_async_p that takes the MI setting into
+   account.  */
+
+int
+mi_async_p (void)
+{
+  return mi_async && target_can_async_p ();
+}
+
 /* Command implementations.  FIXME: Is this libgdb?  No.  This is the MI
    layer that calls libgdb.  Any operation used in the below should be
    formalized.  */
@@ -229,6 +269,8 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
 static void
 exec_continue (char **argv, int argc)
 {
+  prepare_execution_command (&current_target, mi_async_p ());
+
   if (non_stop)
     {
       /* In non-stop mode, 'resume' always resumes a single thread.
@@ -395,8 +437,8 @@ run_one_inferior (struct inferior *inf, void *arg)
       switch_to_thread (null_ptid);
       set_current_program_space (inf->pspace);
     }
-  mi_execute_cli_command (run_cmd, target_can_async_p (),
-			  target_can_async_p () ? "&" : NULL);
+  mi_execute_cli_command (run_cmd, mi_async_p (),
+			  mi_async_p () ? "&" : NULL);
   return 0;
 }
 
@@ -450,8 +492,8 @@ mi_cmd_exec_run (char *command, char **argv, int argc)
     {
       const char *run_cmd = start_p ? "start" : "run";
 
-      mi_execute_cli_command (run_cmd, target_can_async_p (),
-			      target_can_async_p () ? "&" : NULL);
+      mi_execute_cli_command (run_cmd, mi_async_p (),
+			      mi_async_p () ? "&" : NULL);
     }
 }
 
@@ -1838,11 +1880,10 @@ mi_cmd_list_target_features (char *command, char **argv, int argc)
       struct ui_out *uiout = current_uiout;
 
       cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");
-      if (target_can_async_p ())
+      if (mi_async_p ())
 	ui_out_field_string (uiout, NULL, "async");
       if (target_can_execute_reverse)
 	ui_out_field_string (uiout, NULL, "reverse");
-
       do_cleanups (cleanup);
       return;
     }
@@ -2269,7 +2310,7 @@ mi_execute_async_cli_command (char *cli_command, char **argv, int argc)
   struct cleanup *old_cleanups;
   char *run;
 
-  if (target_can_async_p ())
+  if (mi_async_p ())
     run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
   else
     run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
@@ -2920,3 +2961,25 @@ mi_cmd_trace_frame_collected (char *command, char **argv, int argc)
 
   do_cleanups (old_chain);
 }
+
+void
+_initialize_mi_main (void)
+{
+  struct cmd_list_element *c;
+
+  add_setshow_boolean_cmd ("mi-async", class_run,
+			   &mi_async_1, _("\
+Set whether MI asynchronous mode is enabled."), _("\
+Show whether MI asynchronous mode is enabled."), _("\
+Tells GDB whether MI should be in asynchronous mode."),
+			   set_mi_async_command,
+			   show_mi_async_command,
+			   &setlist,
+			   &showlist);
+
+  /* Alias old "target-async" to "mi-async".  */
+  c = add_alias_cmd ("target-async", "mi-async", class_run, 0, &setlist);
+  deprecate_cmd (c, "set mi-async");
+  c = add_alias_cmd ("target-async", "mi-async", class_run, 0, &showlist);
+  deprecate_cmd (c, "show mi-async");
+}
diff --git a/gdb/mi/mi-main.h b/gdb/mi/mi-main.h
index c32845d..530aeb7 100644
--- a/gdb/mi/mi-main.h
+++ b/gdb/mi/mi-main.h
@@ -28,6 +28,10 @@ extern void mi_load_progress (const char *section_name,
 
 extern void mi_print_timing_maybe (void);
 
+/* Whether MI is in async mode.  */
+
+extern int mi_async_p (void);
+
 extern char *current_token;
 
 extern int running_result_record_printed;
diff --git a/gdb/target.c b/gdb/target.c
index 6a1a2ff..cb154ab 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -4105,16 +4105,17 @@ maintenance_print_target_stack (char *cmd, int from_tty)
     }
 }
 
-/* Controls if async mode is permitted.  */
-int target_async_permitted = 0;
+/* Controls if targets can report that they can/are async.  This is
+   just for maintainers to use when debugging gdb.  */
+int target_async_permitted = 1;
 
 /* The set command writes to this variable.  If the inferior is
    executing, target_async_permitted is *not* updated.  */
-static int target_async_permitted_1 = 0;
+static int target_async_permitted_1 = 1;
 
 static void
-set_target_async_command (char *args, int from_tty,
-			  struct cmd_list_element *c)
+maint_set_target_async_command (char *args, int from_tty,
+				struct cmd_list_element *c)
 {
   if (have_live_inferiors ())
     {
@@ -4126,9 +4127,9 @@ set_target_async_command (char *args, int from_tty,
 }
 
 static void
-show_target_async_command (struct ui_file *file, int from_tty,
-			   struct cmd_list_element *c,
-			   const char *value)
+maint_show_target_async_command (struct ui_file *file, int from_tty,
+				 struct cmd_list_element *c,
+				 const char *value)
 {
   fprintf_filtered (file,
 		    _("Controlling the inferior in "
@@ -4233,10 +4234,10 @@ result in significant performance improvement for remote targets."),
 Set whether gdb controls the inferior in asynchronous mode."), _("\
 Show whether gdb controls the inferior in asynchronous mode."), _("\
 Tells gdb whether to control the inferior in asynchronous mode."),
-			   set_target_async_command,
-			   show_target_async_command,
-			   &setlist,
-			   &showlist);
+			   maint_set_target_async_command,
+			   maint_show_target_async_command,
+			   &maintenance_set_cmdlist,
+			   &maintenance_show_cmdlist);
 
   add_setshow_boolean_cmd ("may-write-registers", class_support,
 			   &may_write_registers_1, _("\
diff --git a/gdb/target.h b/gdb/target.h
index 9371529..face210 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1619,8 +1619,7 @@ extern int default_child_has_execution (struct target_ops *ops,
 #define target_can_lock_scheduler \
      (current_target.to_has_thread_control & tc_schedlock)
 
-/* Should the target enable async mode if it is supported?  Temporary
-   cludge until async mode is a strict superset of sync mode.  */
+/* Controls whether async mode is permitted.  */
 extern int target_async_permitted;
 
 /* Can the target support asynchronous execution?  */
diff --git a/gdb/testsuite/gdb.base/async-shell.exp b/gdb/testsuite/gdb.base/async-shell.exp
index 4890a59..f0550bc 100644
--- a/gdb/testsuite/gdb.base/async-shell.exp
+++ b/gdb/testsuite/gdb.base/async-shell.exp
@@ -31,7 +31,6 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} $srcfile] } {
 
 set gdbindex_warning_re "warning: Skipping \[^\r\n\]+ \\.gdb_index section \[^\r\n\]*\r\nDo \"set use-deprecated-index-sections on\" before the file is read\r\nto use the section anyway\\."
 
-gdb_test_no_output "set target-async on "
 gdb_test_no_output "set non-stop on"
 gdb_test "run &" "Starting program: \[^\r\n\]*(\r\n$gdbindex_warning_re)?"
 
diff --git a/gdb/testsuite/gdb.base/async.exp b/gdb/testsuite/gdb.base/async.exp
index f0a18e8..0f99b01 100644
--- a/gdb/testsuite/gdb.base/async.exp
+++ b/gdb/testsuite/gdb.base/async.exp
@@ -25,8 +25,6 @@ if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} {
     return -1
 }
 
-gdb_test_no_output "set target-async on"
-
 #
 # set it up at a breakpoint so we can play with it
 #
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
index 6eb1f02..bde2de8 100644
--- a/gdb/testsuite/gdb.base/corefile.exp
+++ b/gdb/testsuite/gdb.base/corefile.exp
@@ -241,7 +241,7 @@ gdb_exit
 
 # Test an attach command will clear any loaded core file.
 
-proc corefile_test_attach {{async 0}} {
+proc corefile_test_attach {} {
     global binfile corefile gdb_prompt
 
     if ![is_remote target] {
@@ -257,11 +257,6 @@ proc corefile_test_attach {{async 0}} {
 
 	gdb_start
 
-	if {$async} {
-	    gdb_test_no_output "set target-async on" \
-		"enable target-async for attach tests"
-	}
-
 	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"
 
@@ -298,13 +293,3 @@ 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.base/dprintf-non-stop.exp b/gdb/testsuite/gdb.base/dprintf-non-stop.exp
index fdaa5c1..df1e270 100644
--- a/gdb/testsuite/gdb.base/dprintf-non-stop.exp
+++ b/gdb/testsuite/gdb.base/dprintf-non-stop.exp
@@ -26,7 +26,6 @@ if [prepare_for_testing "failed to prepare for dprintf with non-stop" \
     return -1
 }
 
-gdb_test_no_output "set target-async on"
 gdb_test_no_output "set non-stop on"
 
 if ![runto main] {
diff --git a/gdb/testsuite/gdb.base/gdb-sigterm.exp b/gdb/testsuite/gdb.base/gdb-sigterm.exp
index f52517c..df0de42 100644
--- a/gdb/testsuite/gdb.base/gdb-sigterm.exp
+++ b/gdb/testsuite/gdb.base/gdb-sigterm.exp
@@ -79,17 +79,7 @@ proc do_test { pass } {
 # 50 runs should be approx. a safe number to be sure it is fixed now.
 
 for {set pass 0} {$pass < 50} {incr pass} {
-
     clean_restart ${testfile}
-    gdb_test_no_output "set target-async off" ""
-    with_test_prefix "sync" {
-        do_test $pass
-    }
-
-    clean_restart ${testfile}
-    gdb_test_no_output "set target-async on" ""
-    with_test_prefix "async" {
-        do_test $pass
-    }
+    do_test $pass
 }
 pass "$pass SIGTERM passes"
diff --git a/gdb/testsuite/gdb.base/inferior-died.exp b/gdb/testsuite/gdb.base/inferior-died.exp
index 33f92e9..152bdd8 100644
--- a/gdb/testsuite/gdb.base/inferior-died.exp
+++ b/gdb/testsuite/gdb.base/inferior-died.exp
@@ -38,7 +38,6 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.c] } {
 }
 
 gdb_test_no_output "set detach-on-fork off"
-gdb_test_no_output "set target-async on"
 gdb_test_no_output "set non-stop on"
 
 if ![runto_main] {
diff --git a/gdb/testsuite/gdb.base/interrupt-noterm.exp b/gdb/testsuite/gdb.base/interrupt-noterm.exp
index a22acd2..5c92b97 100644
--- a/gdb/testsuite/gdb.base/interrupt-noterm.exp
+++ b/gdb/testsuite/gdb.base/interrupt-noterm.exp
@@ -22,7 +22,6 @@ if [prepare_for_testing "failed to prepare for testing" \
 
 # Pretend there's no terminal.
 gdb_test_no_output "set interactive-mode off"
-gdb_test_no_output "set target-async on"
 
 if ![runto main] {
     fail "Can't run to main"
diff --git a/gdb/testsuite/gdb.mi/mi-async.exp b/gdb/testsuite/gdb.mi/mi-async.exp
index e41701d..0df4c98 100644
--- a/gdb/testsuite/gdb.mi/mi-async.exp
+++ b/gdb/testsuite/gdb.mi/mi-async.exp
@@ -27,7 +27,7 @@ if { !([isnative] && [istarget *-linux*]) } then {
 
 # The plan is for async mode to become the default but toggle for now.
 set saved_gdbflags $GDBFLAGS
-set GDBFLAGS [concat $GDBFLAGS " -ex \"set target-async on\""]
+set GDBFLAGS [concat $GDBFLAGS " -ex \"set mi-async on\""]
 
 load_lib mi-support.exp
 
diff --git a/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp b/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp
index 3727d81..5187b40 100644
--- a/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp
+++ b/gdb/testsuite/gdb.mi/mi-nonstop-exit.exp
@@ -40,7 +40,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nonstop.exp b/gdb/testsuite/gdb.mi/mi-nonstop.exp
index 5ef74ed..ba7dfd4 100644
--- a/gdb/testsuite/gdb.mi/mi-nonstop.exp
+++ b/gdb/testsuite/gdb.mi/mi-nonstop.exp
@@ -50,7 +50,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp
index 754689c..ae9e5f2 100644
--- a/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp
+++ b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp
@@ -53,7 +53,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nsintrall.exp b/gdb/testsuite/gdb.mi/mi-nsintrall.exp
index f613e7f..ac1209e 100644
--- a/gdb/testsuite/gdb.mi/mi-nsintrall.exp
+++ b/gdb/testsuite/gdb.mi/mi-nsintrall.exp
@@ -40,7 +40,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp
index 350c060..0ff04ca 100644
--- a/gdb/testsuite/gdb.mi/mi-nsmoribund.exp
+++ b/gdb/testsuite/gdb.mi/mi-nsmoribund.exp
@@ -40,7 +40,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-nsthrexec.exp b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp
index 85617d0..008a831 100644
--- a/gdb/testsuite/gdb.mi/mi-nsthrexec.exp
+++ b/gdb/testsuite/gdb.mi/mi-nsthrexec.exp
@@ -50,7 +50,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp b/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp
index 3dbf4c7..44371c8 100644
--- a/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp
+++ b/gdb/testsuite/gdb.mi/mi-watch-nonstop.exp
@@ -52,7 +52,7 @@ mi_gdb_reinitialize_dir $srcdir/$subdir
 mi_gdb_load $binfile
 
 mi_gdb_test "-gdb-set non-stop 1" ".*"
-mi_gdb_test "-gdb-set target-async 1" ".*"
+mi_gdb_test "-gdb-set mi-async 1" ".*"
 mi_detect_async
 
 if { [mi_run_to_main] < 0 } {
diff --git a/gdb/testsuite/gdb.multi/watchpoint-multi.exp b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
index b7fb0a9..e6a8957 100644
--- a/gdb/testsuite/gdb.multi/watchpoint-multi.exp
+++ b/gdb/testsuite/gdb.multi/watchpoint-multi.exp
@@ -37,7 +37,7 @@ if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executa
 
 clean_restart $executable
 
-# Simulate non-stop+target-async which also uses breakpoint always-inserted.
+# Simulate non-stop which also uses breakpoint always-inserted.
 gdb_test_no_output "set breakpoint always-inserted on"
 # displaced-stepping is also needed as other GDB sometimes still removes the
 # breakpoints, even with always-inserted on.
diff --git a/gdb/testsuite/gdb.python/py-evsignal.exp b/gdb/testsuite/gdb.python/py-evsignal.exp
index af3d53c..530fd07 100644
--- a/gdb/testsuite/gdb.python/py-evsignal.exp
+++ b/gdb/testsuite/gdb.python/py-evsignal.exp
@@ -35,7 +35,6 @@ gdb_test_no_output "python exec (open ('${pyfile}').read ())" ""
 
 gdb_test "test-events" "Event testers registered."
 gdb_test_no_output "set non-stop on"
-gdb_test_no_output "set target-async on"
 
 gdb_run_cmd
 gdb_test_multiple "" "Signal Thread 3"  {
diff --git a/gdb/testsuite/gdb.python/py-evthreads.exp b/gdb/testsuite/gdb.python/py-evthreads.exp
index ffa322f..d62624e 100644
--- a/gdb/testsuite/gdb.python/py-evthreads.exp
+++ b/gdb/testsuite/gdb.python/py-evthreads.exp
@@ -40,7 +40,6 @@ gdb_test_no_output "python exec (open ('${pyfile}').read ())" ""
 
 gdb_test "test-events" "Event testers registered."
 gdb_test_no_output "set non-stop on"
-gdb_test_no_output "set target-async on"
 
 gdb_breakpoint "main"
 gdb_breakpoint "thread2"
diff --git a/gdb/testsuite/gdb.python/py-prompt.exp b/gdb/testsuite/gdb.python/py-prompt.exp
index e376c05..ebe4cb6 100644
--- a/gdb/testsuite/gdb.python/py-prompt.exp
+++ b/gdb/testsuite/gdb.python/py-prompt.exp
@@ -90,8 +90,7 @@ if { [istarget "*-*-cygwin*"] } {
     set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
 }
 
-set GDBFLAGS [concat $tmp_gdbflags " -ex \"set target-async on\""]
-set GDBFLAGS [concat $GDBFLAGS " -ex \"set pagination off\""]
+set GDBFLAGS [concat $tmp_gdbflags " -ex \"set pagination off\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"attach $testpid\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"continue&\""]
@@ -107,8 +106,7 @@ gdb_test "python print (\"'\" + str(p\[0\]) + \"'\")" "'$gdb_prompt_fail '" \
 	 "prompt_hook argument is default prompt. 3"
 gdb_exit
 
-set GDBFLAGS [concat $tmp_gdbflags " -ex \"set target-async on\""]
-set GDBFLAGS [concat $GDBFLAGS " -ex \"set pagination off\""]
+set GDBFLAGS [concat $tmp_gdbflags " -ex \"set pagination off\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"attach $testpid\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"interrupt\""]
diff --git a/gdb/testsuite/gdb.reverse/break-precsave.exp b/gdb/testsuite/gdb.reverse/break-precsave.exp
index f1e6c69..3206e3c 100644
--- a/gdb/testsuite/gdb.reverse/break-precsave.exp
+++ b/gdb/testsuite/gdb.reverse/break-precsave.exp
@@ -110,9 +110,3 @@ proc precsave_tests {} {
 }
 
 precsave_tests
-
-with_test_prefix "target-async" {
-    clean_restart $testfile
-    gdb_test_no_output "set target-async on"
-    precsave_tests
-}
diff --git a/gdb/testsuite/gdb.server/solib-list.exp b/gdb/testsuite/gdb.server/solib-list.exp
index 8cc3edc..4504a23 100644
--- a/gdb/testsuite/gdb.server/solib-list.exp
+++ b/gdb/testsuite/gdb.server/solib-list.exp
@@ -66,7 +66,6 @@ foreach nonstop { 0 1 } { with_test_prefix "non-stop $nonstop" {
     gdb_test "disconnect" ".*"
 
     gdb_test "set non-stop $nonstop"
-    gdb_test "set target-async $nonstop"
 
     # It is required for the non-stop mode, GDB would try to step over
     # _dl_debug_state breakpoint will still only ld.so loaded in gdbserver.
diff --git a/gdb/testsuite/gdb.threads/thread-specific-bp.exp b/gdb/testsuite/gdb.threads/thread-specific-bp.exp
index b8416d7..4273e1d 100644
--- a/gdb/testsuite/gdb.threads/thread-specific-bp.exp
+++ b/gdb/testsuite/gdb.threads/thread-specific-bp.exp
@@ -122,6 +122,5 @@ check_thread_specific_breakpoint "all-stop"
 clean_restart ${binfile}
 
 # Test non-stop mode.
-gdb_test_no_output "set target-async on" "set async mode"
 gdb_test_no_output "set non-stop on" "set non-stop mode"
 check_thread_specific_breakpoint "non-stop"
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
index 9f07cda..f1b5749 100644
--- a/gdb/testsuite/lib/mi-support.exp
+++ b/gdb/testsuite/lib/mi-support.exp
@@ -1014,10 +1014,10 @@ proc mi_detect_async {} {
     global async
     global mi_gdb_prompt
 
-    send_gdb "show target-async\n"
+    send_gdb "show mi-async\n"
 
     gdb_expect {
-	-re ".*Controlling the inferior in asynchronous mode is on...*$mi_gdb_prompt$" {
+	-re "asynchronous mode is on...*$mi_gdb_prompt$" {
 	    set async 1
 	}
 	-re ".*$mi_gdb_prompt$" {
-- 
1.9.0


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-05-29 13:44 ` [pushed] Re: [PATCH v6 0/2] enable target-async by default Pedro Alves
@ 2014-07-01 16:28   ` Jan Kratochvil
  2014-07-02  8:59     ` Mark Wielaard
  2014-10-05 14:00   ` Crash regression for annota1.exp w/vDSO debuginfo [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
  1 sibling, 1 reply; 42+ messages in thread
From: Jan Kratochvil @ 2014-07-01 16:28 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Thu, 29 May 2014 15:44:02 +0200, Pedro Alves wrote:
> I went ahead and pushed this all in, with Eli's comments addressed.

329ea57934a9d4b250a0b417af1ec47bc2d0ceb6 is the first bad commit
commit 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6
Author: Pedro Alves <palves@redhat.com>
Date:   Thu May 29 19:58:57 2014 +0100
    enable target async by default; separate MI and target notions of async

This affects GCC testsuite where guality.exp does not start at all with:
	gdb: took too long to attach


cat >var2.c <<HERE
#include <stdio.h>
volatile int xxx;
int main(void) {
  while (!xxx);
  printf("xxx=%d\n",xxx);
  return 0;
}
HERE
gcc -o var2 var2.c -Wall -g
./var2 &p=$!;sleep 0.1;echo -e "set trace-commands\nattach $p\nset xxx=1\nprint xxx"|gdb -q;kill -9 $p

--->

[1] 31729
(gdb) (gdb) +attach 31729
Attaching to process 31729
+set xxx=1
No symbol table is loaded.  Use the "file" command.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(gdb) Reading symbols from /home/jkratoch/t/var2...done.
Reading symbols from /lib64/libc.so.6...Reading symbols from /usr/lib/debug/usr/lib64/libc-2.19.90.so.debug...done.
done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/usr/lib64/ld-2.19.90.so.debug...done.
done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x0000000000400541 in main () at var2.c:4
4	  while (!xxx);
+print xxx
$1 = 0


Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-07-01 16:28   ` Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
@ 2014-07-02  8:59     ` Mark Wielaard
  2014-07-02  9:16       ` Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Mark Wielaard @ 2014-07-02  8:59 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Pedro Alves, gdb-patches

On Tue, 2014-07-01 at 18:28 +0200, Jan Kratochvil wrote:
> On Thu, 29 May 2014 15:44:02 +0200, Pedro Alves wrote:
> > I went ahead and pushed this all in, with Eli's comments addressed.
> 
> 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6 is the first bad commit
> commit 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6
> Author: Pedro Alves <palves@redhat.com>
> Date:   Thu May 29 19:58:57 2014 +0100
>     enable target async by default; separate MI and target notions of async
> 
> This affects GCC testsuite where guality.exp does not start at all with:
> 	gdb: took too long to attach

Thanks for tracking this down Jan. Should this patch be reverted or
should gcc guality.h be patched to work around the new async default
somehow?

Currently I am using the following patch to guality.h in gcc which seems
to work around it, but I don't really understand why:

diff --git a/gcc/testsuite/gcc.dg/guality/guality.h
b/gcc/testsuite/gcc.dg/guality/guality.h
index 8b657f2..d83e270 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.h
+++ b/gcc/testsuite/gcc.dg/guality/guality.h
@@ -243,6 +243,7 @@ main (int argc, char *argv[])
          || fprintf (guality_gdb_input, "\
 set height 0\n\
 attach %i\n\
+print guality_attached\n\
 set guality_attached = 1\n\
 b %i\n\
 continue\n\

Thanks,

Mark

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-07-02  8:59     ` Mark Wielaard
@ 2014-07-02  9:16       ` Pedro Alves
  2014-07-03 15:39         ` Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-07-02  9:16 UTC (permalink / raw)
  To: Mark Wielaard, Jan Kratochvil; +Cc: gdb-patches

On 07/02/2014 09:59 AM, Mark Wielaard wrote:
> Thanks for tracking this down Jan. Should this patch be reverted 

Unless it turns into a deep rat hole, I'd like to fix the issue
instead.  I haven't investigated this particular issue yet, but I've
been busy fixing PR17072, and I ended up fixing several issues
related to execution commands entered directly in the command line,
before GDB's main event loop starts.  This one sounds related.

> or
> should gcc guality.h be patched to work around the new async default
> somehow?

No, the async default in an internal implementation detail.  It should
cause no visible change of behavior, other than enabling features.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-07-02  9:16       ` Pedro Alves
@ 2014-07-03 15:39         ` Pedro Alves
  2014-07-04 13:48           ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-07-03 15:39 UTC (permalink / raw)
  To: Mark Wielaard, Jan Kratochvil; +Cc: gdb-patches

On 07/02/2014 10:15 AM, Pedro Alves wrote:
> On 07/02/2014 09:59 AM, Mark Wielaard wrote:
>> Thanks for tracking this down Jan. Should this patch be reverted 
> 
> Unless it turns into a deep rat hole, I'd like to fix the issue
> instead.  I haven't investigated this particular issue yet, but I've
> been busy fixing PR17072, and I ended up fixing several issues
> related to execution commands entered directly in the command line,
> before GDB's main event loop starts.  This one sounds related.

Looking at this now.  The other series unfortunately doesn't fix this.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-03 15:39         ` Pedro Alves
@ 2014-07-04 13:48           ` Pedro Alves
  2014-07-04 21:13             ` Mark Wielaard
                               ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Pedro Alves @ 2014-07-04 13:48 UTC (permalink / raw)
  To: Mark Wielaard, Jan Kratochvil; +Cc: gdb-patches

On 07/03/2014 04:38 PM, Pedro Alves wrote:
> On 07/02/2014 10:15 AM, Pedro Alves wrote:
>> On 07/02/2014 09:59 AM, Mark Wielaard wrote:
>>> Thanks for tracking this down Jan. Should this patch be reverted 
>>
>> Unless it turns into a deep rat hole, I'd like to fix the issue
>> instead.  I haven't investigated this particular issue yet, but I've
>> been busy fixing PR17072, and I ended up fixing several issues
>> related to execution commands entered directly in the command line,
>> before GDB's main event loop starts.  This one sounds related.
> 
> Looking at this now.  The other series unfortunately doesn't fix this.
> 

Here's a fix.  Let me know whether it fixes guality testing.

You can also find it at:

 git@github.com:palves/gdb.git palves/attach_from_stdin

I've also pushed it on top of the palves/pr17072_pagination_async
branch, in case the other fixes on that branch (posted yesterday)
are necessary.

Thanks,
Pedro Alves

8<----------

From f93645049c02459bedada7b61fea633f59a47817 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Fri, 4 Jul 2014 13:47:53 +0100
Subject: [PATCH] Fix "attach" command vs user input race

On async targets, a synchronous attach is done like this:

   #1 - target_attach is called (PTRACE_ATTACH is issued)
   #2 - a continuation is installed
   #3 - we go back to the event loop
   #4 - target reports stop (SIGSTOP), event loop wakes up, and
        attach continuation is called
   #5 - among other things, the continuation calls
        target_terminal_inferior, which removes stdin from the event
        loop

Note that in #3, GDB is still processing user input.  If the user is
fast enough, e.g., with something like:

  echo -e "attach PID\nset xxx=1" | gdb

... then the "set" command is processed before the attach completes.

We get worse behavior even, if input is a tty and therefore
readline/editing is enabled, with e.g.,:

 (gdb) attach PID\nset xxx=1

we then crash readline/gdb, with:

 Attaching to program: attach-wait-input, process 14537
 readline: readline_callback_read_char() called with no handler!
 Aborted
 $

Fix this by calling target_terminal_inferior before #3 above.

The test covers both scenarios by running with editing/readline forced
to both on and off.

gdb/
2014-07-04  Pedro Alves  <palves@redhat.com>

	* infcmd.c (attach_command_post_wait): Don't call
	target_terminal_inferior here.
	(attach_command): Call it here instead.

gdb/testsuite/
2014-07-04  Pedro Alves  <palves@redhat.com>

	* gdb.base/attach-fg-no-stdin.exp: New file.
	* gdb.base/attach-fg-no-stdin.c: New file.
---
 gdb/infcmd.c                                 |   9 +-
 gdb/testsuite/gdb.base/attach-wait-input.c   |  47 +++++++++++
 gdb/testsuite/gdb.base/attach-wait-input.exp | 119 +++++++++++++++++++++++++++
 3 files changed, 170 insertions(+), 5 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/attach-wait-input.c
 create mode 100644 gdb/testsuite/gdb.base/attach-wait-input.exp

diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index c4bb401..76ab12b 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2381,9 +2381,6 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)

   post_create_inferior (&current_target, from_tty);

-  /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
-
   if (async_exec)
     {
       /* The user requested an `attach&', so be sure to leave threads
@@ -2495,9 +2492,11 @@ attach_command (char *args, int from_tty)
      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.  */
+  /* Set up the "saved terminal modes" of the inferior based on what
+     modes we are starting it with, and remove stdin from the event
+     loop.  */
   target_terminal_init ();
+  target_terminal_inferior ();

   /* Set up execution context to know that we should return from
      wait_for_inferior as soon as the target reports a stop.  */
diff --git a/gdb/testsuite/gdb.base/attach-wait-input.c b/gdb/testsuite/gdb.base/attach-wait-input.c
new file mode 100644
index 0000000..bb99b1f
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach-wait-input.c
@@ -0,0 +1,47 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* This program is intended to be started outside of gdb, and then
+   attached to by gdb.  Thus, it simply spins in a loop.  The loop
+   is exited when & if the variable 'should_exit' is non-zero.  (It
+   is initialized to zero in this program, so the loop will never
+   exit unless/until gdb sets the variable to non-zero.)
+   */
+
+#include <sys/types.h>
+#include <unistd.h>
+
+volatile int should_exit = 0;
+int mypid;
+
+static void
+setup_done (void)
+{
+}
+
+int
+main (void)
+{
+  unsigned int counter = 1;
+
+  mypid = getpid ();
+  setup_done ();
+
+  for (counter = 0; !should_exit && counter < 100; counter++)
+    sleep (1);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/attach-wait-input.exp b/gdb/testsuite/gdb.base/attach-wait-input.exp
new file mode 100644
index 0000000..3120778
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach-wait-input.exp
@@ -0,0 +1,119 @@
+# Copyright 1997-2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+# Verify that GDB waits for the "attach" command to finish before
+# processing the following command.
+#
+# GDB used to have a race where on async targets, in the small window
+# between the attach request and the initial stop for the attach, GDB
+# was still processing user input.
+#
+# The issue was originally detected with:
+#
+#  echo -e "attach PID\nset xxx=1" | gdb
+#
+# In that scenario, stdin is not a tty, which disables readline.
+# Explicitly turning off editing exercises the same code path, and is
+# simpler to do, so we test with both editing on and off.
+
+# The test uses the "attach" command.
+if [target_info exists use_gdb_stub] {
+    return
+}
+
+standard_testfile
+
+if {[build_executable "failed to build" $testfile $srcfile debug]} {
+    return -1
+}
+
+# Start the program running, and return its PID, ready for attaching.
+
+proc start_program {binfile} {
+    global gdb_prompt
+    global decimal
+
+    clean_restart $binfile
+
+    if ![runto setup_done] then {
+	fail "Can't run to setup_done"
+	return 0
+    }
+
+    # Get the PID of the test process.
+    set testpid ""
+    set test "get inferior process ID"
+    gdb_test_multiple "p mypid" $test {
+	-re " = ($decimal)\r\n$gdb_prompt $" {
+	    set testpid $expect_out(1,string)
+	    pass $test
+	}
+    }
+
+    gdb_test "detach" "Detaching from program: .*"
+
+    if {$testpid == ""} {
+	return
+    }
+
+    return $testpid
+}
+
+# Do test proper.  EDITING indicates whether "set editing" is on or
+# off.
+
+proc test { editing } {
+    global gdb_prompt
+    global binfile
+    global decimal
+
+    with_test_prefix "editing $editing" {
+
+	set testpid [start_program $binfile]
+	if {$testpid == ""} {
+	    return
+	}
+
+	# Enable/disable readline.
+	gdb_test_no_output "set editing $editing"
+
+	# Send both commands at once.
+	send_gdb "attach $testpid\nprint should_exit = 1\n"
+
+	# Use gdb_expect directly instead of gdb_test_multiple to
+	# avoid races with the double prompt.
+	set test "attach and print"
+	gdb_expect {
+	    -re "Attaching to program.*process $testpid\r\n.*$gdb_prompt.*$decimal = 1\r\n$gdb_prompt $" {
+		pass "$test"
+	    }
+	    timeout {
+		fail "$test (timeout)"
+	    }
+	}
+
+	# As we've used attach, on quit, we'll detach from the
+	# program.  Explicitly kill it in case we failed above.
+	gdb_test "kill" \
+	    "" \
+	    "after attach, exit" \
+	    "Kill the program being debugged.*y or n. $" \
+	    "y"
+    }
+}
+
+foreach editing {"on" "off"} {
+    test $editing
+}
-- 
1.9.3


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-04 13:48           ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Pedro Alves
@ 2014-07-04 21:13             ` Mark Wielaard
  2014-07-07 16:39             ` Doug Evans
  2014-07-07 17:02             ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Jan Kratochvil
  2 siblings, 0 replies; 42+ messages in thread
From: Mark Wielaard @ 2014-07-04 21:13 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Jan Kratochvil, gdb-patches

On Fri, 2014-07-04 at 14:48 +0100, Pedro Alves wrote:
> Here's a fix.  Let me know whether it fixes guality testing.

Yes, that patch works for me. Now I can run make check-c
RUNTESTFLAGS=guality.exp in gcc without needing any guality.h
workarounds.

Thanks,

Mark

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-04 13:48           ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Pedro Alves
  2014-07-04 21:13             ` Mark Wielaard
@ 2014-07-07 16:39             ` Doug Evans
  2014-07-08 15:24               ` Pedro Alves
  2014-07-07 17:02             ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Jan Kratochvil
  2 siblings, 1 reply; 42+ messages in thread
From: Doug Evans @ 2014-07-07 16:39 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Mark Wielaard, Jan Kratochvil, gdb-patches

Pedro Alves writes:
 > gdb/
 > 2014-07-04  Pedro Alves  <palves@redhat.com>
 > 
 > 	* infcmd.c (attach_command_post_wait): Don't call
 > 	target_terminal_inferior here.
 > 	(attach_command): Call it here instead.
 > [...]
 > diff --git a/gdb/infcmd.c b/gdb/infcmd.c
 > index c4bb401..76ab12b 100644
 > --- a/gdb/infcmd.c
 > +++ b/gdb/infcmd.c
 > @@ -2381,9 +2381,6 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
 > 
 >    post_create_inferior (&current_target, from_tty);
 > 
 > -  /* Install inferior's terminal modes.  */
 > -  target_terminal_inferior ();
 > -
 >    if (async_exec)
 >      {
 >        /* The user requested an `attach&', so be sure to leave threads
 > @@ -2495,9 +2492,11 @@ attach_command (char *args, int from_tty)
 >       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.  */
 > +  /* Set up the "saved terminal modes" of the inferior based on what
 > +     modes we are starting it with, and remove stdin from the event
 > +     loop.  */
 >    target_terminal_init ();
 > +  target_terminal_inferior ();
 > 
 >    /* Set up execution context to know that we should return from
 >       wait_for_inferior as soon as the target reports a stop.  */

Our nomenclature here is problematic. I always do a double take when
I see attach and target_terminal_foo mentioned in the same sentence.
Bleah.

For the case at hand, and at least until we have something more
readable, can I ask for a slight change here?

target_terminal_inferior can do a lot more than just "remove stdin
from the event loop", thus as a reader I'm left being unsure
if there aren't still more bugs here.

Plus, while I can see how to map the comment to the code in the patch,

"Set up the "saved terminal modes" of the inferior based on what
modes we are starting it with"
-->
  target_terminal_init ();

and

"remove stdin from the event loop"
-->
  target_terminal_inferior ();

If I look at the result after the patch,
combining the two steps into one sentence doesn't help clarify
things given that target_terminal_inferior can do more than just
"remove stdin from the event loop".

E.g., this is a marginal improvement:

  /* Set up the "saved terminal modes" of the inferior based on what
     modes we are starting it with.  */
  target_terminal_init ();
  /* And remove stdin from the event loop.  */
  target_terminal_inferior ();

But I'm hoping for more text in the second comment to explain things
better.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-04 13:48           ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Pedro Alves
  2014-07-04 21:13             ` Mark Wielaard
  2014-07-07 16:39             ` Doug Evans
@ 2014-07-07 17:02             ` Jan Kratochvil
  2 siblings, 0 replies; 42+ messages in thread
From: Jan Kratochvil @ 2014-07-07 17:02 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Mark Wielaard, gdb-patches

On Fri, 04 Jul 2014 15:48:40 +0200, Pedro Alves wrote:
> Here's a fix.  Let me know whether it fixes guality testing.

Mark has already replied the same but I can also confirm it fixes the GCC
testsuite.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-07 16:39             ` Doug Evans
@ 2014-07-08 15:24               ` Pedro Alves
  2014-07-09 16:37                 ` Doug Evans
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-07-08 15:24 UTC (permalink / raw)
  To: Doug Evans; +Cc: Mark Wielaard, Jan Kratochvil, gdb-patches

On 07/07/2014 05:39 PM, Doug Evans wrote:

> Our nomenclature here is problematic. I always do a double take when
> I see attach and target_terminal_foo mentioned in the same sentence.
> Bleah.

Why?  "run; detach; attach SAME_PID" is a trivial case where we end
up attached to an inferior that is sharing the same tty as GDB.  In
fact, the test does that.

> But I'm hoping for more text in the second comment to explain things
> better.

See updated patch and let me know what you think.

FYI, I wrote a test that sends a ctrl-c right after "attach", which triggers
the issue mentioned in the comment, but it also trips on a set of
other races (orthogonal to sync/async), which made the test not
even KFAILable, and so worthless.

------
From ef85a658ee8ff26c0b3b18db7ea7ee3da3d3650b Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Tue, 8 Jul 2014 13:25:58 +0100
Subject: [PATCH] Fix "attach" command vs user input race

On async targets, a synchronous attach is done like this:

   #1 - target_attach is called (PTRACE_ATTACH is issued)
   #2 - a continuation is installed
   #3 - we go back to the event loop
   #4 - target reports stop (SIGSTOP), event loop wakes up, and
        attach continuation is called
   #5 - among other things, the continuation calls
        target_terminal_inferior, which removes stdin from the event
        loop

Note that in #3, GDB is still processing user input.  If the user is
fast enough, e.g., with something like:

  echo -e "attach PID\nset xxx=1" | gdb

... then the "set" command is processed before the attach completes.

We get worse behavior even, if input is a tty and therefore
readline/editing is enabled, with e.g.,:

 (gdb) attach PID\nset xxx=1

we then crash readline/gdb, with:

 Attaching to program: attach-wait-input, process 14537
 readline: readline_callback_read_char() called with no handler!
 Aborted
 $

Fix this by calling target_terminal_inferior before #3 above.

The test covers both scenarios by running with editing/readline forced
to both on and off.

gdb/
2014-07-04  Pedro Alves  <palves@redhat.com>

	* infcmd.c (attach_command_post_wait): Don't call
	target_terminal_inferior here.
	(attach_command): Call it here instead.

gdb/testsuite/
2014-07-04  Pedro Alves  <palves@redhat.com>

	* gdb.base/attach-wait-input.exp: New file.
	* gdb.base/attach-wait-input.c: New file.
---
 gdb/infcmd.c                                 |  23 ++++--
 gdb/testsuite/gdb.base/attach-wait-input.c   |  40 +++++++++
 gdb/testsuite/gdb.base/attach-wait-input.exp | 119 +++++++++++++++++++++++++++
 3 files changed, 177 insertions(+), 5 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/attach-wait-input.c
 create mode 100644 gdb/testsuite/gdb.base/attach-wait-input.exp

diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index c4bb401..df7a6cd 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2381,9 +2381,6 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
 
   post_create_inferior (&current_target, from_tty);
 
-  /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
-
   if (async_exec)
     {
       /* The user requested an `attach&', so be sure to leave threads
@@ -2495,10 +2492,26 @@ attach_command (char *args, int from_tty)
      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.  */
+  /* Set up the "saved terminal modes" of the inferior based on what
+     modes we are starting it with.  */
   target_terminal_init ();
 
+  /* Install inferior's terminal modes.  This may look like a no-op,
+     as we've just saved them above, however, this does more than
+     restore terminal settings:
+
+     - installs a SIGINT handler that forwards SIGINT to the inferior.
+       Otherwise a Ctrl-C pressed just while waiting for that initial
+       stop would end up as a spurious Quit.
+
+     - removes stdin from the event loop, which we need if attaching
+       in the foreground, otherwise on targets that report an initial
+       stop on attach (which are most) we'd process input/commands
+       while we're in the event loop waiting for that stop.  That is,
+       before the attach continuation runs and the command is really
+       finished.  */
+  target_terminal_inferior ();
+
   /* Set up execution context to know that we should return from
      wait_for_inferior as soon as the target reports a stop.  */
   init_wait_for_inferior ();
diff --git a/gdb/testsuite/gdb.base/attach-wait-input.c b/gdb/testsuite/gdb.base/attach-wait-input.c
new file mode 100644
index 0000000..bddf2e1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach-wait-input.c
@@ -0,0 +1,40 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <sys/types.h>
+#include <unistd.h>
+
+volatile int should_exit = 0;
+int mypid;
+
+static void
+setup_done (void)
+{
+}
+
+int
+main (void)
+{
+  unsigned int counter = 1;
+
+  mypid = getpid ();
+  setup_done ();
+
+  for (counter = 0; !should_exit && counter < 100; counter++)
+    sleep (1);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/attach-wait-input.exp b/gdb/testsuite/gdb.base/attach-wait-input.exp
new file mode 100644
index 0000000..d6d572e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach-wait-input.exp
@@ -0,0 +1,119 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+# Verify that GDB waits for the "attach" command to finish before
+# processing the following command.
+#
+# GDB used to have a race where on async targets, in the small window
+# between the attach request and the initial stop for the attach, GDB
+# was still processing user input.
+#
+# The issue was originally detected with:
+#
+#  echo -e "attach PID\nset xxx=1" | gdb
+#
+# In that scenario, stdin is not a tty, which disables readline.
+# Explicitly turning off editing exercises the same code path, and is
+# simpler to do, so we test with both editing on and off.
+
+# The test uses the "attach" command.
+if [target_info exists use_gdb_stub] {
+    return
+}
+
+standard_testfile
+
+if {[build_executable "failed to build" $testfile $srcfile debug]} {
+    return -1
+}
+
+# Start the program running, and return its PID, ready for attaching.
+
+proc start_program {binfile} {
+    global gdb_prompt
+    global decimal
+
+    clean_restart $binfile
+
+    if ![runto setup_done] then {
+	fail "Can't run to setup_done"
+	return 0
+    }
+
+    # Get the PID of the test process.
+    set testpid ""
+    set test "get inferior process ID"
+    gdb_test_multiple "p mypid" $test {
+	-re " = ($decimal)\r\n$gdb_prompt $" {
+	    set testpid $expect_out(1,string)
+	    pass $test
+	}
+    }
+
+    gdb_test "detach" "Detaching from program: .*"
+
+    if {$testpid == ""} {
+	return
+    }
+
+    return $testpid
+}
+
+# Do test proper.  EDITING indicates whether "set editing" is on or
+# off.
+
+proc test { editing } {
+    global gdb_prompt
+    global binfile
+    global decimal
+
+    with_test_prefix "editing $editing" {
+
+	set testpid [start_program $binfile]
+	if {$testpid == ""} {
+	    return
+	}
+
+	# Enable/disable readline.
+	gdb_test_no_output "set editing $editing"
+
+	# Send both commands at once.
+	send_gdb "attach $testpid\nprint should_exit = 1\n"
+
+	# Use gdb_expect directly instead of gdb_test_multiple to
+	# avoid races with the double prompt.
+	set test "attach and print"
+	gdb_expect {
+	    -re "Attaching to program.*process $testpid\r\n.*$gdb_prompt.*$decimal = 1\r\n$gdb_prompt $" {
+		pass "$test"
+	    }
+	    timeout {
+		fail "$test (timeout)"
+	    }
+	}
+
+	# As we've used attach, on quit, we'll detach from the
+	# program.  Explicitly kill it in case we failed above.
+	gdb_test "kill" \
+	    "" \
+	    "after attach, exit" \
+	    "Kill the program being debugged.*y or n. $" \
+	    "y"
+    }
+}
+
+foreach editing {"on" "off"} {
+    test $editing
+}
-- 
1.9.3


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-08 15:24               ` Pedro Alves
@ 2014-07-09 16:37                 ` Doug Evans
  2014-07-09 17:09                   ` [pushed+7.8] " Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Doug Evans @ 2014-07-09 16:37 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Mark Wielaard, Jan Kratochvil, gdb-patches

Pedro Alves writes:
 > On 07/07/2014 05:39 PM, Doug Evans wrote:
 > 
 > > Our nomenclature here is problematic. I always do a double take when
 > > I see attach and target_terminal_foo mentioned in the same sentence.
 > > Bleah.
 > 
 > Why?  "run; detach; attach SAME_PID" is a trivial case where we end
 > up attached to an inferior that is sharing the same tty as GDB.  In
 > fact, the test does that.

I know.

But for me it's not the normal case.
I wish the naming/wording could better reflect what's happening.
[but that's not something that has to be addressed here of course]

 > @@ -2495,10 +2492,26 @@ attach_command (char *args, int from_tty)
 >       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.  */
 > +  /* Set up the "saved terminal modes" of the inferior based on what
 > +     modes we are starting it with.  */
 >    target_terminal_init ();

spurious change

 >  
 > +  /* Install inferior's terminal modes.  This may look like a no-op,
 > +     as we've just saved them above, however, this does more than
 > +     restore terminal settings:
 > +
 > +     - installs a SIGINT handler that forwards SIGINT to the inferior.
 > +       Otherwise a Ctrl-C pressed just while waiting for that initial
 > +       stop would end up as a spurious Quit.
 > +
 > +     - removes stdin from the event loop, which we need if attaching
 > +       in the foreground, otherwise on targets that report an initial
 > +       stop on attach (which are most) we'd process input/commands
 > +       while we're in the event loop waiting for that stop.  That is,
 > +       before the attach continuation runs and the command is really
 > +       finished.  */
 > +  target_terminal_inferior ();
 > +
 >    /* Set up execution context to know that we should return from
 >       wait_for_inferior as soon as the target reports a stop.  */
 >    init_wait_for_inferior ();

I like this a lot better.  Thanks.
The patch is ok with me, modulo removing the spurious change.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-09 16:37                 ` Doug Evans
@ 2014-07-09 17:09                   ` Pedro Alves
  2014-07-29 22:03                     ` Doug Evans
  2014-09-03  7:59                     ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]] Jan Kratochvil
  0 siblings, 2 replies; 42+ messages in thread
From: Pedro Alves @ 2014-07-09 17:09 UTC (permalink / raw)
  To: Doug Evans; +Cc: Mark Wielaard, Jan Kratochvil, gdb-patches

On 07/09/2014 05:37 PM, Doug Evans wrote:

> spurious change

Fixed.

> I like this a lot better.  Thanks.
> The patch is ok with me, modulo removing the spurious change.

Here's what I pushed to both master and gdb-7.8-branch.

Thanks.

-------------
From 1fe2833b6dd03602ba86aa334e81466ea9abe66a Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Wed, 9 Jul 2014 17:52:58 +0100
Subject: [PATCH] Fix "attach" command vs user input race

On async targets, a synchronous attach is done like this:

   #1 - target_attach is called (PTRACE_ATTACH is issued)
   #2 - a continuation is installed
   #3 - we go back to the event loop
   #4 - target reports stop (SIGSTOP), event loop wakes up, and
        attach continuation is called
   #5 - among other things, the continuation calls
        target_terminal_inferior, which removes stdin from the event
        loop

Note that in #3, GDB is still processing user input.  If the user is
fast enough, e.g., with something like:

  echo -e "attach PID\nset xxx=1" | gdb

... then the "set" command is processed before the attach completes.

We get worse behavior even, if input is a tty and therefore
readline/editing is enabled, with e.g.,:

 (gdb) attach PID\nset xxx=1

we then crash readline/gdb, with:

 Attaching to program: attach-wait-input, process 14537
 readline: readline_callback_read_char() called with no handler!
 Aborted
 $

Fix this by calling target_terminal_inferior before #3 above.

The test covers both scenarios by running with editing/readline forced
to both on and off.

gdb/
2014-07-09  Pedro Alves  <palves@redhat.com>

	* infcmd.c (attach_command_post_wait): Don't call
	target_terminal_inferior here.
	(attach_command): Call it here instead.

gdb/testsuite/
2014-07-09  Pedro Alves  <palves@redhat.com>

	* gdb.base/attach-wait-input.exp: New file.
	* gdb.base/attach-wait-input.c: New file.
---
 gdb/ChangeLog                                |   6 ++
 gdb/testsuite/ChangeLog                      |   5 ++
 gdb/infcmd.c                                 |  19 ++++-
 gdb/testsuite/gdb.base/attach-wait-input.c   |  40 +++++++++
 gdb/testsuite/gdb.base/attach-wait-input.exp | 119 +++++++++++++++++++++++++++
 5 files changed, 186 insertions(+), 3 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/attach-wait-input.c
 create mode 100644 gdb/testsuite/gdb.base/attach-wait-input.exp

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d4304e6..1bd19fc 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-09  Pedro Alves  <palves@redhat.com>
+
+	* infcmd.c (attach_command_post_wait): Don't call
+	target_terminal_inferior here.
+	(attach_command): Call it here instead.
+
 2014-07-07  Pedro Alves  <palves@redhat.com>
 
 	PR gdb/17096
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 7667969..66dcc95 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-07-09  Pedro Alves  <palves@redhat.com>
+
+	* gdb.base/attach-wait-input.exp: New file.
+	* gdb.base/attach-wait-input.c: New file.
+
 2014-06-23  Siva Chandra Reddy  <sivachandra@google.com>
 
 	* gdb.python/py-xmethods.exp: Use "progspace" instead of the
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index df4fd40..a712b6f 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2381,9 +2381,6 @@ attach_command_post_wait (char *args, int from_tty, int async_exec)
 
   post_create_inferior (&current_target, from_tty);
 
-  /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
-
   if (async_exec)
     {
       /* The user requested an `attach&', so be sure to leave threads
@@ -2499,6 +2496,22 @@ attach_command (char *args, int from_tty)
      based on what modes we are starting it with.  */
   target_terminal_init ();
 
+  /* Install inferior's terminal modes.  This may look like a no-op,
+     as we've just saved them above, however, this does more than
+     restore terminal settings:
+
+     - installs a SIGINT handler that forwards SIGINT to the inferior.
+       Otherwise a Ctrl-C pressed just while waiting for the initial
+       stop would end up as a spurious Quit.
+
+     - removes stdin from the event loop, which we need if attaching
+       in the foreground, otherwise on targets that report an initial
+       stop on attach (which are most) we'd process input/commands
+       while we're in the event loop waiting for that stop.  That is,
+       before the attach continuation runs and the command is really
+       finished.  */
+  target_terminal_inferior ();
+
   /* Set up execution context to know that we should return from
      wait_for_inferior as soon as the target reports a stop.  */
   init_wait_for_inferior ();
diff --git a/gdb/testsuite/gdb.base/attach-wait-input.c b/gdb/testsuite/gdb.base/attach-wait-input.c
new file mode 100644
index 0000000..bddf2e1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach-wait-input.c
@@ -0,0 +1,40 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2014 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <sys/types.h>
+#include <unistd.h>
+
+volatile int should_exit = 0;
+int mypid;
+
+static void
+setup_done (void)
+{
+}
+
+int
+main (void)
+{
+  unsigned int counter = 1;
+
+  mypid = getpid ();
+  setup_done ();
+
+  for (counter = 0; !should_exit && counter < 100; counter++)
+    sleep (1);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/attach-wait-input.exp b/gdb/testsuite/gdb.base/attach-wait-input.exp
new file mode 100644
index 0000000..d6d572e
--- /dev/null
+++ b/gdb/testsuite/gdb.base/attach-wait-input.exp
@@ -0,0 +1,119 @@
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+# Verify that GDB waits for the "attach" command to finish before
+# processing the following command.
+#
+# GDB used to have a race where on async targets, in the small window
+# between the attach request and the initial stop for the attach, GDB
+# was still processing user input.
+#
+# The issue was originally detected with:
+#
+#  echo -e "attach PID\nset xxx=1" | gdb
+#
+# In that scenario, stdin is not a tty, which disables readline.
+# Explicitly turning off editing exercises the same code path, and is
+# simpler to do, so we test with both editing on and off.
+
+# The test uses the "attach" command.
+if [target_info exists use_gdb_stub] {
+    return
+}
+
+standard_testfile
+
+if {[build_executable "failed to build" $testfile $srcfile debug]} {
+    return -1
+}
+
+# Start the program running, and return its PID, ready for attaching.
+
+proc start_program {binfile} {
+    global gdb_prompt
+    global decimal
+
+    clean_restart $binfile
+
+    if ![runto setup_done] then {
+	fail "Can't run to setup_done"
+	return 0
+    }
+
+    # Get the PID of the test process.
+    set testpid ""
+    set test "get inferior process ID"
+    gdb_test_multiple "p mypid" $test {
+	-re " = ($decimal)\r\n$gdb_prompt $" {
+	    set testpid $expect_out(1,string)
+	    pass $test
+	}
+    }
+
+    gdb_test "detach" "Detaching from program: .*"
+
+    if {$testpid == ""} {
+	return
+    }
+
+    return $testpid
+}
+
+# Do test proper.  EDITING indicates whether "set editing" is on or
+# off.
+
+proc test { editing } {
+    global gdb_prompt
+    global binfile
+    global decimal
+
+    with_test_prefix "editing $editing" {
+
+	set testpid [start_program $binfile]
+	if {$testpid == ""} {
+	    return
+	}
+
+	# Enable/disable readline.
+	gdb_test_no_output "set editing $editing"
+
+	# Send both commands at once.
+	send_gdb "attach $testpid\nprint should_exit = 1\n"
+
+	# Use gdb_expect directly instead of gdb_test_multiple to
+	# avoid races with the double prompt.
+	set test "attach and print"
+	gdb_expect {
+	    -re "Attaching to program.*process $testpid\r\n.*$gdb_prompt.*$decimal = 1\r\n$gdb_prompt $" {
+		pass "$test"
+	    }
+	    timeout {
+		fail "$test (timeout)"
+	    }
+	}
+
+	# As we've used attach, on quit, we'll detach from the
+	# program.  Explicitly kill it in case we failed above.
+	gdb_test "kill" \
+	    "" \
+	    "after attach, exit" \
+	    "Kill the program being debugged.*y or n. $" \
+	    "y"
+    }
+}
+
+foreach editing {"on" "off"} {
+    test $editing
+}
-- 
1.9.3


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-09 17:09                   ` [pushed+7.8] " Pedro Alves
@ 2014-07-29 22:03                     ` Doug Evans
  2014-07-29 23:10                       ` Doug Evans
  2014-07-30 12:38                       ` Pedro Alves
  2014-09-03  7:59                     ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]] Jan Kratochvil
  1 sibling, 2 replies; 42+ messages in thread
From: Doug Evans @ 2014-07-29 22:03 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Wed, Jul 9, 2014 at 10:09 AM, Pedro Alves <palves@redhat.com> wrote:
> On 07/09/2014 05:37 PM, Doug Evans wrote:
>
>> spurious change
>
> Fixed.
>
>> I like this a lot better.  Thanks.
>> The patch is ok with me, modulo removing the spurious change.
>
> Here's what I pushed to both master and gdb-7.8-branch.
>
> Thanks.
>
> -------------
> From 1fe2833b6dd03602ba86aa334e81466ea9abe66a Mon Sep 17 00:00:00 2001
> From: Pedro Alves <palves@redhat.com>
> Date: Wed, 9 Jul 2014 17:52:58 +0100
> Subject: [PATCH] Fix "attach" command vs user input race
>
> On async targets, a synchronous attach is done like this:
>
>    #1 - target_attach is called (PTRACE_ATTACH is issued)
>    #2 - a continuation is installed
>    #3 - we go back to the event loop
>    #4 - target reports stop (SIGSTOP), event loop wakes up, and
>         attach continuation is called
>    #5 - among other things, the continuation calls
>         target_terminal_inferior, which removes stdin from the event
>         loop
>
> Note that in #3, GDB is still processing user input.  If the user is
> fast enough, e.g., with something like:
>
>   echo -e "attach PID\nset xxx=1" | gdb
>
> ... then the "set" command is processed before the attach completes.
>
> We get worse behavior even, if input is a tty and therefore
> readline/editing is enabled, with e.g.,:
>
>  (gdb) attach PID\nset xxx=1
>
> we then crash readline/gdb, with:
>
>  Attaching to program: attach-wait-input, process 14537
>  readline: readline_callback_read_char() called with no handler!
>  Aborted
>  $
>
> Fix this by calling target_terminal_inferior before #3 above.
>
> The test covers both scenarios by running with editing/readline forced
> to both on and off.
>
> gdb/
> 2014-07-09  Pedro Alves  <palves@redhat.com>
>
>         * infcmd.c (attach_command_post_wait): Don't call
>         target_terminal_inferior here.
>         (attach_command): Call it here instead.
>
> gdb/testsuite/
> 2014-07-09  Pedro Alves  <palves@redhat.com>
>
>         * gdb.base/attach-wait-input.exp: New file.
>         * gdb.base/attach-wait-input.c: New file.

Hi.

Is this TODO still needed after this patch?

infcmd.c:

/*
 * TODO:
 * Should save/restore the tty state since it might be that the
 * program to be debugged was started on this tty and it wants
 * the tty in some state other than what we want.  If it's running
 * on another terminal or without a terminal, then saving and
 * restoring the tty state is a harmless no-op.
 * This only needs to be done if we are attaching to a process.
 */

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-29 22:03                     ` Doug Evans
@ 2014-07-29 23:10                       ` Doug Evans
  2014-07-30 12:46                         ` Pedro Alves
  2014-07-30 12:38                       ` Pedro Alves
  1 sibling, 1 reply; 42+ messages in thread
From: Doug Evans @ 2014-07-29 23:10 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Tue, Jul 29, 2014 at 2:48 PM, Doug Evans <dje@google.com> wrote:
> On Wed, Jul 9, 2014 at 10:09 AM, Pedro Alves <palves@redhat.com> wrote:
>> On 07/09/2014 05:37 PM, Doug Evans wrote:
>>
>>> spurious change
>>
>> Fixed.
>>
>>> I like this a lot better.  Thanks.
>>> The patch is ok with me, modulo removing the spurious change.
>>
>> Here's what I pushed to both master and gdb-7.8-branch.
>>
>> Thanks.
>>
>> -------------
>> From 1fe2833b6dd03602ba86aa334e81466ea9abe66a Mon Sep 17 00:00:00 2001
>> From: Pedro Alves <palves@redhat.com>
>> Date: Wed, 9 Jul 2014 17:52:58 +0100
>> Subject: [PATCH] Fix "attach" command vs user input race
>>
>> On async targets, a synchronous attach is done like this:
>>
>>    #1 - target_attach is called (PTRACE_ATTACH is issued)
>>    #2 - a continuation is installed
>>    #3 - we go back to the event loop
>>    #4 - target reports stop (SIGSTOP), event loop wakes up, and
>>         attach continuation is called
>>    #5 - among other things, the continuation calls
>>         target_terminal_inferior, which removes stdin from the event
>>         loop
>>
>> Note that in #3, GDB is still processing user input.  If the user is
>> fast enough, e.g., with something like:
>>
>>   echo -e "attach PID\nset xxx=1" | gdb
>>
>> ... then the "set" command is processed before the attach completes.
>>
>> We get worse behavior even, if input is a tty and therefore
>> readline/editing is enabled, with e.g.,:
>>
>>  (gdb) attach PID\nset xxx=1
>>
>> we then crash readline/gdb, with:
>>
>>  Attaching to program: attach-wait-input, process 14537
>>  readline: readline_callback_read_char() called with no handler!
>>  Aborted
>>  $
>>
>> Fix this by calling target_terminal_inferior before #3 above.
>>
>> The test covers both scenarios by running with editing/readline forced
>> to both on and off.
>>
>> gdb/
>> 2014-07-09  Pedro Alves  <palves@redhat.com>
>>
>>         * infcmd.c (attach_command_post_wait): Don't call
>>         target_terminal_inferior here.
>>         (attach_command): Call it here instead.
>>
>> gdb/testsuite/
>> 2014-07-09  Pedro Alves  <palves@redhat.com>
>>
>>         * gdb.base/attach-wait-input.exp: New file.
>>         * gdb.base/attach-wait-input.c: New file.
>
> Hi.
>
> Is this TODO still needed after this patch?
>
> infcmd.c:
>
> /*
>  * TODO:
>  * Should save/restore the tty state since it might be that the
>  * program to be debugged was started on this tty and it wants
>  * the tty in some state other than what we want.  If it's running
>  * on another terminal or without a terminal, then saving and
>  * restoring the tty state is a harmless no-op.
>  * This only needs to be done if we are attaching to a process.
>  */

A related issue (or the same one if one prefers):

post_create_inferior does this:

  /* Be sure we own the terminal in case write operations are performed.  */
  target_terminal_ours ();

but post_create_inferior is called *after* target_post_attach
in attach_command_post_wait:

  /* Take any necessary post-attaching actions for this platform.  */
  target_post_attach (ptid_get_pid (inferior_ptid));

  post_create_inferior (&current_target, from_tty);

What if target_post_attach does some writes?
Seems like it can, e.g., some of the ptrace checking stuff may print a warning.
Plus attach_command_post_wait calls some other stuff before
post_create_inferior that could cause some writes to the terminal.

Question: Is there a specific terminal state that needs to be in
effect when attach_command_post_wait returns?
Or can we just call target_terminal_ours at its start?
[and leave it to other code to switch back to target_terminal_inferior
as needed - e.g. proceed calls resume which will call
target_terminal_inferior]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-29 22:03                     ` Doug Evans
  2014-07-29 23:10                       ` Doug Evans
@ 2014-07-30 12:38                       ` Pedro Alves
  2014-07-30 16:59                         ` Doug Evans
  1 sibling, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-07-30 12:38 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

On 07/29/2014 10:48 PM, Doug Evans wrote:
> On Wed, Jul 9, 2014 at 10:09 AM, Pedro Alves <palves@redhat.com> wrote:
>> On 07/09/2014 05:37 PM, Doug Evans wrote:
>>
>>> spurious change
>>
>> Fixed.
>>
>>> I like this a lot better.  Thanks.
>>> The patch is ok with me, modulo removing the spurious change.
>>
>> Here's what I pushed to both master and gdb-7.8-branch.
>>
>> Thanks.
>>
>> -------------
>> From 1fe2833b6dd03602ba86aa334e81466ea9abe66a Mon Sep 17 00:00:00 2001
>> From: Pedro Alves <palves@redhat.com>
>> Date: Wed, 9 Jul 2014 17:52:58 +0100
>> Subject: [PATCH] Fix "attach" command vs user input race
>>
>> On async targets, a synchronous attach is done like this:
>>
>>    #1 - target_attach is called (PTRACE_ATTACH is issued)
>>    #2 - a continuation is installed
>>    #3 - we go back to the event loop
>>    #4 - target reports stop (SIGSTOP), event loop wakes up, and
>>         attach continuation is called
>>    #5 - among other things, the continuation calls
>>         target_terminal_inferior, which removes stdin from the event
>>         loop
>>
>> Note that in #3, GDB is still processing user input.  If the user is
>> fast enough, e.g., with something like:
>>
>>   echo -e "attach PID\nset xxx=1" | gdb
>>
>> ... then the "set" command is processed before the attach completes.
>>
>> We get worse behavior even, if input is a tty and therefore
>> readline/editing is enabled, with e.g.,:
>>
>>  (gdb) attach PID\nset xxx=1
>>
>> we then crash readline/gdb, with:
>>
>>  Attaching to program: attach-wait-input, process 14537
>>  readline: readline_callback_read_char() called with no handler!
>>  Aborted
>>  $
>>
>> Fix this by calling target_terminal_inferior before #3 above.
>>
>> The test covers both scenarios by running with editing/readline forced
>> to both on and off.
>>
>> gdb/
>> 2014-07-09  Pedro Alves  <palves@redhat.com>
>>
>>         * infcmd.c (attach_command_post_wait): Don't call
>>         target_terminal_inferior here.
>>         (attach_command): Call it here instead.
>>
>> gdb/testsuite/
>> 2014-07-09  Pedro Alves  <palves@redhat.com>
>>
>>         * gdb.base/attach-wait-input.exp: New file.
>>         * gdb.base/attach-wait-input.c: New file.
> 
> Hi.
> 
> Is this TODO still needed after this patch?
> 
> infcmd.c:
> 
> /*
>  * TODO:
>  * Should save/restore the tty state since it might be that the
>  * program to be debugged was started on this tty and it wants
>  * the tty in some state other than what we want.  If it's running
>  * on another terminal or without a terminal, then saving and
>  * restoring the tty state is a harmless no-op.
>  * This only needs to be done if we are attaching to a process.
>  */
> 

As usual, git blame/log is your friend...

That's been in place for over 20 years.   In bd5635a1 (1991), we see:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
 * TODO:
 * Should save/restore the tty state since it might be that the
 * program to be debugged was started on this tty and it wants
 * the tty in some state other than what we want.  If it's running
 * on another terminal or without a terminal, then saving and
 * restoring the tty state is a harmless no-op.
 * This only needs to be done if we are attaching to a process.
 */

/*
 * attach_command --
 * takes a program started up outside of gdb and ``attaches'' to it.
 * This stops it cold in its tracks and allows us to start tracing it.
 * For this to work, we must be able to send the process a
 * signal and we must have the same effective uid as the program.
 */
void
attach_command (args, from_tty)
     char *args;
     int from_tty;
{
  target_attach (args, from_tty);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


So clearly the TODO has been stale for a long while.
We've been saving/restoring the tty state way before
my patch.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-29 23:10                       ` Doug Evans
@ 2014-07-30 12:46                         ` Pedro Alves
  0 siblings, 0 replies; 42+ messages in thread
From: Pedro Alves @ 2014-07-30 12:46 UTC (permalink / raw)
  To: Doug Evans; +Cc: gdb-patches

On 07/29/2014 11:03 PM, Doug Evans wrote:
> A related issue (or the same one if one prefers):
> 
> post_create_inferior does this:
> 
>   /* Be sure we own the terminal in case write operations are performed.  */
>   target_terminal_ours ();

Yeah.

As I mentioned before, when I wrote a test that sends a ctrl-c right
after "attach", which triggered the issue mentioned in the new
comment,

     - installs a SIGINT handler that forwards SIGINT to the inferior.
       Otherwise a Ctrl-C pressed just while waiting for the initial
       stop would end up as a spurious Quit.

it tripped on a set of other races.

This call was one of them.  We should actually be calling
target_terminal_ours_for_output, not target_terminal_ours, so
that stdin/ctrl-c is still redirected to the inferior.  As is,
IIRC, if a ctrl-c arrives after than target_terminal_ours and before
the next target_terminal_inferior, we end up in the prompt, with
a Quit, but with the target still running.

I gave up fixing those at the time, as they're orthogonal to
sync/async.

> 
> but post_create_inferior is called *after* target_post_attach
> in attach_command_post_wait:
> 
>   /* Take any necessary post-attaching actions for this platform.  */
>   target_post_attach (ptid_get_pid (inferior_ptid));
> 
>   post_create_inferior (&current_target, from_tty);
> 
> What if target_post_attach does some writes?

Something should call target_terminal_ours_for_output before.

> Seems like it can, e.g., some of the ptrace checking stuff may print a warning.
> Plus attach_command_post_wait calls some other stuff before
> post_create_inferior that could cause some writes to the terminal.
> 
> Question: Is there a specific terminal state that needs to be in
> effect when attach_command_post_wait returns?
> Or can we just call target_terminal_ours at its start?

I think we can.

> [and leave it to other code to switch back to target_terminal_inferior
> as needed - e.g. proceed calls resume which will call
> target_terminal_inferior]

Even with that, it'll still be possible to have a ctrl-c pressed after
to_attach is called, and before target_terminal_inferior is called
(and therefore set_sigint_trap is called, which sets up ctrl-c
forwarding).

When I last looked at this, it seemed to be that ideally, we should
only have a single SIGINT handler, which just records that a ctrl-c was
pressed, and then the event loop decides whether a ctrl-c is a Quit or
whether it should be forwarded to the inferior, depending on whether the
target is running on the foreground, or not.

-- 
Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]
  2014-07-30 12:38                       ` Pedro Alves
@ 2014-07-30 16:59                         ` Doug Evans
  2014-08-21 16:34                           ` [PUSHED] infcmd.c: Remove stale TODO Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Doug Evans @ 2014-07-30 16:59 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Wed, Jul 30, 2014 at 5:05 AM, Pedro Alves <palves@redhat.com> wrote:
>>> [...]
>>> gdb/
>>> 2014-07-09  Pedro Alves  <palves@redhat.com>
>>>
>>>         * infcmd.c (attach_command_post_wait): Don't call
>>>         target_terminal_inferior here.
>>>         (attach_command): Call it here instead.
>>>
>>> gdb/testsuite/
>>> 2014-07-09  Pedro Alves  <palves@redhat.com>
>>>
>>>         * gdb.base/attach-wait-input.exp: New file.
>>>         * gdb.base/attach-wait-input.c: New file.
>>
>> Hi.
>>
>> Is this TODO still needed after this patch?
>>
>> infcmd.c:
>>
>> /*
>>  * TODO:
>>  * Should save/restore the tty state since it might be that the
>>  * program to be debugged was started on this tty and it wants
>>  * the tty in some state other than what we want.  If it's running
>>  * on another terminal or without a terminal, then saving and
>>  * restoring the tty state is a harmless no-op.
>>  * This only needs to be done if we are attaching to a process.
>>  */
>>
>
> As usual, git blame/log is your friend...
>
> That's been in place for over 20 years.   In bd5635a1 (1991), we see:
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> /*
>  * TODO:
>  * Should save/restore the tty state since it might be that the
>  * program to be debugged was started on this tty and it wants
>  * the tty in some state other than what we want.  If it's running
>  * on another terminal or without a terminal, then saving and
>  * restoring the tty state is a harmless no-op.
>  * This only needs to be done if we are attaching to a process.
>  */
>
> /*
>  * attach_command --
>  * takes a program started up outside of gdb and ``attaches'' to it.
>  * This stops it cold in its tracks and allows us to start tracing it.
>  * For this to work, we must be able to send the process a
>  * signal and we must have the same effective uid as the program.
>  */
> void
> attach_command (args, from_tty)
>      char *args;
>      int from_tty;
> {
>   target_attach (args, from_tty);
> }
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>
> So clearly the TODO has been stale for a long while.

23 years?  Zoinks! :)

> We've been saving/restoring the tty state way before
> my patch.
>
> Thanks,
> Pedro Alves
>

It wasn't clear to me whether the comment was (trying to) refer to
something more specific for the task at hand.  Just being too literal
I guess.
Thanks.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v6 2/2] enable target async by default; separate MI and target notions of async
  2014-05-29 13:49     ` Pedro Alves
@ 2014-07-30 18:40       ` Doug Evans
  0 siblings, 0 replies; 42+ messages in thread
From: Doug Evans @ 2014-07-30 18:40 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Eli Zaretskii, gdb-patches

On Thu, May 29, 2014 at 6:48 AM, Pedro Alves <palves@redhat.com> wrote:
> [...]
> Below's what I pushed.
>
> 8<------------
> Subject: [PATCH] enable target async by default; separate MI and target
>  notions of async
>
> This finally makes background execution commands possible by default.
>
> However, in order to do that, there's one last thing we need to do --
> we need to separate the MI and target notions of "async".  Unlike the
> CLI, where the user explicitly requests foreground vs background
> execution in the execution command itself (c vs c&), MI chose to treat
> "set target-async" specially -- setting it changes the default
> behavior of execution commands.
>
> So, we can't simply "set target-async" default to on, as that would
> affect MI frontends.  Instead we have to make the setting MI-specific,
> and teach MI about sync commands on top of an async target.
>
> Because the "target" word in "set target-async" ends up as a potential
> source of confusion, the patch adds a "set mi-async" option, and makes
> "set target-async" a deprecated alias.
>
> Rather than make the targets always async, this patch introduces a new
> "maint set target-async" option so that the GDB developer can control
> whether the target is async.  This makes it simpler to debug issues
> arising only in the synchronous mode; important because sync mode
> seems unlikely to go away.
>
> Unlike in previous revisions, "set target-async" does not affect this
> new maint parameter.  The rationale for this is that then one can
> easily run the test suite in the "maint set target-async off" mode and
> have tests that enable mi-async fail just like they fail on
> non-async-capable targets.  This emulation is exactly the point of the
> maint option.
>
> I had asked Tom in a previous iteration to split the actual change of
> the target async default to a separate patch, but it turns out that
> that is quite awkward in this version of the patch, because with MI
> async and target async decoupled (unlike in previous versions), if we
> don't flip the default at the same time, then just "set target-async
> on" alone never actually manages to do anything.  It's best to not
> have that transitory state in the tree.
>
> Given "set target-async on" now only has effect for MI, the patch goes
> through the testsuite removing it from non-MI tests.  MI tests are
> adjusted to use the new and less confusing "mi-async" spelling.
>
> 2014-05-29  Pedro Alves  <palves@redhat.com>
>             Tom Tromey  <tromey@redhat.com>
>
>         * NEWS: Mention "maint set target-async", "set mi-async", and that
>         background execution commands are now always available.
>         * target.h (target_async_permitted): Update comment.
>         * target.c (target_async_permitted, target_async_permitted_1):
>         Default to 1.
>         (set_target_async_command): Rename to ...
>         (maint_set_target_async_command): ... this.
>         (show_target_async_command): Rename to ...
>         (maint_show_target_async_command): ... this.
>         (_initialize_target): Adjust.
>         * infcmd.c (prepare_execution_command): Make extern.
>         * inferior.h (prepare_execution_command): Declare.
>         * infrun.c (set_observer_mode): Leave target async alone.
>         * mi/mi-interp.c (mi_interpreter_init): Install
>         mi_on_sync_execution_done as sync_execution_done observer.
>         (mi_on_sync_execution_done): New function.
>         (mi_execute_command_input_handler): Don't print the prompt if we
>         just started a synchronous command with an async target.
>         (mi_on_resume): Check sync_execution before printing prompt.
>         * mi/mi-main.h (mi_async_p): Declare.
>         * mi/mi-main.c: Include gdbcmd.h.
>         (mi_async_p): New function.
>         (mi_async, mi_async_1): New globals.
>         (set_mi_async_command, show_mi_async_command, mi_async): New
>         functions.
>         (exec_continue): Call prepare_execution_command.
>         (run_one_inferior, mi_cmd_exec_run, mi_cmd_list_target_features)
>         (mi_execute_async_cli_command): Use mi_async_p.
>         (_initialize_mi_main): Install "set mi-async".  Make
>         "target-async" a deprecated alias.
>
> 2014-05-29  Pedro Alves  <palves@redhat.com>
>             Tom Tromey  <tromey@redhat.com>
>
>         * gdb.texinfo (Non-Stop Mode): Remove "set target-async 1"
>         from example.
>         (Asynchronous and non-stop modes): Document '-gdb-set mi-async'.
>         Mention that target-async is now deprecated.
>         (Maintenance Commands): Document maint set/show target-async.
>
> 2014-05-29  Pedro Alves  <palves@redhat.com>
>             Tom Tromey  <tromey@redhat.com>
>
>         * gdb.base/async-shell.exp: Don't enable target-async.
>         * gdb.base/async.exp
>         * gdb.base/corefile.exp (corefile_test_attach): Remove 'async'
>         parameter.  Adjust.
>         (top level): Don't test with "target-async".
>         * gdb.base/dprintf-non-stop.exp: Don't enable target-async.
>         * gdb.base/gdb-sigterm.exp: Don't test with "target-async".
>         * gdb.base/inferior-died.exp: Don't enable target-async.
>         * gdb.base/interrupt-noterm.exp: Likewise.
>         * gdb.mi/mi-async.exp: Use "mi-async" instead of "target-async".
>         * gdb.mi/mi-nonstop-exit.exp: Likewise.
>         * gdb.mi/mi-nonstop.exp: Likewise.
>         * gdb.mi/mi-ns-stale-regcache.exp: Likewise.
>         * gdb.mi/mi-nsintrall.exp: Likewise.
>         * gdb.mi/mi-nsmoribund.exp: Likewise.
>         * gdb.mi/mi-nsthrexec.exp: Likewise.
>         * gdb.mi/mi-watch-nonstop.exp: Likewise.
>         * gdb.multi/watchpoint-multi.exp: Adjust comment.
>         * gdb.python/py-evsignal.exp: Don't enable target-async.
>         * gdb.python/py-evthreads.exp: Likewise.
>         * gdb.python/py-prompt.exp: Likewise.
>         * gdb.reverse/break-precsave.exp: Don't test with "target-async".
>         * gdb.server/solib-list.exp: Don't enable target-async.
>         * gdb.threads/thread-specific-bp.exp: Likewise.
>         * lib/mi-support.exp: Adjust to use mi-async.

Hi.

I happened to notice a couple of comments that still need updating.

linux-nat.c:

/* target_is_async_p implementation.  */

static int
linux_nat_is_async_p (struct target_ops *ops)
{
  /* NOTE: palves 2008-03-21: We're only async when the user requests
     it explicitly with the "set target-async" command.
     Someday, linux will always be async.  */
  return target_async_permitted;
}

/* target_can_async_p implementation.  */

static int
linux_nat_can_async_p (struct target_ops *ops)
{
  /* NOTE: palves 2008-03-21: We're only async when the user requests
     it explicitly with the "set target-async" command.
     Someday, linux will always be async.  */
  return target_async_permitted;
}

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PUSHED] infcmd.c: Remove stale TODO
  2014-07-30 16:59                         ` Doug Evans
@ 2014-08-21 16:34                           ` Pedro Alves
  0 siblings, 0 replies; 42+ messages in thread
From: Pedro Alves @ 2014-08-21 16:34 UTC (permalink / raw)
  To: gdb-patches; +Cc: Doug Evans

This TODO has been stale for over 2 years.  In bd5635a1 (1991), we
already see the comment, when we only had a bare attach_command:

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 /*
  * TODO:
  * Should save/restore the tty state since it might be that the
  * program to be debugged was started on this tty and it wants
  * the tty in some state other than what we want.  If it's running
  * on another terminal or without a terminal, then saving and
  * restoring the tty state is a harmless no-op.
  * This only needs to be done if we are attaching to a process.
  */

 /*
  * attach_command --
  * takes a program started up outside of gdb and ``attaches'' to it.
  * This stops it cold in its tracks and allows us to start tracing it.
  * For this to work, we must be able to send the process a
  * signal and we must have the same effective uid as the program.
  */
 void
 attach_command (args, from_tty)
      char *args;
      int from_tty;
 {
   target_attach (args, from_tty);
 }
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Later in b5a3d2aa (1992) target_terminal_init, etc. calls are added to
attach_command, and in 7e97eb28 (1992) we see:

+      /* If we attached to the process, we might or might not be sharing
+        a terminal.  Avoid printing error msg if we are unable to set our
+        terminal's process group to his process group ID.  */
+      if (!attach_flag) {
+       OOPSY ("ioctl TIOCSPGRP");

Clearly the TODO has been stale for a long while.

I considered preserving the text elsewhere, but then thought the
comments in inflow.c already have all the necessary info.

gdb/ChangeLog:

	* infcmd.c (attach_command): Remove comment.
---
 gdb/ChangeLog |  4 ++++
 gdb/infcmd.c  | 10 ----------
 2 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fae78e5..bf7f618 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@
+2014-08-21  Pedro Alves  <palves@redhat.com>
+
+	* infcmd.c (attach_command): Remove comment.
+
 2014-08-21  Bin Cheng  <bin.cheng@arm.com>
 
 	* aarch64-linux-nat.c (dr_changed_t): Change the type from
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index bc42cea..b6aba04 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2365,16 +2365,6 @@ proceed_after_attach (int pid)
   do_cleanups (old_chain);
 }
 
-/*
- * TODO:
- * Should save/restore the tty state since it might be that the
- * program to be debugged was started on this tty and it wants
- * the tty in some state other than what we want.  If it's running
- * on another terminal or without a terminal, then saving and
- * restoring the tty state is a harmless no-op.
- * This only needs to be done if we are attaching to a process.
- */
-
 /* attach_command --
    takes a program started up outside of gdb and ``attaches'' to it.
    This stops it cold in its tracks and allows us to start debugging it.
-- 
1.9.3


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Regression: GDB stopped on run with attached process (PR 17347)  [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]]
  2014-07-09 17:09                   ` [pushed+7.8] " Pedro Alves
  2014-07-29 22:03                     ` Doug Evans
@ 2014-09-03  7:59                     ` Jan Kratochvil
  2014-09-03 20:11                       ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race Pedro Alves
  1 sibling, 1 reply; 42+ messages in thread
From: Jan Kratochvil @ 2014-09-03  7:59 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On Wed, 09 Jul 2014 19:09:29 +0200, Pedro Alves wrote:
> Here's what I pushed to both master and gdb-7.8-branch.

https://sourceware.org/bugzilla/show_bug.cgi?id=17347

sleep 1h&p=$!;sleep 0.1;gdb -batch sleep $p -ex r

PASS:
[2] 22970
0x0000003fdf8bc780 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:81
81      T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
/usr/bin/sleep: missing operand
Try '/usr/bin/sleep --help' for more information.
[Inferior 1 (process 23030) exited with code 01]
[2]+  Killed                  sleep 1h

FAIL:
[2]   Killed                  sleep 1h
[3]+  Stopped                 ./gdb/gdb -batch sleep $! -ex r

7180e04a36d812bbea2c280f2db33a7e8ce6b07b is the first bad commit
commit 7180e04a36d812bbea2c280f2db33a7e8ce6b07b
Author: Pedro Alves <palves@redhat.com>
Date:   Wed Jul 9 15:59:02 2014 +0100

    Fix "attach" command vs user input race

private Red Hat reference: https://bugzilla.redhat.com/show_bug.cgi?id=1136704

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression: GDB stopped on run with attached process (PR 17347)  [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race
  2014-09-03  7:59                     ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]] Jan Kratochvil
@ 2014-09-03 20:11                       ` Pedro Alves
  2014-09-07 19:28                         ` Jan Kratochvil
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-09-03 20:11 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/03/2014 08:58 AM, Jan Kratochvil wrote:

> https://sourceware.org/bugzilla/show_bug.cgi?id=17347

Thanks Jan.

Here's a fix, test included.  Comments?

Thanks,
Pedro Alves

--------------------------
[PATCH] gdb/17347 - Regression: GDB stopped on run with attached process

Doing:

  gdb --pid=PID -ex run

Results in GDB getting a SIGTTIN, and thus ending stopped.  That's
usually indicative of a missing target_terminal_ours call.

E.g., from the PR:

 $ sleep 1h & p=$!; sleep 0.1; gdb -batch sleep $p -ex run
 [1] 28263
 [1]   Killed                  sleep 1h

 [2]+  Stopped                 gdb -batch sleep $p -ex run

The workaround is doing:

 gdb -ex "attach $PID" -ex "run"

instead of

 gdb [-p] $PID -ex "run"

With the former, gdb waits for the attach command to complete before
moving on to the "run" command, because the interpreter is in sync
mode at this point, within execute_command.  But for the latter,
attach_command is called directly from captured_main, and thus misses
that waiting.  IOW, "run" is running before the attach continuation
has run, before the program stops and attach completes.  The broken
terminal settings are just one symptom of that.  Any command that
queries or requires input results in the same.

The fix is to wait in catch_command_errors (which is specific to
main.c nowadays), just like we wait in execute_command.

gdb/ChangeLog:
2014-09-03  Pedro Alves  <palves@redhat.com>

	PR gdb/17347
	* main.c: Include "infrun.h".
	(catch_command_errors, catch_command_errors_const): Wait for the
	foreground command to complete.
	* top.c (maybe_wait_sync_command_done): New function, factored out
	from ...
	(maybe_wait_sync_command_done): ... here.
	* top.h (maybe_wait_sync_command_done): New declaration.

gdb/testsuite/ChangeLog:
2014-09-03  Pedro Alves  <palves@redhat.com>

	PR gdb/17347
	* gdb.base/attach.exp (spawn_test_prog): New, factored out from
	...
	(do_attach_tests, do_call_attach_tests, do_command_attach_tests):
	... here.
	(gdb_spawn_with_cmdline_opts): New procedure.
	(test_command_line_attach_run): New procedure.
	(top level): Call it.
---
 gdb/main.c                        |   9 +++
 gdb/testsuite/gdb.base/attach.exp | 118 ++++++++++++++++++++++++++------------
 gdb/top.c                         |  26 +++++----
 gdb/top.h                         |   8 +++
 4 files changed, 114 insertions(+), 47 deletions(-)

diff --git a/gdb/main.c b/gdb/main.c
index 12f0146..756dd4f 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -45,6 +45,7 @@
 #include "filestuff.h"
 #include <signal.h>
 #include "event-top.h"
+#include "infrun.h"
 
 /* The selected interpreter.  This will be used as a set command
    variable, so it should always be malloc'ed - since
@@ -369,7 +370,11 @@ catch_command_errors (catch_command_errors_ftype *command,
 
   TRY_CATCH (e, mask)
     {
+      int was_sync = sync_execution;
+
       command (arg, from_tty);
+
+      maybe_wait_sync_command_done (was_sync);
     }
   return handle_command_errors (e);
 }
@@ -388,7 +393,11 @@ catch_command_errors_const (catch_command_errors_const_ftype *command,
 
   TRY_CATCH (e, mask)
     {
+      int was_sync = sync_execution;
+
       command (arg, from_tty);
+
+      maybe_wait_sync_command_done (was_sync);
     }
   return handle_command_errors (e);
 }
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index 9714c29..c94c127 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -58,6 +58,37 @@ if [get_compiler_info] {
     return -1
 }
 
+# Start the program running and then wait for a bit, to be sure that
+# it can be attached to.  Return the process's PID.
+
+proc spawn_test_prog { executable } {
+    set testpid [eval exec $executable &]
+    exec sleep 2
+    if { [istarget "*-*-cygwin*"] } {
+	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
+	# different due to the way fork/exec works.
+	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
+    }
+
+    return $testpid
+}
+
+# Spawn GDB with CMDLINE_FLAGS appended to the GDBFLAGS global.
+
+proc gdb_spawn_with_cmdline_opts { cmdline_flags } {
+    global GDBFLAGS
+
+    set saved_gdbflags $GDBFLAGS
+
+    append GDBFLAGS $cmdline_flags
+
+    set res [gdb_spawn]
+
+    set GDBFLAGS $saved_gdbflags
+
+    return $res
+}
+
 proc do_attach_tests {} {
     global gdb_prompt
     global binfile
@@ -70,13 +101,7 @@ proc do_attach_tests {} {
     # Start the program running and then wait for a bit, to be sure
     # that it can be attached to.
 
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_test_prog $binfile]
 
     # Verify that we cannot attach to nonsense.
 
@@ -279,16 +304,7 @@ proc do_attach_tests {} {
    
     remote_exec build "kill -9 ${testpid}"
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-   
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_test_prog $binfile]
 
     # Verify that we can attach to the process, and find its a.out
     # when we're cd'd to some directory that doesn't contain the
@@ -335,16 +351,7 @@ proc do_call_attach_tests {} {
     global gdb_prompt
     global binfile2
     
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-   
-    set testpid [eval exec $binfile2 &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_test_prog $binfile2]
 
     # Attach
    
@@ -397,16 +404,7 @@ proc do_command_attach_tests {} {
 	return 0
     }
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_test_prog $binfile]
 
     gdb_exit
     if $verbose>1 then {
@@ -429,6 +427,50 @@ proc do_command_attach_tests {} {
     remote_exec build "kill -9 ${testpid}"
 }
 
+# Test ' gdb --pid PID -ex "run" '.  GDB used to have a bug where
+# "run" would run before the attach finished - PR17347.
+
+proc test_command_line_attach_run {} {
+    global gdb_prompt
+    global binfile
+    global verbose
+    global GDB
+    global INTERNAL_GDBFLAGS
+
+    if ![isnative] then {
+	unsupported "commandline attach run test"
+	return 0
+    }
+
+    with_test_prefix "cmdline attach run" {
+	set testpid [spawn_test_prog $binfile]
+
+	set test "run to prompt"
+	gdb_exit
+	set res [gdb_spawn_with_cmdline_opts "--pid=$testpid -ex \"start\""]
+	if { $res != 0} {
+	    fail $test
+	    return $res
+	}
+	gdb_test_multiple "" $test {
+	    -re {Attaching to.*Start it from the beginning\? \(y or n\) } {
+		pass $test
+	    }
+	}
+
+	send_gdb "y\n"
+
+	set test "run to main"
+	gdb_test_multiple "" $test {
+	    -re "Temporary breakpoint .* main .*$gdb_prompt $" {
+		pass $test
+	    }
+	}
+
+	# Get rid of the process
+	remote_exec build "kill -9 ${testpid}"
+    }
+}
 
 # Start with a fresh gdb
 
@@ -453,4 +495,6 @@ do_call_attach_tests
 
 do_command_attach_tests
 
+test_command_line_attach_run
+
 return 0
diff --git a/gdb/top.c b/gdb/top.c
index fc2b84d..ba71f8f 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -373,6 +373,21 @@ check_frame_language_change (void)
     }
 }
 
+void
+maybe_wait_sync_command_done (int was_sync)
+{
+  /* If the interpreter is in sync mode (we're running a user
+     command's list, running command hooks or similars), and we
+     just ran a synchronous command that started the target, wait
+     for that command to end.  */
+  if (!interpreter_async && !was_sync && sync_execution)
+    {
+      while (gdb_do_one_event () >= 0)
+	if (!sync_execution)
+	  break;
+    }
+}
+
 /* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
@@ -459,16 +474,7 @@ execute_command (char *p, int from_tty)
       else
 	cmd_func (c, arg, from_tty);
 
-      /* If the interpreter is in sync mode (we're running a user
-	 command's list, running command hooks or similars), and we
-	 just ran a synchronous command that started the target, wait
-	 for that command to end.  */
-      if (!interpreter_async && !was_sync && sync_execution)
-	{
-	  while (gdb_do_one_event () >= 0)
-	    if (!sync_execution)
-	      break;
-	}
+      maybe_wait_sync_command_done (was_sync);
 
       /* If this command has been post-hooked, run the hook last.  */
       execute_cmd_post_hook (c);
diff --git a/gdb/top.h b/gdb/top.h
index c322c33..94f6c48 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -42,6 +42,14 @@ extern void quit_command (char *, int);
 extern void quit_cover (void);
 extern void execute_command (char *, int);
 
+/* If the interpreter is in sync mode (we're running a user command's
+   list, running command hooks or similars), and we just ran a
+   synchronous command that started the target, wait for that command
+   to end.  WAS_SYNC indicates whether sync_execution was set before
+   the command was run.  */
+
+extern void maybe_wait_sync_command_done (int was_sync);
+
 extern void check_frame_language_change (void);
 
 /* Prepare for execution of a command.
-- 
1.9.3

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race
  2014-09-03 20:11                       ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race Pedro Alves
@ 2014-09-07 19:28                         ` Jan Kratochvil
  2014-09-08 16:19                           ` [PATCH 1/2] testsuite: refactor spawn and wait for attach (was: Re: Regression: GDB stopped on run with attached process) Pedro Alves
  2014-09-08 16:27                           ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race Pedro Alves
  0 siblings, 2 replies; 42+ messages in thread
From: Jan Kratochvil @ 2014-09-07 19:28 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Doug Evans, Mark Wielaard, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 5673 bytes --]

On Wed, 03 Sep 2014 22:11:03 +0200, Pedro Alves wrote:
> On 09/03/2014 08:58 AM, Jan Kratochvil wrote:
> 
> > https://sourceware.org/bugzilla/show_bug.cgi?id=17347
> 
> Thanks Jan.
> 
> Here's a fix, test included.  Comments?

In the testsuite run from the Fedora rpm packaging I get:

GNU gdb (GDB) Fedora 7.8-21.fc21^M
Copyright (C) 2014 Free Software Foundation, Inc.^M
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>^M
This is free software: you are free to change and redistribute it.^M
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"^M
and "show warranty" for details.^M
This GDB was configured as "i686-redhat-linux-gnu".^M
Type "show configuration" for configuration details.^M
For bug reporting instructions, please see:^M
<http://www.gnu.org/software/gdb/bugs/>.^M
Find the GDB manual and other documentation resources online at:^M
<http://www.gnu.org/software/gdb/documentation/>.^M
For help, type "help".^M
Type "apropos word" to search for commands related to "word".^M
Attaching to process 27028^M
Reading symbols from /unsafebuild-i686-redhat-linux-gnu/gdb/testsuite.unix.-m32/outputs/gdb.base/attach/attach...done.^M
Reading symbols from /lib/libm.so.6...Reading symbols from /usr/lib/debug/usr/lib/libm-2.19.90.so.debug...done.^M
done.^M
Loaded symbols for /lib/libm.so.6^M
Reading symbols from /lib/libc.so.6...Reading symbols from /usr/lib/debug/usr/lib/libc-2.19.90.so.debug...done.^M
done.^M
Loaded symbols for /lib/libc.so.6^M
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug/usr/lib/ld-2.19.90.so.debug...done.^M
done.^M
Loaded symbols for /lib/ld-linux.so.2^M
main ()^M
    at gdb/testsuite/gdb.base/attach.c:15^M
15       while (! should_exit)^M
The program being debugged has been started already.^M
Start it from the beginning? (y or n) PASS: gdb.base/attach.exp: cmdline attach run: run to prompt
y^M
^M
Temporary breakpoint 1 at 0x8048481: file gdb/testsuite/gdb.base/attach.c, line 13.^M
Starting program: /unsafe/home/jkratoch/hammock/20140907fedorarel21-f21/fedora-2---Type <return> to continue, or q <return> to quit---ERROR: Window too small.
UNRESOLVED: gdb.base/attach.exp: cmdline attach run: run to main


While I do not fully understand why that happens in every run of that Fedora
testsuite while it never happens during my reproducibility attempts by hand
I find it understandable and the Fedora testsuite issues does get fixed by the
attached patch.


> --- a/gdb/testsuite/gdb.base/attach.exp
> +++ b/gdb/testsuite/gdb.base/attach.exp
> @@ -58,6 +58,37 @@ if [get_compiler_info] {
>      return -1
>  }
>  
> +# Start the program running and then wait for a bit, to be sure that
> +# it can be attached to.  Return the process's PID.
> +
> +proc spawn_test_prog { executable } {
> +    set testpid [eval exec $executable &]
> +    exec sleep 2

Unrelated to this patch - this patch only moved the code.  Also the code move
could be a separate patch:

I do not see why the testsuite commonly uses "exec sleep" while it also uses
"sleep" itself which also works fine.


> +    if { [istarget "*-*-cygwin*"] } {
> +	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
> +	# different due to the way fork/exec works.
> +	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
> +    }
> +
> +    return $testpid
> +}
[...]
> @@ -429,6 +427,50 @@ proc do_command_attach_tests {} {
>      remote_exec build "kill -9 ${testpid}"
>  }
>  
> +# Test ' gdb --pid PID -ex "run" '.  GDB used to have a bug where
> +# "run" would run before the attach finished - PR17347.
> +
> +proc test_command_line_attach_run {} {
> +    global gdb_prompt
> +    global binfile

> +    global verbose
> +    global GDB
> +    global INTERNAL_GDBFLAGS

These 3 lines are unused.


> +
> +    if ![isnative] then {
> +	unsupported "commandline attach run test"
> +	return 0
> +    }
> +
> +    with_test_prefix "cmdline attach run" {
> +	set testpid [spawn_test_prog $binfile]
> +
> +	set test "run to prompt"
> +	gdb_exit
> +	set res [gdb_spawn_with_cmdline_opts "--pid=$testpid -ex \"start\""]

Here see the attachment.


> +	if { $res != 0} {
> +	    fail $test
> +	    return $res
> +	}
> +	gdb_test_multiple "" $test {
> +	    -re {Attaching to.*Start it from the beginning\? \(y or n\) } {
> +		pass $test
> +	    }
> +	}
> +
> +	send_gdb "y\n"
> +
> +	set test "run to main"
> +	gdb_test_multiple "" $test {
> +	    -re "Temporary breakpoint .* main .*$gdb_prompt $" {
> +		pass $test
> +	    }
> +	}
> +
> +	# Get rid of the process
> +	remote_exec build "kill -9 ${testpid}"
> +    }
> +}
>  
>  # Start with a fresh gdb
>  
> @@ -453,4 +495,6 @@ do_call_attach_tests
>  
>  do_command_attach_tests
>  
> +test_command_line_attach_run
> +
>  return 0
> diff --git a/gdb/top.c b/gdb/top.c
> index fc2b84d..ba71f8f 100644
> --- a/gdb/top.c
> +++ b/gdb/top.c
> @@ -373,6 +373,21 @@ check_frame_language_change (void)
>      }
>  }
>  

Missing:
/* See top.h.  */

Unless that rule from me has been abandoned.


> +void
> +maybe_wait_sync_command_done (int was_sync)
> +{
> +  /* If the interpreter is in sync mode (we're running a user
> +     command's list, running command hooks or similars), and we
> +     just ran a synchronous command that started the target, wait
> +     for that command to end.  */
> +  if (!interpreter_async && !was_sync && sync_execution)
> +    {
> +      while (gdb_do_one_event () >= 0)
> +	if (!sync_execution)
> +	  break;
> +    }
> +}
> +
>  /* Execute the line P as a command, in the current user context.
>     Pass FROM_TTY as second argument to the defining function.  */
>  


Thanks,
Jan

[-- Attachment #2: 1 --]
[-- Type: text/plain, Size: 538 bytes --]

diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index c94c127..6e566a3 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -447,7 +444,8 @@ proc test_command_line_attach_run {} {
 
 	set test "run to prompt"
 	gdb_exit
-	set res [gdb_spawn_with_cmdline_opts "--pid=$testpid -ex \"start\""]
+	set res [gdb_spawn_with_cmdline_opts \
+		 "-iex set\\ height\\ 0 -iex set\\ width\\ 0 --pid=$testpid -ex \"start\""]
 	if { $res != 0} {
 	    fail $test
 	    return $res

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH 1/2] testsuite: refactor spawn and wait for attach (was: Re: Regression: GDB stopped on run with attached process)
  2014-09-07 19:28                         ` Jan Kratochvil
@ 2014-09-08 16:19                           ` Pedro Alves
  2014-09-09 17:29                             ` Jan Kratochvil
  2014-09-08 16:27                           ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race Pedro Alves
  1 sibling, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-09-08 16:19 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/07/2014 08:28 PM, Jan Kratochvil wrote:
>> > --- a/gdb/testsuite/gdb.base/attach.exp
>> > +++ b/gdb/testsuite/gdb.base/attach.exp
>> > @@ -58,6 +58,37 @@ if [get_compiler_info] {
>> >      return -1
>> >  }
>> >  
>> > +# Start the program running and then wait for a bit, to be sure that
>> > +# it can be attached to.  Return the process's PID.
>> > +
>> > +proc spawn_test_prog { executable } {
>> > +    set testpid [eval exec $executable &]
>> > +    exec sleep 2
> Unrelated to this patch - this patch only moved the code.  Also the code move
> could be a separate patch:

Indeed it could.  I've done that now.  See below.  There were actually more
places around the testsuite that have that same code.  Let me know how it looks
to you.

> I do not see why the testsuite commonly uses "exec sleep" while it also uses
> "sleep" itself which also works fine.

No idea, though I'd guess that there's really no good reason.

------ 8< -------
[PATCH 1/2] testsuite: refactor spawn and wait for attach

Several places in the testsuite have a copy of a snippet of code that
spawns a test program, waits a bit, and then does some PID munging for
Cygwin.  This is in order to have GDB attach to the spawned program.

This refactors all that to a common procedure.

(multi-attach.exp wants to spawn multiple processes, so this makes the
new procedure's interface work with lists.)

Tested on x86_64 Fedora 20.

gdb/testsuite/ChangeLog:
2014-09-08  Pedro Alves  <palves@redhat.com>

	* lib/gdb.exp (spawn_wait_for_attach): New procedure.
	* gdb.base/attach.exp (do_attach_tests, do_call_attach_tests)
	(do_command_attach_tests): Use spawn_wait_for_attach.
	* gdb.base/solib-overlap.exp: Likewise.
	* gdb.multi/multi-attach.exp: Likewise.
	* gdb.python/py-prompt.exp: Likewise.
	* gdb.python/py-sync-interp.exp: Likewise.
	* gdb.server/ext-attach.exp: Likewise.
---
 gdb/testsuite/gdb.base/attach.exp           | 41 +++--------------------------
 gdb/testsuite/gdb.base/solib-overlap.exp    | 11 +-------
 gdb/testsuite/gdb.multi/multi-attach.exp    | 13 +++------
 gdb/testsuite/gdb.python/py-prompt.exp      | 10 +------
 gdb/testsuite/gdb.python/py-sync-interp.exp | 10 +------
 gdb/testsuite/gdb.server/ext-attach.exp     | 10 +------
 gdb/testsuite/lib/gdb.exp                   | 25 ++++++++++++++++++
 7 files changed, 37 insertions(+), 83 deletions(-)

diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index 9714c29..a20c51a 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -70,13 +70,7 @@ proc do_attach_tests {} {
     # Start the program running and then wait for a bit, to be sure
     # that it can be attached to.
 
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     # Verify that we cannot attach to nonsense.
 
@@ -279,16 +273,7 @@ proc do_attach_tests {} {
    
     remote_exec build "kill -9 ${testpid}"
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-   
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     # Verify that we can attach to the process, and find its a.out
     # when we're cd'd to some directory that doesn't contain the
@@ -335,16 +320,7 @@ proc do_call_attach_tests {} {
     global gdb_prompt
     global binfile2
     
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-   
-    set testpid [eval exec $binfile2 &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile2]
 
     # Attach
    
@@ -397,16 +373,7 @@ proc do_command_attach_tests {} {
 	return 0
     }
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     gdb_exit
     if $verbose>1 then {
diff --git a/gdb/testsuite/gdb.base/solib-overlap.exp b/gdb/testsuite/gdb.base/solib-overlap.exp
index 68731be..7486b07 100644
--- a/gdb/testsuite/gdb.base/solib-overlap.exp
+++ b/gdb/testsuite/gdb.base/solib-overlap.exp
@@ -82,16 +82,7 @@ foreach prelink_lib1 {0x40000000 0x50000000} { with_test_prefix "$prelink_lib1"
 	return -1
     }
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-
-    set testpid [eval exec $binfile &]
-    sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     remote_exec build "mv -f ${binfile_lib1} ${binfile_lib1}-running"
     remote_exec build "mv -f ${binfile_lib2} ${binfile_lib2}-running"
diff --git a/gdb/testsuite/gdb.multi/multi-attach.exp b/gdb/testsuite/gdb.multi/multi-attach.exp
index e933520..eaff2c9 100644
--- a/gdb/testsuite/gdb.multi/multi-attach.exp
+++ b/gdb/testsuite/gdb.multi/multi-attach.exp
@@ -30,15 +30,10 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug additiona
 
 # Start the programs running and then wait for a bit, to be sure that
 # they can be attached to.
-set testpid1 [eval exec $binfile &]
-set testpid2 [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid{1,2} are the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid1 [ exec ps -e | gawk "{ if (\$1 == $testpid1) print \$4; }" ]
-    set testpid2 [ exec ps -e | gawk "{ if (\$1 == $testpid2) print \$4; }" ]
-}
+
+set pid_list [spawn_wait_for_attach [list $binfile $binfile]]
+set testpid1 [lindex $pid_list 0]
+set testpid2 [lindex $pid_list 1]
 
 gdb_test "attach $testpid1" \
     "Attaching to program: .*, process $testpid1.*(in|at).*" \
diff --git a/gdb/testsuite/gdb.python/py-prompt.exp b/gdb/testsuite/gdb.python/py-prompt.exp
index ebe4cb6..1c53c03 100644
--- a/gdb/testsuite/gdb.python/py-prompt.exp
+++ b/gdb/testsuite/gdb.python/py-prompt.exp
@@ -80,15 +80,7 @@ gdb_test "python print (\"'\" + str(p\[0\]) + \"'\")" "'$gdb_prompt_fail '" \
 	 "prompt_hook argument is default prompt. 2"
 gdb_exit
 
-# Start the program running and then wait for a bit, to be sure
-# that it can be attached to.
-set testpid [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-}
+set testpid [spawn_wait_for_attach $binfile]
 
 set GDBFLAGS [concat $tmp_gdbflags " -ex \"set pagination off\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
diff --git a/gdb/testsuite/gdb.python/py-sync-interp.exp b/gdb/testsuite/gdb.python/py-sync-interp.exp
index b9b86bc..d62f966 100644
--- a/gdb/testsuite/gdb.python/py-sync-interp.exp
+++ b/gdb/testsuite/gdb.python/py-sync-interp.exp
@@ -41,15 +41,7 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
     return -1
 }
 
-# Start the program running and then wait for a bit, to be sure
-# that it can be attached to.
-set testpid [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-}
+set testpid [spawn_wait_for_attach $binfile]
 
 # Test command 'where' is executed when command 'attach' is done, otherwise
 # function 'sleep' may not show up in backtrace.
diff --git a/gdb/testsuite/gdb.server/ext-attach.exp b/gdb/testsuite/gdb.server/ext-attach.exp
index 5f7bac4..9baeeb7 100644
--- a/gdb/testsuite/gdb.server/ext-attach.exp
+++ b/gdb/testsuite/gdb.server/ext-attach.exp
@@ -44,15 +44,7 @@ gdbserver_start_extended
 
 gdb_test_no_output "set remote exec-file $target_exec" "set remote exec-file"
 
-# Start the program running and then wait for a bit, to be sure
-# that it can be attached to.
-set testpid [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-}
+set testpid [spawn_wait_for_attach $binfile]
 
 gdb_test "attach $testpid" \
     "Attaching to program: .*, process $testpid.*(in|at).*" \
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 1019ecd..ecf942e 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -3347,6 +3347,31 @@ proc gdb_exit { } {
     catch default_gdb_exit
 }
 
+# Start a set of programs running and then wait for a bit, to be sure
+# that they can be attached to.  Return a list of the processes' PIDs.
+
+proc spawn_wait_for_attach { executable_list } {
+    set pid_list {}
+
+    foreach {executable} $executable_list {
+	lappend pid_list [eval exec $executable &]
+    }
+
+    sleep 2
+
+    if { [istarget "*-*-cygwin*"] } {
+	for {set i 0} {$i < [llength $pid_list]} {incr i} {
+	    # testpid is the Cygwin PID, GDB uses the Windows PID,
+	    # which might be different due to the way fork/exec works.
+	    set testpid [lindex $pid_list $i]
+	    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
+	    lreplace $i $i $testpid
+	}
+    }
+
+    return $pid_list
+}
+
 #
 # gdb_load_cmd -- load a file into the debugger.
 #		  ARGS - additional args to load command.
-- 
1.9.3


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race
  2014-09-07 19:28                         ` Jan Kratochvil
  2014-09-08 16:19                           ` [PATCH 1/2] testsuite: refactor spawn and wait for attach (was: Re: Regression: GDB stopped on run with attached process) Pedro Alves
@ 2014-09-08 16:27                           ` Pedro Alves
  2014-09-09 18:25                             ` Jan Kratochvil
  1 sibling, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-09-08 16:27 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/07/2014 08:28 PM, Jan Kratochvil wrote:

> Temporary breakpoint 1 at 0x8048481: file gdb/testsuite/gdb.base/attach.c, line 13.^M
> Starting program: /unsafe/home/jkratoch/hammock/20140907fedorarel21-f21/fedora-2---Type <return> to continue, or q <return> to quit---ERROR: Window too small.
> UNRESOLVED: gdb.base/attach.exp: cmdline attach run: run to main

Good catch.  I see that if one runs the test with a short enough terminal,
do_command_attach_tests fails as well.  I'm leaving that for a
separate patch.

>> +proc test_command_line_attach_run {} {
>> +    global gdb_prompt
>> +    global binfile
> 
>> +    global verbose
>> +    global GDB
>> +    global INTERNAL_GDBFLAGS
> 
> These 3 lines are unused.

Thanks, removed.


>> +	set test "run to prompt"
>> +	gdb_exit
>> +	set res [gdb_spawn_with_cmdline_opts "--pid=$testpid -ex \"start\""]
> 
> Here see the attachment.

Thanks for this.


> Missing:
> /* See top.h.  */
> 
> Unless that rule from me has been abandoned.

Added.

Here's the updated patch.  WDYT?

---------- 8< ----------
Subject: [PATCH 2/2] gdb/17347 - Regression: GDB stopped on run with attached
 process

Doing:

  gdb --pid=PID -ex run

Results in GDB getting a SIGTTIN, and thus ending stopped.  That's
usually indicative of a missing target_terminal_ours call.

E.g., from the PR:

 $ sleep 1h & p=$!; sleep 0.1; gdb -batch sleep $p -ex run
 [1] 28263
 [1]   Killed                  sleep 1h

 [2]+  Stopped                 gdb -batch sleep $p -ex run

The workaround is doing:

 gdb -ex "attach $PID" -ex "run"

instead of

 gdb [-p] $PID -ex "run"

With the former, gdb waits for the attach command to complete before
moving on to the "run" command, because the interpreter is in sync
mode at this point, within execute_command.  But for the latter,
attach_command is called directly from captured_main, and thus misses
that waiting.  IOW, "run" is running before the attach continuation
has run, before the program stops and attach completes.  The broken
terminal settings are just one symptom of that.  Any command that
queries or requires input results in the same.

The fix is to wait in catch_command_errors (which is specific to
main.c nowadays), just like we wait in execute_command.

gdb/ChangeLog:
2014-09-08  Pedro Alves  <palves@redhat.com>

	PR gdb/17347
	* main.c: Include "infrun.h".
	(catch_command_errors, catch_command_errors_const): Wait for the
	foreground command to complete.
	* top.c (maybe_wait_sync_command_done): New function, factored out
	from ...
	(maybe_wait_sync_command_done): ... here.
	* top.h (maybe_wait_sync_command_done): New declaration.

gdb/testsuite/ChangeLog:
2014-09-08  Pedro Alves  <palves@redhat.com>

	PR gdb/17347
	* lib/gdb.exp (gdb_spawn_with_cmdline_opts): New procedure.
	* gdb.base/attach.exp (test_command_line_attach_run): New
	procedure.
	(top level): Call it.
---
 gdb/main.c                        |  9 ++++++++
 gdb/testsuite/gdb.base/attach.exp | 45 +++++++++++++++++++++++++++++++++++++++
 gdb/testsuite/lib/gdb.exp         | 16 ++++++++++++++
 gdb/top.c                         | 28 +++++++++++++++---------
 gdb/top.h                         |  8 +++++++
 5 files changed, 96 insertions(+), 10 deletions(-)

diff --git a/gdb/main.c b/gdb/main.c
index 12f0146..756dd4f 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -45,6 +45,7 @@
 #include "filestuff.h"
 #include <signal.h>
 #include "event-top.h"
+#include "infrun.h"
 
 /* The selected interpreter.  This will be used as a set command
    variable, so it should always be malloc'ed - since
@@ -369,7 +370,11 @@ catch_command_errors (catch_command_errors_ftype *command,
 
   TRY_CATCH (e, mask)
     {
+      int was_sync = sync_execution;
+
       command (arg, from_tty);
+
+      maybe_wait_sync_command_done (was_sync);
     }
   return handle_command_errors (e);
 }
@@ -388,7 +393,11 @@ catch_command_errors_const (catch_command_errors_const_ftype *command,
 
   TRY_CATCH (e, mask)
     {
+      int was_sync = sync_execution;
+
       command (arg, from_tty);
+
+      maybe_wait_sync_command_done (was_sync);
     }
   return handle_command_errors (e);
 }
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index a20c51a..6340496 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -396,6 +396,49 @@ proc do_command_attach_tests {} {
     remote_exec build "kill -9 ${testpid}"
 }
 
+# Test ' gdb --pid PID -ex "run" '.  GDB used to have a bug where
+# "run" would run before the attach finished - PR17347.
+
+proc test_command_line_attach_run {} {
+    global gdb_prompt
+    global binfile
+
+    if ![isnative] then {
+	unsupported "commandline attach run test"
+	return 0
+    }
+
+    with_test_prefix "cmdline attach run" {
+	set testpid [spawn_wait_for_attach $binfile]
+
+	set test "run to prompt"
+	gdb_exit
+
+	set res [gdb_spawn_with_cmdline_opts \
+		     "-iex \"set height 0\" -iex \"set width 0\" --pid=$testpid -ex \"start\""]
+	if { $res != 0} {
+	    fail $test
+	    return $res
+	}
+	gdb_test_multiple "" $test {
+	    -re {Attaching to.*Start it from the beginning\? \(y or n\) } {
+		pass $test
+	    }
+	}
+
+	send_gdb "y\n"
+
+	set test "run to main"
+	gdb_test_multiple "" $test {
+	    -re "Temporary breakpoint .* main .*$gdb_prompt $" {
+		pass $test
+	    }
+	}
+
+	# Get rid of the process
+	remote_exec build "kill -9 ${testpid}"
+    }
+}
 
 # Start with a fresh gdb
 
@@ -420,4 +463,6 @@ do_call_attach_tests
 
 do_command_attach_tests
 
+test_command_line_attach_run
+
 return 0
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index ecf942e..c54ba4b 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -3334,6 +3334,22 @@ proc gdb_spawn { } {
     default_gdb_spawn
 }
 
+# Spawn GDB with CMDLINE_FLAGS appended to the GDBFLAGS global.
+
+proc gdb_spawn_with_cmdline_opts { cmdline_flags } {
+    global GDBFLAGS
+
+    set saved_gdbflags $GDBFLAGS
+
+    append GDBFLAGS $cmdline_flags
+
+    set res [gdb_spawn]
+
+    set GDBFLAGS $saved_gdbflags
+
+    return $res
+}
+
 # Start gdb running, wait for prompt, and disable the pagers.
 
 # Overridable function -- you can override this function in your
diff --git a/gdb/top.c b/gdb/top.c
index fc2b84d..d6696cd 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -373,6 +373,23 @@ check_frame_language_change (void)
     }
 }
 
+/* See top.h.  */
+
+void
+maybe_wait_sync_command_done (int was_sync)
+{
+  /* If the interpreter is in sync mode (we're running a user
+     command's list, running command hooks or similars), and we
+     just ran a synchronous command that started the target, wait
+     for that command to end.  */
+  if (!interpreter_async && !was_sync && sync_execution)
+    {
+      while (gdb_do_one_event () >= 0)
+	if (!sync_execution)
+	  break;
+    }
+}
+
 /* Execute the line P as a command, in the current user context.
    Pass FROM_TTY as second argument to the defining function.  */
 
@@ -459,16 +476,7 @@ execute_command (char *p, int from_tty)
       else
 	cmd_func (c, arg, from_tty);
 
-      /* If the interpreter is in sync mode (we're running a user
-	 command's list, running command hooks or similars), and we
-	 just ran a synchronous command that started the target, wait
-	 for that command to end.  */
-      if (!interpreter_async && !was_sync && sync_execution)
-	{
-	  while (gdb_do_one_event () >= 0)
-	    if (!sync_execution)
-	      break;
-	}
+      maybe_wait_sync_command_done (was_sync);
 
       /* If this command has been post-hooked, run the hook last.  */
       execute_cmd_post_hook (c);
diff --git a/gdb/top.h b/gdb/top.h
index c322c33..94f6c48 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -42,6 +42,14 @@ extern void quit_command (char *, int);
 extern void quit_cover (void);
 extern void execute_command (char *, int);
 
+/* If the interpreter is in sync mode (we're running a user command's
+   list, running command hooks or similars), and we just ran a
+   synchronous command that started the target, wait for that command
+   to end.  WAS_SYNC indicates whether sync_execution was set before
+   the command was run.  */
+
+extern void maybe_wait_sync_command_done (int was_sync);
+
 extern void check_frame_language_change (void);
 
 /* Prepare for execution of a command.
-- 
1.9.3


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 1/2] testsuite: refactor spawn and wait for attach (was: Re: Regression: GDB stopped on run with attached process)
  2014-09-08 16:19                           ` [PATCH 1/2] testsuite: refactor spawn and wait for attach (was: Re: Regression: GDB stopped on run with attached process) Pedro Alves
@ 2014-09-09 17:29                             ` Jan Kratochvil
  2014-09-09 17:35                               ` [PATCH 1/2] testsuite: refactor spawn and wait for attach Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Kratochvil @ 2014-09-09 17:29 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On Mon, 08 Sep 2014 18:19:17 +0200, Pedro Alves wrote:
> Indeed it could.  I've done that now.  See below.  There were actually more
> places around the testsuite that have that same code.  Let me know how it looks
> to you.

As long as it has been tested on *-*-cygwin* I do not see anything wrong
there.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 1/2] testsuite: refactor spawn and wait for attach
  2014-09-09 17:29                             ` Jan Kratochvil
@ 2014-09-09 17:35                               ` Pedro Alves
  2014-09-10 21:25                                 ` Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-09-09 17:35 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/09/2014 06:29 PM, Jan Kratochvil wrote:
> On Mon, 08 Sep 2014 18:19:17 +0200, Pedro Alves wrote:
>> Indeed it could.  I've done that now.  See below.  There were actually more
>> places around the testsuite that have that same code.  Let me know how it looks
>> to you.
> 
> As long as it has been tested on *-*-cygwin* I do not see anything wrong
> there.

It hasn't.  I wonder if someone can help with this?

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race
  2014-09-08 16:27                           ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race Pedro Alves
@ 2014-09-09 18:25                             ` Jan Kratochvil
  2014-09-11 12:36                               ` Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Kratochvil @ 2014-09-09 18:25 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On Mon, 08 Sep 2014 18:26:55 +0200, Pedro Alves wrote:
> Here's the updated patch.  WDYT?

Yes, fine with that.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 1/2] testsuite: refactor spawn and wait for attach
  2014-09-09 17:35                               ` [PATCH 1/2] testsuite: refactor spawn and wait for attach Pedro Alves
@ 2014-09-10 21:25                                 ` Pedro Alves
  2014-09-11 12:34                                   ` Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-09-10 21:25 UTC (permalink / raw)
  To: Pedro Alves, Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/09/2014 06:35 PM, Pedro Alves wrote:
> On 09/09/2014 06:29 PM, Jan Kratochvil wrote:
>> On Mon, 08 Sep 2014 18:19:17 +0200, Pedro Alves wrote:
>>> Indeed it could.  I've done that now.  See below.  There were actually more
>>> places around the testsuite that have that same code.  Let me know how it looks
>>> to you.
>>
>> As long as it has been tested on *-*-cygwin* I do not see anything wrong
>> there.
> 
> It hasn't.  I wonder if someone can help with this?

FYI, Keith was kind enough to run testing and sent me the logs,
though I haven't analyzed them yet.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH 1/2] testsuite: refactor spawn and wait for attach
  2014-09-10 21:25                                 ` Pedro Alves
@ 2014-09-11 12:34                                   ` Pedro Alves
  0 siblings, 0 replies; 42+ messages in thread
From: Pedro Alves @ 2014-09-11 12:34 UTC (permalink / raw)
  To: Pedro Alves, Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/10/2014 10:25 PM, Pedro Alves wrote:
> On 09/09/2014 06:35 PM, Pedro Alves wrote:
>> On 09/09/2014 06:29 PM, Jan Kratochvil wrote:
>>> On Mon, 08 Sep 2014 18:19:17 +0200, Pedro Alves wrote:
>>>> Indeed it could.  I've done that now.  See below.  There were actually more
>>>> places around the testsuite that have that same code.  Let me know how it looks
>>>> to you.
>>>
>>> As long as it has been tested on *-*-cygwin* I do not see anything wrong
>>> there.
>>
>> It hasn't.  I wonder if someone can help with this?
> 
> FYI, Keith was kind enough to run testing and sent me the logs,
> though I haven't analyzed them yet.

There was a silly bug, causing new Cygwin fails. 
lreplace was being misused.  This fixed it:

 +++ w/gdb/testsuite/lib/gdb.exp
 @@ -3381,7 +3381,7 @@ proc spawn_wait_for_attach { executable_list } {
             # which might be different due to the way fork/exec works.
             set testpid [lindex $pid_list $i]
             set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
 -           lreplace $i $i $testpid
 +           set pid_list [lreplace $pid_list $i $i $testpid]
         }
      }

I borrowed the wife's laptop and managed to test the fix
on Cygwin myself (boy is that slow...).

Here's what I pushed to both master and 7.8.

----
From 7ec5670becb3f978f4d2f4df252ad0cbf805e37a Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Thu, 11 Sep 2014 13:14:47 +0100
Subject: [PATCH] testsuite: refactor spawn and wait for attach

Several places in the testsuite have a copy of a snippet of code that
spawns a test program, waits a bit, and then does some PID munging for
Cygwin.  This is in order to have GDB attach to the spawned program.

This refactors all that to a common procedure.

(multi-attach.exp wants to spawn multiple processes, so this makes the
new procedure's interface work with lists.)

Tested on x86_64 Fedora 20.

gdb/testsuite/ChangeLog:
2014-09-11  Pedro Alves  <palves@redhat.com>

	* lib/gdb.exp (spawn_wait_for_attach): New procedure.
	* gdb.base/attach.exp (do_attach_tests, do_call_attach_tests)
	(do_command_attach_tests): Use spawn_wait_for_attach.
	* gdb.base/solib-overlap.exp: Likewise.
	* gdb.multi/multi-attach.exp: Likewise.
	* gdb.python/py-prompt.exp: Likewise.
	* gdb.python/py-sync-interp.exp: Likewise.
	* gdb.server/ext-attach.exp: Likewise.
---
 gdb/testsuite/ChangeLog                     | 11 ++++++++
 gdb/testsuite/gdb.base/attach.exp           | 41 +++--------------------------
 gdb/testsuite/gdb.base/solib-overlap.exp    | 11 +-------
 gdb/testsuite/gdb.multi/multi-attach.exp    | 13 +++------
 gdb/testsuite/gdb.python/py-prompt.exp      | 10 +------
 gdb/testsuite/gdb.python/py-sync-interp.exp | 10 +------
 gdb/testsuite/gdb.server/ext-attach.exp     | 10 +------
 gdb/testsuite/lib/gdb.exp                   | 25 ++++++++++++++++++
 8 files changed, 48 insertions(+), 83 deletions(-)

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index f85f9b5..a388194 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2014-09-11  Pedro Alves  <palves@redhat.com>
+
+	* lib/gdb.exp (spawn_wait_for_attach): New procedure.
+	* gdb.base/attach.exp (do_attach_tests, do_call_attach_tests)
+	(do_command_attach_tests): Use spawn_wait_for_attach.
+	* gdb.base/solib-overlap.exp: Likewise.
+	* gdb.multi/multi-attach.exp: Likewise.
+	* gdb.python/py-prompt.exp: Likewise.
+	* gdb.python/py-sync-interp.exp: Likewise.
+	* gdb.server/ext-attach.exp: Likewise.
+
 2014-09-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	PR python/17355
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index 9714c29..a20c51a 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -70,13 +70,7 @@ proc do_attach_tests {} {
     # Start the program running and then wait for a bit, to be sure
     # that it can be attached to.
 
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     # Verify that we cannot attach to nonsense.
 
@@ -279,16 +273,7 @@ proc do_attach_tests {} {
    
     remote_exec build "kill -9 ${testpid}"
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-   
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     # Verify that we can attach to the process, and find its a.out
     # when we're cd'd to some directory that doesn't contain the
@@ -335,16 +320,7 @@ proc do_call_attach_tests {} {
     global gdb_prompt
     global binfile2
     
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-   
-    set testpid [eval exec $binfile2 &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile2]
 
     # Attach
    
@@ -397,16 +373,7 @@ proc do_command_attach_tests {} {
 	return 0
     }
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-
-    set testpid [eval exec $binfile &]
-    exec sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     gdb_exit
     if $verbose>1 then {
diff --git a/gdb/testsuite/gdb.base/solib-overlap.exp b/gdb/testsuite/gdb.base/solib-overlap.exp
index 68731be..7486b07 100644
--- a/gdb/testsuite/gdb.base/solib-overlap.exp
+++ b/gdb/testsuite/gdb.base/solib-overlap.exp
@@ -82,16 +82,7 @@ foreach prelink_lib1 {0x40000000 0x50000000} { with_test_prefix "$prelink_lib1"
 	return -1
     }
 
-    # Start the program running and then wait for a bit, to be sure
-    # that it can be attached to.
-
-    set testpid [eval exec $binfile &]
-    sleep 2
-    if { [istarget "*-*-cygwin*"] } {
-	# testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-	# different due to the way fork/exec works.
-	set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-    }
+    set testpid [spawn_wait_for_attach $binfile]
 
     remote_exec build "mv -f ${binfile_lib1} ${binfile_lib1}-running"
     remote_exec build "mv -f ${binfile_lib2} ${binfile_lib2}-running"
diff --git a/gdb/testsuite/gdb.multi/multi-attach.exp b/gdb/testsuite/gdb.multi/multi-attach.exp
index e933520..eaff2c9 100644
--- a/gdb/testsuite/gdb.multi/multi-attach.exp
+++ b/gdb/testsuite/gdb.multi/multi-attach.exp
@@ -30,15 +30,10 @@ if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug additiona
 
 # Start the programs running and then wait for a bit, to be sure that
 # they can be attached to.
-set testpid1 [eval exec $binfile &]
-set testpid2 [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid{1,2} are the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid1 [ exec ps -e | gawk "{ if (\$1 == $testpid1) print \$4; }" ]
-    set testpid2 [ exec ps -e | gawk "{ if (\$1 == $testpid2) print \$4; }" ]
-}
+
+set pid_list [spawn_wait_for_attach [list $binfile $binfile]]
+set testpid1 [lindex $pid_list 0]
+set testpid2 [lindex $pid_list 1]
 
 gdb_test "attach $testpid1" \
     "Attaching to program: .*, process $testpid1.*(in|at).*" \
diff --git a/gdb/testsuite/gdb.python/py-prompt.exp b/gdb/testsuite/gdb.python/py-prompt.exp
index ebe4cb6..1c53c03 100644
--- a/gdb/testsuite/gdb.python/py-prompt.exp
+++ b/gdb/testsuite/gdb.python/py-prompt.exp
@@ -80,15 +80,7 @@ gdb_test "python print (\"'\" + str(p\[0\]) + \"'\")" "'$gdb_prompt_fail '" \
 	 "prompt_hook argument is default prompt. 2"
 gdb_exit
 
-# Start the program running and then wait for a bit, to be sure
-# that it can be attached to.
-set testpid [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-}
+set testpid [spawn_wait_for_attach $binfile]
 
 set GDBFLAGS [concat $tmp_gdbflags " -ex \"set pagination off\""]
 set GDBFLAGS [concat $GDBFLAGS " -ex \"set editing on\""]
diff --git a/gdb/testsuite/gdb.python/py-sync-interp.exp b/gdb/testsuite/gdb.python/py-sync-interp.exp
index b9b86bc..d62f966 100644
--- a/gdb/testsuite/gdb.python/py-sync-interp.exp
+++ b/gdb/testsuite/gdb.python/py-sync-interp.exp
@@ -41,15 +41,7 @@ if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
     return -1
 }
 
-# Start the program running and then wait for a bit, to be sure
-# that it can be attached to.
-set testpid [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-}
+set testpid [spawn_wait_for_attach $binfile]
 
 # Test command 'where' is executed when command 'attach' is done, otherwise
 # function 'sleep' may not show up in backtrace.
diff --git a/gdb/testsuite/gdb.server/ext-attach.exp b/gdb/testsuite/gdb.server/ext-attach.exp
index 5f7bac4..9baeeb7 100644
--- a/gdb/testsuite/gdb.server/ext-attach.exp
+++ b/gdb/testsuite/gdb.server/ext-attach.exp
@@ -44,15 +44,7 @@ gdbserver_start_extended
 
 gdb_test_no_output "set remote exec-file $target_exec" "set remote exec-file"
 
-# Start the program running and then wait for a bit, to be sure
-# that it can be attached to.
-set testpid [eval exec $binfile &]
-exec sleep 2
-if { [istarget "*-*-cygwin*"] } {
-    # testpid is the Cygwin PID, GDB uses the Windows PID, which might be
-    # different due to the way fork/exec works.
-    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
-}
+set testpid [spawn_wait_for_attach $binfile]
 
 gdb_test "attach $testpid" \
     "Attaching to program: .*, process $testpid.*(in|at).*" \
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 7650d2a..e2ee110 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -3323,6 +3323,31 @@ proc gdb_exit { } {
     catch default_gdb_exit
 }
 
+# Start a set of programs running and then wait for a bit, to be sure
+# that they can be attached to.  Return a list of the processes' PIDs.
+
+proc spawn_wait_for_attach { executable_list } {
+    set pid_list {}
+
+    foreach {executable} $executable_list {
+	lappend pid_list [eval exec $executable &]
+    }
+
+    sleep 2
+
+    if { [istarget "*-*-cygwin*"] } {
+	for {set i 0} {$i < [llength $pid_list]} {incr i} {
+	    # testpid is the Cygwin PID, GDB uses the Windows PID,
+	    # which might be different due to the way fork/exec works.
+	    set testpid [lindex $pid_list $i]
+	    set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ]
+	    set pid_list [lreplace $pid_list $i $i $testpid]
+	}
+    }
+
+    return $pid_list
+}
+
 #
 # gdb_load_cmd -- load a file into the debugger.
 #		  ARGS - additional args to load command.
-- 
1.9.3


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race
  2014-09-09 18:25                             ` Jan Kratochvil
@ 2014-09-11 12:36                               ` Pedro Alves
  2014-09-12  7:34                                 ` [testsuite patch] runaway attach processes [Re: Regression: GDB stopped on run with attached process (PR 17347)] Jan Kratochvil
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-09-11 12:36 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/09/2014 07:25 PM, Jan Kratochvil wrote:
> On Mon, 08 Sep 2014 18:26:55 +0200, Pedro Alves wrote:
>> Here's the updated patch.  WDYT?
> 
> Yes, fine with that.

Thanks, pushed to both master and 7.8.

Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [testsuite patch] runaway attach processes  [Re: Regression: GDB stopped on run with attached process (PR 17347)]
  2014-09-11 12:36                               ` Pedro Alves
@ 2014-09-12  7:34                                 ` Jan Kratochvil
  2014-09-12 10:14                                   ` Pedro Alves
  0 siblings, 1 reply; 42+ messages in thread
From: Jan Kratochvil @ 2014-09-12  7:34 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Doug Evans, Mark Wielaard, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 497 bytes --]

On Thu, 11 Sep 2014 14:35:53 +0200, Pedro Alves wrote:
> Thanks, pushed to both master and 7.8.

I have started seeing occasional runaway 'attach' processes these days.
I cannot be certain it is really caused by this patch, for example
grep 'FAIL.*cmdline attach run' does not show anything in my logs.

But as I remember this 'attach' runaway process always happened in GDB (but
I do not remember it in the past months) I think it would be most safe to just
solve it forever by [attached].


Jan

[-- Attachment #2: 1 --]
[-- Type: text/plain, Size: 1823 bytes --]

gdb/testsuite/
2014-09-12  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/attach.c: Include unistd.h.
	(main): Call alarm.  Add label postloop.
	* gdb.base/attach.exp (do_attach_tests): Use gdb_get_line_number,
	gdb_breakpoint, gdb_continue_to_breakpoint.
	(test_command_line_attach_run): Kill ${testpid} in one exit path.

diff --git a/gdb/testsuite/gdb.base/attach.c b/gdb/testsuite/gdb.base/attach.c
index 0041b47..91b180c 100644
--- a/gdb/testsuite/gdb.base/attach.c
+++ b/gdb/testsuite/gdb.base/attach.c
@@ -5,6 +5,7 @@
    exit unless/until gdb sets the variable to non-zero.)
    */
 #include <stdio.h>
+#include <unistd.h>
 
 int  should_exit = 0;
 
@@ -12,9 +13,11 @@ int main ()
 {
   int  local_i = 0;
 
+  alarm (60);
+
   while (! should_exit)
     {
       local_i++;
     }
-  return 0;
+  return 0; /* postloop */
 }
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index 6340496..5fb5c53 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -256,11 +256,8 @@ proc do_attach_tests {} {
 
     # Verify that the modification really happened.
 
-    gdb_test "tbreak 19" "Temporary breakpoint .*at.*$srcfile, line 19.*" \
-	"after attach2, set tbreak postloop"
-
-    gdb_test "continue" "main.*at.*$srcfile:19.*" \
-	"after attach2, reach tbreak postloop"
+    gdb_breakpoint [gdb_get_line_number "postloop"] temporary
+    gdb_continue_to_breakpoint "postloop" ".* postloop .*"
 
     # Allow the test process to exit, to cleanup after ourselves.
 
@@ -418,6 +415,7 @@ proc test_command_line_attach_run {} {
 		     "-iex \"set height 0\" -iex \"set width 0\" --pid=$testpid -ex \"start\""]
 	if { $res != 0} {
 	    fail $test
+	    remote_exec build "kill -9 ${testpid}"
 	    return $res
 	}
 	gdb_test_multiple "" $test {

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [testsuite patch] runaway attach processes  [Re: Regression: GDB stopped on run with attached process (PR 17347)]
  2014-09-12  7:34                                 ` [testsuite patch] runaway attach processes [Re: Regression: GDB stopped on run with attached process (PR 17347)] Jan Kratochvil
@ 2014-09-12 10:14                                   ` Pedro Alves
  2014-09-12 11:40                                     ` [commit] " Jan Kratochvil
  0 siblings, 1 reply; 42+ messages in thread
From: Pedro Alves @ 2014-09-12 10:14 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On 09/12/2014 08:34 AM, Jan Kratochvil wrote:
> On Thu, 11 Sep 2014 14:35:53 +0200, Pedro Alves wrote:
>> > Thanks, pushed to both master and 7.8.
> I have started seeing occasional runaway 'attach' processes these days.
> I cannot be certain it is really caused by this patch, for example
> grep 'FAIL.*cmdline attach run' does not show anything in my logs.
> 
> But as I remember this 'attach' runaway process always happened in GDB (but
> I do not remember it in the past months) I think it would be most safe to just
> solve it forever by [attached].

Agreed.  OK.

> gdb/testsuite/
> 2014-09-12  Jan Kratochvil  <jan.kratochvil@redhat.com>
> 
> 	* gdb.base/attach.c: Include unistd.h.
> 	(main): Call alarm.  Add label postloop.
> 	* gdb.base/attach.exp (do_attach_tests): Use gdb_get_line_number,
> 	gdb_breakpoint, gdb_continue_to_breakpoint.
> 	(test_command_line_attach_run): Kill ${testpid} in one exit path.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [commit] [testsuite patch] runaway attach processes  [Re: Regression: GDB stopped on run with attached process (PR 17347)]
  2014-09-12 10:14                                   ` Pedro Alves
@ 2014-09-12 11:40                                     ` Jan Kratochvil
  0 siblings, 0 replies; 42+ messages in thread
From: Jan Kratochvil @ 2014-09-12 11:40 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Doug Evans, Mark Wielaard, gdb-patches

On Fri, 12 Sep 2014 12:14:18 +0200, Pedro Alves wrote:
> On 09/12/2014 08:34 AM, Jan Kratochvil wrote:
> > gdb/testsuite/
> > 2014-09-12  Jan Kratochvil  <jan.kratochvil@redhat.com>
> > 
> > 	* gdb.base/attach.c: Include unistd.h.
> > 	(main): Call alarm.  Add label postloop.
> > 	* gdb.base/attach.exp (do_attach_tests): Use gdb_get_line_number,
> > 	gdb_breakpoint, gdb_continue_to_breakpoint.
> > 	(test_command_line_attach_run): Kill ${testpid} in one exit path.
> 
> Thanks,

Checked in: 
	1cf2f1b045e9e647f6dfd28829ff4592c588dcb7


Thanks,
Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Crash regression for annota1.exp w/vDSO debuginfo  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-05-29 13:44 ` [pushed] Re: [PATCH v6 0/2] enable target-async by default Pedro Alves
  2014-07-01 16:28   ` Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
@ 2014-10-05 14:00   ` Jan Kratochvil
  2014-10-05 14:14     ` Jan Kratochvil
                       ` (2 more replies)
  1 sibling, 3 replies; 42+ messages in thread
From: Jan Kratochvil @ 2014-10-05 14:00 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Thu, 29 May 2014 15:44:02 +0200, Pedro Alves wrote:
> I went ahead and pushed this all in, with Eli's comments addressed.

329ea57934a9d4b250a0b417af1ec47bc2d0ceb6 is the first bad commit
commit 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6
Author: Pedro Alves <palves@redhat.com>
Date:   Thu May 29 19:58:57 2014 +0100

    enable target async by default; separate MI and target notions of async

CFLAGS=-g ./configure --without-guile --with-separate-debug-dir=/usr/lib/debug;make;cd gdb/testsuite;make site.exp;i=0;while runtest gdb.base/annota1.exp;! grep 'called with no handler' gdb.log ;do i=$[$i+1];echo -----------$i;done

Starting program: .../gdb/testsuite/gdb.base/annota1 ^M
warning: section  not found in /usr/lib/debug/lib/modules/3.16.3-200.fc20.x86_64/vdso/vdso64.so.debug^M
[...]
FAIL: gdb.base/annota1.exp: run until main breakpoint (timeout)
[...]
readline: readline_callback_read_char() called with no handler!^M
ERROR: Process no longer exists

kernel-debuginfo-3.16.3-200.fc20.x86_64

#0  in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  in __GI_abort () at abort.c:89
#2  in rl_callback_read_char () at callback.c:116
#3  in rl_callback_read_char_wrapper (client_data=0x0) at event-top.c:167
#4  in stdin_event_handler (error=0, client_data=0x0) at event-top.c:373
#5  in handle_file_event (data=...) at event-loop.c:763
#6  in process_event () at event-loop.c:340
#7  in gdb_do_one_event () at event-loop.c:361
#8  in start_event_loop () at event-loop.c:429
#9  in cli_command_loop (data=0x0) at event-top.c:182
#10 in current_interp_command_loop () at interps.c:318
#11 in captured_command_loop (data=0x0) at main.c:323
#12 in catch_errors (func=0x6133a6 <captured_command_loop>, func_args=0x0, errstring=0x902525 "", mask=RETURN_MASK_ALL) at exceptions.c:237
#13 in captured_main (data=0x7fff7eb43bd0) at main.c:1151
#14 in catch_errors (func=0x6137be <captured_main>, func_args=0x7fff7eb43bd0, errstring=0x902525 "", mask=RETURN_MASK_ALL) at exceptions.c:237
#15 in gdb_main (args=0x7fff7eb43bd0) at main.c:1159
#16 in main (argc=5, argv=0x7fff7eb43cd8) at gdb.c:32

That file /usr/lib/debug/lib/modules/3.16.3-200.fc20.x86_64/vdso/vdso64.so.debug is required for the crash reproducibility.

That message
	warning: section  not found in /usr/lib/debug/lib/modules/3.16.3-200.fc20.x86_64/vdso/vdso64.so.debug^M
is does not seem to be right - the file looks OK to me - but that seems
unrelated to this regression.  Going to check next what vDSO separate debug
info problem it is.


Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Crash regression for annota1.exp w/vDSO debuginfo  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-10-05 14:00   ` Crash regression for annota1.exp w/vDSO debuginfo [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
@ 2014-10-05 14:14     ` Jan Kratochvil
  2014-10-05 16:43     ` Jan Kratochvil
  2014-10-09 15:48     ` Pedro Alves
  2 siblings, 0 replies; 42+ messages in thread
From: Jan Kratochvil @ 2014-10-05 14:14 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Sun, 05 Oct 2014 16:00:39 +0200, Jan Kratochvil wrote:
> On Thu, 29 May 2014 15:44:02 +0200, Pedro Alves wrote:
> > I went ahead and pushed this all in, with Eli's comments addressed.
> 
> 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6 is the first bad commit
> commit 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6
> Author: Pedro Alves <palves@redhat.com>
> Date:   Thu May 29 19:58:57 2014 +0100
> 
>     enable target async by default; separate MI and target notions of async
> 
> CFLAGS=-g ./configure --without-guile --with-separate-debug-dir=/usr/lib/debug;make;cd gdb/testsuite;make site.exp;i=0;while runtest gdb.base/annota1.exp;! grep 'called with no handler' gdb.log ;do i=$[$i+1];echo -----------$i;done

Another reproducer can be found in:
	crash in non-stop mode with continue -a & (readline_callback_read_char() called with no handler!)
	https://sourceware.org/bugzilla/show_bug.cgi?id=17300


Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Crash regression for annota1.exp w/vDSO debuginfo  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-10-05 14:00   ` Crash regression for annota1.exp w/vDSO debuginfo [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
  2014-10-05 14:14     ` Jan Kratochvil
@ 2014-10-05 16:43     ` Jan Kratochvil
  2014-10-09 15:48     ` Pedro Alves
  2 siblings, 0 replies; 42+ messages in thread
From: Jan Kratochvil @ 2014-10-05 16:43 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Sun, 05 Oct 2014 16:00:39 +0200, Jan Kratochvil wrote:
> That message
> 	warning: section  not found in /usr/lib/debug/lib/modules/3.16.3-200.fc20.x86_64/vdso/vdso64.so.debug^M
> is does not seem to be right - the file looks OK to me - but that seems
> unrelated to this regression.  Going to check next what vDSO separate debug
> info problem it is.

The message happens only with the separate debug info installed but in fact
the bug can be seen even without the separate debug info installed.

kernel-3.16.3-200.fc20.x86_64
(gdb) info files
[...]
0x00007ffff7ffb120 - 0x00007ffff7ffb160 is  in system-supplied DSO at 0x7ffff7ffb000
                                          ^^
0x00007ffff7ffb160 - 0x00007ffff7ffb268 is .dynsym in system-supplied DSO at 0x7ffff7ffb000
0x00007ffff7ffb268 - 0x00007ffff7ffb2c6 is .dynstr in system-supplied DSO at 0x7ffff7ffb000
  [ 8] .fake_shstrtab    STRTAB          0000000000000780 000780 000076 00   A  0   0 32

This is because sh_name==0 for the first section and .fake_shstrtab
errorneously did not contain 0x00 as its very first byte (as required by the
ELF standard) and therefore BFD considered the first section nameless.

I have verified the problem no longer occurs on:

kernel-3.17.0-0.rc7.git3.1.fc22.x86_64
(gdb) info files
0x00007ffff7ffd120 - 0x00007ffff7ffd160 is .hash in system-supplied DSO at 0x7ffff7ffd000
                                           ^^^^^
0x00007ffff7ffd160 - 0x00007ffff7ffd268 is .dynsym in system-supplied DSO at 0x7ffff7ffd000
0x00007ffff7ffd268 - 0x00007ffff7ffd2c6 is .dynstr in system-supplied DSO at 0x7ffff7ffd000
  [15] .shstrtab         STRTAB          0000000000000000 001308 0000a2 00      0   0  1

Expecting it is probably since:
	https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=da861e18ecccb5c126b9eb95ff720ce082a46286
	x86, vdso: Get rid of the fake section mechanism

I have tested that this older kernel also does not have the problem:
kernel-3.10.0-123.el7.x86_64
        0x00007ffff7ffa120 - 0x00007ffff7ffa160 is .hash in system-supplied DSO at 0x7ffff7ffa000
        0x00007ffff7ffa160 - 0x00007ffff7ffa268 is .dynsym in system-supplied DSO at 0x7ffff7ffa000
        0x00007ffff7ffa268 - 0x00007ffff7ffa2c6 is .dynstr in system-supplied DSO at 0x7ffff7ffa000
  [15] .shstrtab         STRTAB          0000000000000000 00105a 0000a3 00      0   0  1

Therefore I do not think it is worth workarounding in GDB.


Jan

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: Crash regression for annota1.exp w/vDSO debuginfo  [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]
  2014-10-05 14:00   ` Crash regression for annota1.exp w/vDSO debuginfo [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
  2014-10-05 14:14     ` Jan Kratochvil
  2014-10-05 16:43     ` Jan Kratochvil
@ 2014-10-09 15:48     ` Pedro Alves
  2 siblings, 0 replies; 42+ messages in thread
From: Pedro Alves @ 2014-10-09 15:48 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: gdb-patches

On 10/05/2014 03:00 PM, Jan Kratochvil wrote:
> On Thu, 29 May 2014 15:44:02 +0200, Pedro Alves wrote:
>> I went ahead and pushed this all in, with Eli's comments addressed.
> 
> 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6 is the first bad commit
> commit 329ea57934a9d4b250a0b417af1ec47bc2d0ceb6
> Author: Pedro Alves <palves@redhat.com>
> Date:   Thu May 29 19:58:57 2014 +0100
> 
>     enable target async by default; separate MI and target notions of async
> 
> CFLAGS=-g ./configure --without-guile --with-separate-debug-dir=/usr/lib/debug;make;cd gdb/testsuite;make site.exp;i=0;while runtest gdb.base/annota1.exp;! grep 'called with no handler' gdb.log ;do i=$[$i+1];echo -----------$i;done
> 
> Starting program: .../gdb/testsuite/gdb.base/annota1 ^M
> warning: section  not found in /usr/lib/debug/lib/modules/3.16.3-200.fc20.x86_64/vdso/vdso64.so.debug^M
> [...]
> FAIL: gdb.base/annota1.exp: run until main breakpoint (timeout)
> [...]
> readline: readline_callback_read_char() called with no handler!^M
> ERROR: Process no longer exists

Thanks for the reproducer.  After investigation with a lot of head
scratching staring at hacked in logs in select place, in the end this
turned out to be real simple to trigger.  All it takes is turning on
annotations, do "c", and type something while the program is running...

I've filed PR 17472 for this.  I'll send a series fixing this and a
couple other terminal/readline issues shortly.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2014-10-09 15:48 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-23 20:59 [PATCH v6 0/2] enable target-async by default Pedro Alves
2014-05-23 20:59 ` [PATCH v6 2/2] enable target async by default; separate MI and target notions of async Pedro Alves
2014-05-24  7:03   ` Eli Zaretskii
2014-05-29 13:49     ` Pedro Alves
2014-07-30 18:40       ` Doug Evans
2014-05-23 20:59 ` [PATCH v6 1/2] Make display_gdb_prompt CLI-only Pedro Alves
2014-05-29 13:44 ` [pushed] Re: [PATCH v6 0/2] enable target-async by default Pedro Alves
2014-07-01 16:28   ` Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
2014-07-02  8:59     ` Mark Wielaard
2014-07-02  9:16       ` Pedro Alves
2014-07-03 15:39         ` Pedro Alves
2014-07-04 13:48           ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Pedro Alves
2014-07-04 21:13             ` Mark Wielaard
2014-07-07 16:39             ` Doug Evans
2014-07-08 15:24               ` Pedro Alves
2014-07-09 16:37                 ` Doug Evans
2014-07-09 17:09                   ` [pushed+7.8] " Pedro Alves
2014-07-29 22:03                     ` Doug Evans
2014-07-29 23:10                       ` Doug Evans
2014-07-30 12:46                         ` Pedro Alves
2014-07-30 12:38                       ` Pedro Alves
2014-07-30 16:59                         ` Doug Evans
2014-08-21 16:34                           ` [PUSHED] infcmd.c: Remove stale TODO Pedro Alves
2014-09-03  7:59                     ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]]] Jan Kratochvil
2014-09-03 20:11                       ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race Pedro Alves
2014-09-07 19:28                         ` Jan Kratochvil
2014-09-08 16:19                           ` [PATCH 1/2] testsuite: refactor spawn and wait for attach (was: Re: Regression: GDB stopped on run with attached process) Pedro Alves
2014-09-09 17:29                             ` Jan Kratochvil
2014-09-09 17:35                               ` [PATCH 1/2] testsuite: refactor spawn and wait for attach Pedro Alves
2014-09-10 21:25                                 ` Pedro Alves
2014-09-11 12:34                                   ` Pedro Alves
2014-09-08 16:27                           ` Regression: GDB stopped on run with attached process (PR 17347) [Re: [pushed+7.8] Re: [PATCH] Fix "attach" command vs user input race Pedro Alves
2014-09-09 18:25                             ` Jan Kratochvil
2014-09-11 12:36                               ` Pedro Alves
2014-09-12  7:34                                 ` [testsuite patch] runaway attach processes [Re: Regression: GDB stopped on run with attached process (PR 17347)] Jan Kratochvil
2014-09-12 10:14                                   ` Pedro Alves
2014-09-12 11:40                                     ` [commit] " Jan Kratochvil
2014-07-07 17:02             ` [PATCH] Fix "attach" command vs user input race [Re: Regression for attach from stdin [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default]] Jan Kratochvil
2014-10-05 14:00   ` Crash regression for annota1.exp w/vDSO debuginfo [Re: [pushed] Re: [PATCH v6 0/2] enable target-async by default] Jan Kratochvil
2014-10-05 14:14     ` Jan Kratochvil
2014-10-05 16:43     ` Jan Kratochvil
2014-10-09 15:48     ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).