[v2] Enable 'set print inferior-events' and cleanup attach/detach messages

Message ID 20180131165735.4339-1-sergiodj@redhat.com
State New
Headers show
Series
  • [v2] Enable 'set print inferior-events' and cleanup attach/detach messages
Related show

Commit Message

Sergio Durigan Junior Jan. 31, 2018, 4:57 p.m.
This is a followup of Pedro's suggestion to turn 'set print
inferior-events' always on, and do some cleanup on the messages
printed by GDB when attaching/detaching a inferior, or when it exits.

To make sure that the patch is correct, I've tested it with a handful
of combinations of 'set follow-fork-mode', 'set detach-on-fork' and
'set print inferior-events'.  In the end, I decided to make my
hand-made test into an official testcase.  More on that below.

I've also made a few modifications to messages that are printed when
'set print inferior-events' is on.  For example, a few of the messages
did not contain the '[' and ']' as prefix/suffix, which led to a few
inconsistencies like:

  Attaching after process 22995 fork to child process 22995.
  [New inferior 22999]
  Detaching after fork from child process 22999.
  [Inferior 22995 detached]
  [Inferior 2 (process 22999) exited normally]

So I took the opportunity and included the square brackets where
applicable.

As suggested by Pedro, the "[Inferior %d exited]" message from
'exit_inferior' has been removed, because it got duplicated when
'inferior-events' is on.  I'm also using the
'add_{thread,inferior}_silent' versions (instead of their verbose
counterparts) on some locations, also to avoid duplicated messages.

As for the tests, the configuration options being exercised are:

- follow-fork-mode: child/parent
- detach-on-fork: on/off
- print inferior-events: on/off

Built and regtested on BuildBot, without regressions.

gdb/ChangeLog:
2018-01-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Sergio Durigan Junior  <sergiodj@redhat.com>
	    Pedro Alves  <palves@redhat.com>

	* inferior.c (print_inferior_events): Remove 'static'.  Set as
	'1'.
	(exit_inferior): Remove message printed when
	'print_inferior_events' is on.
	(initialize_inferiors): Use 'add_inferior_silent' to set
	'current_inferior_'.
	* inferior.h (print_inferior_events): Declare here as
	'extern'.
	* infrun.c (follow_fork_inferior): Print '[Detaching...]'
	message when 'print_inferior_events' is on.  Use
	'add_thread_silent' instead of 'add_thread'.  Add '[' and ']'
	as prefix/suffix for 'Detaching...' message.
	(handle_vfork_child_exec_or_exit): Add '[' and ']' as
	prefix/suffix when printing 'Detaching...' message.  Print
	them when 'print_inferior_events' is on.

gdb/testsuite/ChangeLog:
2018-01-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Sergio Durigan Junior  <sergiodj@redhat.com>

	* gdb.base/attach-non-pgrp-leader.exp: Adjust 'Detaching...'
	regexps to expect for '[Inferior %d detached]' as well.
	* gdb.base/attach.exp: Likewise.
	* gdb.base/catch-syscall.exp (check_for_program_end): Adjust
	"gdb_continue_to_end".
	(test_catch_syscall_with_wrong_args): Likewise.
	* gdb.base/foll-fork.exp: Adjust regexps to match '[' and
	']'.  Don't set 'verbose' on.
	* gdb.base/foll-vfork.exp: Likewise.
	* gdb.base/fork-detach-info.c: New file.
	* gdb.base/fork-detach-info.exp: New file.
	* gdb.threads/clone-attach-detach.exp: Adjust 'Detaching...'
	regexps to expect for '[Inferior %d detached]' as well.
	* gdb.threads/process-dies-while-detaching.exp: Likewise.
---
 gdb/inferior.c                                     | 10 +---
 gdb/inferior.h                                     |  4 ++
 gdb/infrun.c                                       | 28 ++++-----
 gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp  |  5 +-
 gdb/testsuite/gdb.base/attach.exp                  |  3 +-
 gdb/testsuite/gdb.base/catch-syscall.exp           |  4 +-
 gdb/testsuite/gdb.base/foll-fork.exp               | 14 ++---
 gdb/testsuite/gdb.base/foll-vfork.exp              | 16 ++---
 gdb/testsuite/gdb.base/fork-detach-info.c          | 37 ++++++++++++
 gdb/testsuite/gdb.base/fork-detach-info.exp        | 68 ++++++++++++++++++++++
 gdb/testsuite/gdb.threads/clone-attach-detach.exp  |  4 +-
 .../gdb.threads/process-dies-while-detaching.exp   |  6 +-
 12 files changed, 149 insertions(+), 50 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/fork-detach-info.c
 create mode 100644 gdb/testsuite/gdb.base/fork-detach-info.exp

-- 
2.14.3

Comments

Pedro Alves Feb. 1, 2018, 5:17 p.m. | #1
On 01/31/2018 04:57 PM, Sergio Durigan Junior wrote:
> This is a followup of Pedro's suggestion to turn 'set print

> inferior-events' always on, and do some cleanup on the messages

> printed by GDB when attaching/detaching a inferior, or when it exits.

> 

> To make sure that the patch is correct, I've tested it with a handful

> of combinations of 'set follow-fork-mode', 'set detach-on-fork' and

> 'set print inferior-events'.  In the end, I decided to make my

> hand-made test into an official testcase.  More on that below.

> 

> I've also made a few modifications to messages that are printed when

> 'set print inferior-events' is on.  For example, a few of the messages

> did not contain the '[' and ']' as prefix/suffix, which led to a few

> inconsistencies like:

> 

>   Attaching after process 22995 fork to child process 22995.

>   [New inferior 22999]

>   Detaching after fork from child process 22999.

>   [Inferior 22995 detached]

>   [Inferior 2 (process 22999) exited normally]

> 

> So I took the opportunity and included the square brackets where

> applicable.

> 

> As suggested by Pedro, the "[Inferior %d exited]" message from

> 'exit_inferior' has been removed, because it got duplicated when

> 'inferior-events' is on.  I'm also using the

> 'add_{thread,inferior}_silent' versions (instead of their verbose

> counterparts) on some locations, also to avoid duplicated messages.


Can you give examples of the latter?  (what led to 'add_{thread,inferior}_silent')

> As for the tests, the configuration options being exercised are:

> 

> - follow-fork-mode: child/parent

> - detach-on-fork: on/off

> - print inferior-events: on/off

> 

> Built and regtested on BuildBot, without regressions.


Can you update the log to include examples of what the new
output looks like?  Both "set inferior-events on/off".
That makes it much easier to review/discuss/evaluate.

Can you say what happens to the output with
"set print inferior-events off" compared to current master?
Does output change in that case compared to today?  Not changing
output is not the goal, but it'd be good to be clear.

I'm experimenting a bit, and I'm seeing some inconsistencies
that I wonder whether we should consider revising.

For example, with "set print inferior-events on/off", we see,
for detach:

 (gdb) detach
 Detaching from program: /home/pedro/gdb/build/gdb/testsuite/outputs/gdb.base/foll-fork/foll-fork, process 2685
 [Inferior 2685 detached]
 (gdb) 

But for kill, we see:

 (gdb) k
 Kill the program being debugged? (y or n) y
 (gdb) 

Should detach vs kill be consistent?  I'd think so off hand.

Another thing is related to what I was proposing in the other
thread.  With the patch, we say:

 (gdb) c
 Continuing.
 [New inferior 3239]
 [Inferior 5 (process 3236) exited normally]

The "New inferior 3239" one is showing the target process ID,
which is confusing.  I think we should tweak to mention the
inferior ID, like:

 (gdb) c
 Continuing.
 [New inferior 5 (process 3236)]
 [Inferior 5 (process 3236) exited normally]


Looking at follow-fork child, detach-on-fork on, we see:

 [Attaching after process 12069 fork to child process 12069.]
 [New inferior 12073]
 [Detaching after fork from child process 12073.]
 [Inferior 12069 detached]
 [Inferior 2 (process 12073) exited normally]

That could use some normalization to make messages consistent
with one another.

 [Attaching after process 12069 fork to child process 12069.]
 [New inferior 2 (process 12073)]
 [Detaching after fork from child process 12073.]
 [Inferior 1 (process 12069) detached]
 [Inferior 2 (process 12073) exited normally]

(see more about this case below)

>  

>  	      target_terminal::ours_for_output ();

>  	      fprintf_filtered (gdb_stdlog,

> -				_("Detaching after %s from child %s.\n"),

> +				_("[Detaching after %s from child %s.]\n"),

>  				has_vforked ? "vfork" : "fork",

>  				target_pid_to_str (process_ptid));


I also noticed that this ends up with a period at the end, while
other [] notices don't, like (playing with "set detach-on-fork on"):

 [Detaching after fork from child process 3417.]
 [Inferior 5 (process 3416) exited normally]

> diff --git a/gdb/testsuite/gdb.base/fork-detach-info.exp b/gdb/testsuite/gdb.base/fork-detach-info.exp

> new file mode 100644

> index 0000000000..aa9a85c0d5

> --- /dev/null

> +++ b/gdb/testsuite/gdb.base/fork-detach-info.exp


Maybe this could use a different name, since this isn't
just about _detach_ info?

fork-print-inferior-events.exp, maybe.

> @@ -0,0 +1,68 @@

> +# This testcase is part of GDB, the GNU debugger.

> +

> +# Copyright 2007-2018 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/>.

> +


Please add an intro comment mentioning what the testcase is about.

> +if { [use_gdb_stub] || [target_info gdb_protocol] == "extended-remote" } {

> +    untested "not supported on gdbserver"

> +    return

> +}


I see that this relies on "run", so can't work with use_gdb_stub.
But why is this not supported with extended-remote gdbserver?

> +

> +standard_testfile

> +

> +if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {

> +    return -1

> +}

> +

> +# This is the expected output for each of the test combinations

> +# below.  The order here is important:

> +#

> +#    follow-fork: child; detach-on-fork: on; inferior-events: on

> +#    follow-fork: child; detach-on-fork: on; inferior-events: off

> +#    follow-fork: child; detach-on-fork: off; inferior-events: on

> +#    follow-fork: child; detach-on-fork: off; inferior-events: off

> +#    follow-fork: parent; detach-on-fork: on; inferior-events: on

> +#    follow-fork: parent; detach-on-fork: on; inferior-events: off

> +#    follow-fork: parent; detach-on-fork: off; inferior-events: on

> +#    follow-fork: parent; detach-on-fork: off; inferior-events: off

> +set expected_output [list \

> +    "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Detaching after fork from child process $decimal\\.\\\]\r\n\\\[Inferior $decimal detached\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

> +    "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

> +    "\\\[Detaching after fork from child process $decimal\\.\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

> +    "\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]"]

> +


I had a lot of trouble making sense of this big blurb of expected output.
I didn't know exactly what to suggest, so I played with it locally, and
I think putting the individual messages in variables helps a lot.
And then, I noticed that all the cases end up with 

  \\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]

so we can factor it out.

And then, if we iterate over print_inferior_events first, then
it's super clear that the "set print-inferior-events off"
case is always "no output".  See attached patch on top of yours.

The infrun.c hunk is there in my patch because while playing with
this, I noticed that gdb says that it's detaching the child
(and uses the child's pid), when in fact it is detaching the
parent!

I.e., currently, "set follow-fork child", "set detach-on-fork on":

 [Attaching after process 12069 fork to child process 12069.]
 [New inferior 2 12073]
 [Detaching after fork from child process 12073.]   <<< nope, it's detaching 12069 / the parent
 [Inferior 12069 detached]                          <<< see?
 [Inferior 2 (process 12073) exited normally]

after that fix:

 [Attaching after process 18500 fork to child process 18500.]
 [New inferior 18504]
 [Detaching after fork from parent process 18500.]
 [Inferior 18500 detached]
 [Inferior 2 (process 18504) exited normally]

Thanks,
Pedro Alves
From 7394aafa8f9126521c12e3a822666f75906059a3 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>

Date: Thu, 1 Feb 2018 17:11:43 +0000
Subject: [PATCH] inferior-events

---
 gdb/infrun.c                                |  4 +--
 gdb/testsuite/gdb.base/fork-detach-info.exp | 51 +++++++++++++++++------------
 2 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/gdb/infrun.c b/gdb/infrun.c
index 4ac5bde3035..85feedf6d4e 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -597,12 +597,12 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 	  if (print_inferior_events)
 	    {
 	      /* Ensure that we have a process ptid.  */
-	      ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
+	      ptid_t process_ptid = pid_to_ptid (ptid_get_pid (parent_ptid));
 
 	      target_terminal::ours_for_output ();
 	      fprintf_filtered (gdb_stdlog,
 				_("[Detaching after fork from "
-				  "child %s.]\n"),
+				  "parent %s.]\n"),
 				target_pid_to_str (process_ptid));
 	    }
 
diff --git a/gdb/testsuite/gdb.base/fork-detach-info.exp b/gdb/testsuite/gdb.base/fork-detach-info.exp
index aa9a85c0d5d..bc4aa5edcdd 100644
--- a/gdb/testsuite/gdb.base/fork-detach-info.exp
+++ b/gdb/testsuite/gdb.base/fork-detach-info.exp
@@ -29,38 +29,47 @@ if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
 # This is the expected output for each of the test combinations
 # below.  The order here is important:
 #
-#    follow-fork: child; detach-on-fork: on; inferior-events: on
-#    follow-fork: child; detach-on-fork: on; inferior-events: off
-#    follow-fork: child; detach-on-fork: off; inferior-events: on
-#    follow-fork: child; detach-on-fork: off; inferior-events: off
-#    follow-fork: parent; detach-on-fork: on; inferior-events: on
-#    follow-fork: parent; detach-on-fork: on; inferior-events: off
-#    follow-fork: parent; detach-on-fork: off; inferior-events: on
-#    follow-fork: parent; detach-on-fork: off; inferior-events: off
+#    inferior-events: on;  follow-fork: child;  detach-on-fork: on
+#    inferior-events: on;  follow-fork: child;  detach-on-fork: off
+#    inferior-events: on;  follow-fork: parent; detach-on-fork: on
+#    inferior-events: on;  follow-fork: parent; detach-on-fork: off
+#    inferior-events: off; follow-fork: child;  detach-on-fork: on
+#    inferior-events: off; follow-fork: child;  detach-on-fork: off
+#    inferior-events: off; follow-fork: parent; detach-on-fork: on
+#    inferior-events: off; follow-fork: parent; detach-on-fork: off
+
+set exited_normally_re "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]"
+set attach_child_re "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n"
+set detach_child_re "\\\[Detaching after fork from child process $decimal\\.\\\]\r\n"
+set detach_parent_re "\\\[Detaching after fork from parent process $decimal\\.\\\]\r\n"
+set new_inf_re "\\\[New inferior $decimal\\\]\r\n"
+set inf_detached_re "\\\[Inferior $decimal detached\\\]\r\n"
+
 set expected_output [list \
-    "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Detaching after fork from child process $decimal\\.\\\]\r\n\\\[Inferior $decimal detached\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
-    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
-    "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
-    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
-    "\\\[Detaching after fork from child process $decimal\\.\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
-    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
-    "\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
-    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]"]
+			 "${attach_child_re}${new_inf_re}${detach_parent_re}${inf_detached_re}" \
+			 "${attach_child_re}${new_inf_re}" \
+			 "${detach_child_re}" \
+			 "${new_inf_re}" \
+			 "" \
+			 "" \
+			 "" \
+			 "" \
+			]
 
 set i 0
 
-foreach_with_prefix follow_fork_mode { "child" "parent" } {
-    foreach_with_prefix detach_on_fork { "on" "off" } {
-	foreach_with_prefix print_inferior_events { "on" "off" } {
+foreach_with_prefix print_inferior_events { "on" "off" } {
+    foreach_with_prefix follow_fork_mode { "child" "parent" } {
+	foreach_with_prefix detach_on_fork { "on" "off" } {
 	    clean_restart $binfile
+	    gdb_test_no_output "set print inferior-events $print_inferior_events"
 	    gdb_test_no_output "set follow-fork-mode $follow_fork_mode"
 	    gdb_test_no_output "set detach-on-fork $detach_on_fork"
-	    gdb_test_no_output "set print inferior-events $print_inferior_events"
 
 	    set output [lindex $expected_output $i]
 	    # Always add the "Starting program..." string so that we
 	    # match exactly the lines we want.
-	    set output "Starting program: $binfile\\s*\r\n$output"
+	    set output "Starting program: $binfile\\s*\r\n$output${exited_normally_re}"
 	    set i [expr $i + 1]
 	    gdb_test "run" $output
 	}
-- 
2.14.3
Sergio Durigan Junior March 6, 2018, 1:44 a.m. | #2
On Thursday, February 01 2018, Pedro Alves wrote:

> On 01/31/2018 04:57 PM, Sergio Durigan Junior wrote:

>> This is a followup of Pedro's suggestion to turn 'set print

>> inferior-events' always on, and do some cleanup on the messages

>> printed by GDB when attaching/detaching a inferior, or when it exits.

>> 

>> To make sure that the patch is correct, I've tested it with a handful

>> of combinations of 'set follow-fork-mode', 'set detach-on-fork' and

>> 'set print inferior-events'.  In the end, I decided to make my

>> hand-made test into an official testcase.  More on that below.

>> 

>> I've also made a few modifications to messages that are printed when

>> 'set print inferior-events' is on.  For example, a few of the messages

>> did not contain the '[' and ']' as prefix/suffix, which led to a few

>> inconsistencies like:

>> 

>>   Attaching after process 22995 fork to child process 22995.

>>   [New inferior 22999]

>>   Detaching after fork from child process 22999.

>>   [Inferior 22995 detached]

>>   [Inferior 2 (process 22999) exited normally]

>> 

>> So I took the opportunity and included the square brackets where

>> applicable.

>> 

>> As suggested by Pedro, the "[Inferior %d exited]" message from

>> 'exit_inferior' has been removed, because it got duplicated when

>> 'inferior-events' is on.  I'm also using the

>> 'add_{thread,inferior}_silent' versions (instead of their verbose

>> counterparts) on some locations, also to avoid duplicated messages.

>

> Can you give examples of the latter?  (what led to 'add_{thread,inferior}_silent')


[ Resurrecting the thread... ]

Yes.

Using add_thread, set print inferior-events on, set follow-fork-mode
child, and set detach-on-fork on, I see:

  (gdb) run
  Starting program: a.out
  [Attaching after process 25088 fork to child process 25088.]
  [New inferior 25092]   <--- duplicated
  [Detaching after fork from child process 25092.]
  [Inferior 25088 detached]
  [New process 25092]    <--- duplicated
  [Inferior 2 (process 25092) exited normally]

But using add_thread_silent (with the same configuration as before):

  (gdb) run
  Starting program: a.out
  [Attaching after process 26807 fork to child process 26807.]
  [New inferior 26811]
  [Detaching after fork from child process 26811.]
  [Inferior 26807 detached]
  [Inferior 2 (process 26811) exited normally]

So we get rid of one duplicated line, produced by add_thread.

As for the add_inferior_silent case (on
inferiors.c:initialize_inferiors), it's useful to get rid of the:

  [New inferior 0]

message that happens when initializing GDB.

>> As for the tests, the configuration options being exercised are:

>> 

>> - follow-fork-mode: child/parent

>> - detach-on-fork: on/off

>> - print inferior-events: on/off

>> 

>> Built and regtested on BuildBot, without regressions.

>

> Can you update the log to include examples of what the new

> output looks like?  Both "set inferior-events on/off".

> That makes it much easier to review/discuss/evaluate.


Yes, that's a good idea.  Sorry for not doing that earlier.

> Can you say what happens to the output with

> "set print inferior-events off" compared to current master?

> Does output change in that case compared to today?  Not changing

> output is not the goal, but it'd be good to be clear.


Based on a test using an inferior that just forks:

  #include <unistd.h>
  int main () { fork (); return 0; }

And with set follow-fork-mode child, current master does:

  (gdb) r                                        
  Starting program: a.out
  [New process 5702]
  [Inferior 2 (process 5702) exited normally]

And my patch does:

  (gdb) r
  Starting program: a.out
  [Inferior 2 (process 5993) exited normally]

So yeah, we end up losing the notification of "[New process %d]" there,
which comes from thread.c:add_thread_with_info.

Pedantically, the "[Inferior 2 ... exited normally]" message should also
be considered an inferior event, and maybe should not be printed.

> I'm experimenting a bit, and I'm seeing some inconsistencies

> that I wonder whether we should consider revising.

>

> For example, with "set print inferior-events on/off", we see,

> for detach:

>

>  (gdb) detach

>  Detaching from program: /home/pedro/gdb/build/gdb/testsuite/outputs/gdb.base/foll-fork/foll-fork, process 2685

>  [Inferior 2685 detached]

>  (gdb) 

>

> But for kill, we see:

>

>  (gdb) k

>  Kill the program being debugged? (y or n) y

>  (gdb) 

>

> Should detach vs kill be consistent?  I'd think so off hand.


Hm, alright.  I can modify kill_command and print the message.  WDYT:

  (gdb) kill 
  Kill the program being debugged? (y or n) y
  [Inferior 14161 has been killed]

?

> Another thing is related to what I was proposing in the other

> thread.  With the patch, we say:

>

>  (gdb) c

>  Continuing.

>  [New inferior 3239]

>  [Inferior 5 (process 3236) exited normally]

>

> The "New inferior 3239" one is showing the target process ID,

> which is confusing.  I think we should tweak to mention the

> inferior ID, like:

>

>  (gdb) c

>  Continuing.

>  [New inferior 5 (process 3236)]

>  [Inferior 5 (process 3236) exited normally]


This looks a bit redundant to me, but I think it's the best way (at
least I couldn't think of a better one).

Consider it done.

> Looking at follow-fork child, detach-on-fork on, we see:

>

>  [Attaching after process 12069 fork to child process 12069.]

>  [New inferior 12073]

>  [Detaching after fork from child process 12073.]

>  [Inferior 12069 detached]

>  [Inferior 2 (process 12073) exited normally]

>

> That could use some normalization to make messages consistent

> with one another.

>

>  [Attaching after process 12069 fork to child process 12069.]

>  [New inferior 2 (process 12073)]

>  [Detaching after fork from child process 12073.]

>  [Inferior 1 (process 12069) detached]

>  [Inferior 2 (process 12073) exited normally]

>

> (see more about this case below)

>

>>  

>>  	      target_terminal::ours_for_output ();

>>  	      fprintf_filtered (gdb_stdlog,

>> -				_("Detaching after %s from child %s.\n"),

>> +				_("[Detaching after %s from child %s.]\n"),

>>  				has_vforked ? "vfork" : "fork",

>>  				target_pid_to_str (process_ptid));

>

> I also noticed that this ends up with a period at the end, while

> other [] notices don't, like (playing with "set detach-on-fork on"):

>

>  [Detaching after fork from child process 3417.]

>  [Inferior 5 (process 3416) exited normally]


Good point, I'll remove the periods.

>

>> diff --git a/gdb/testsuite/gdb.base/fork-detach-info.exp b/gdb/testsuite/gdb.base/fork-detach-info.exp

>> new file mode 100644

>> index 0000000000..aa9a85c0d5

>> --- /dev/null

>> +++ b/gdb/testsuite/gdb.base/fork-detach-info.exp

>

> Maybe this could use a different name, since this isn't

> just about _detach_ info?

>

> fork-print-inferior-events.exp, maybe.


Renamed.

>> @@ -0,0 +1,68 @@

>> +# This testcase is part of GDB, the GNU debugger.

>> +

>> +# Copyright 2007-2018 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/>.

>> +

>

> Please add an intro comment mentioning what the testcase is about.


Done.

>> +if { [use_gdb_stub] || [target_info gdb_protocol] == "extended-remote" } {

>> +    untested "not supported on gdbserver"

>> +    return

>> +}

>

> I see that this relies on "run", so can't work with use_gdb_stub.

> But why is this not supported with extended-remote gdbserver?


Just because, for extended-remote, the messages are a bit different:

  [Attaching after Thread 7738.7738 fork to child Thread 7738.7738]
  [New inferior 2 (process 7739)]
  [Detaching after fork from parent process 7738]
  [Inferior 7738 detached]
  [Inferior 2 (process 7739) exited normally]

This case is easy, it would just require an adjustment to the first line
(instead of "process $decimal" we'd expect "Thread
$decimal\.$decimal").  There are more annoying cases, like:

  Reading /lib64/ld-linux-x86-64.so.2 from remote target...
  Reading /lib64/ld-2.26.so.debug from remote target...
  Reading /lib64/.debug/ld-2.26.so.debug from remote target...
  Reading /lib64/libm.so.6 from remote target...
  Reading /lib64/libc.so.6 from remote target...
  Reading /lib64/libm-2.26.so.debug from remote target...
  Reading /lib64/.debug/libm-2.26.so.debug from remote target...
  Reading /lib64/libc-2.26.so.debug from remote target...
  Reading /lib64/.debug/libc-2.26.so.debug from remote target...
  [Attaching after Thread 7762.7762 fork to child Thread 7762.7762]
  [New inferior 2 (process 7763)]
  Reading /lib64/libm.so.6 from remote target...
  Reading /lib64/libc.so.6 from remote target...
  Reading /lib64/ld-linux-x86-64.so.2 from remote target...
  Reading /lib64/libm-2.26.so.debug from remote target...
  Reading /lib64/.debug/libm-2.26.so.debug from remote target...
  Reading /lib64/libc-2.26.so.debug from remote target...
  Reading /lib64/.debug/libc-2.26.so.debug from remote target...
  Reading /lib64/ld-2.26.so.debug from remote target...
  Reading /lib64/.debug/ld-2.26.so.debug from remote target...
  Reading /lib64/ld-linux-x86-64.so.2 from remote target...
  [Inferior 2 (process 7763) exited normally]

In this case, we'd have all the "Reading ..." messages to ignore, which
makes it hard to match the consecutive lines we expect.  Therefore, I
thought it made sense to make this test local.

Maybe a better solution for this would be to provide a similar test
under gdb.server.  Or just tweak the regexps.

>> +

>> +standard_testfile

>> +

>> +if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {

>> +    return -1

>> +}

>> +

>> +# This is the expected output for each of the test combinations

>> +# below.  The order here is important:

>> +#

>> +#    follow-fork: child; detach-on-fork: on; inferior-events: on

>> +#    follow-fork: child; detach-on-fork: on; inferior-events: off

>> +#    follow-fork: child; detach-on-fork: off; inferior-events: on

>> +#    follow-fork: child; detach-on-fork: off; inferior-events: off

>> +#    follow-fork: parent; detach-on-fork: on; inferior-events: on

>> +#    follow-fork: parent; detach-on-fork: on; inferior-events: off

>> +#    follow-fork: parent; detach-on-fork: off; inferior-events: on

>> +#    follow-fork: parent; detach-on-fork: off; inferior-events: off

>> +set expected_output [list \

>> + "\\\[Attaching after process $decimal fork to child process

>> $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Detaching

>> after fork from child process $decimal\\.\\\]\r\n\\\[Inferior

>> $decimal detached\\\]\r\n\\\[Inferior $decimal \\(process

>> $decimal\\) exited normally\\\]" \

>> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

>> +    "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

>> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

>> +    "\\\[Detaching after fork from child process $decimal\\.\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

>> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

>> +    "\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \

>> +    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]"]

>> +

>

> I had a lot of trouble making sense of this big blurb of expected output.

> I didn't know exactly what to suggest, so I played with it locally, and

> I think putting the individual messages in variables helps a lot.

> And then, I noticed that all the cases end up with 

>

>   \\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]

>

> so we can factor it out.

>

> And then, if we iterate over print_inferior_events first, then

> it's super clear that the "set print-inferior-events off"

> case is always "no output".  See attached patch on top of yours.


Thanks for the patch, I applied it on top of what I have here.

> The infrun.c hunk is there in my patch because while playing with

> this, I noticed that gdb says that it's detaching the child

> (and uses the child's pid), when in fact it is detaching the

> parent!

>

> I.e., currently, "set follow-fork child", "set detach-on-fork on":

>

>  [Attaching after process 12069 fork to child process 12069.]

>  [New inferior 2 12073]

>  [Detaching after fork from child process 12073.]   <<< nope, it's detaching 12069 / the parent

>  [Inferior 12069 detached]                          <<< see?

>  [Inferior 2 (process 12073) exited normally]

>

> after that fix:

>

>  [Attaching after process 18500 fork to child process 18500.]

>  [New inferior 18504]

>  [Detaching after fork from parent process 18500.]

>  [Inferior 18500 detached]

>  [Inferior 2 (process 18504) exited normally]


Ah, good catch.  ISTR having a strange feeling when examining these
outputs, but couldn't tell why.

I'll send a new version soon.

Thanks,

-- 
Sergio
GPG key ID: 237A 54B1 0287 28BF 00EF  31F4 D0EB 7628 65FC 5E36
Please send encrypted e-mail if possible
http://sergiodj.net/

Patch

diff --git a/gdb/inferior.c b/gdb/inferior.c
index 38b7369275..5bff8b3c07 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -45,9 +45,8 @@  DEFINE_REGISTRY (inferior, REGISTRY_ACCESS_FIELD)
 struct inferior *inferior_list = NULL;
 static int highest_inferior_num;
 
-/* Print notices on inferior events (attach, detach, etc.), set with
-   `set print inferior-events'.  */
-static int print_inferior_events = 0;
+/* See inferior.h.  */
+int print_inferior_events = 1;
 
 /* The Current Inferior.  This is a strong reference.  I.e., whenever
    an inferior is the current inferior, its refcount is
@@ -232,9 +231,6 @@  exit_inferior (int pid)
   struct inferior *inf = find_inferior_pid (pid);
 
   exit_inferior_1 (inf, 0);
-
-  if (print_inferior_events)
-    printf_unfiltered (_("[Inferior %d exited]\n"), pid);
 }
 
 void
@@ -986,7 +982,7 @@  initialize_inferiors (void)
      can only allocate an inferior when all those modules have done
      that.  Do this after initialize_progspace, due to the
      current_program_space reference.  */
-  current_inferior_ = add_inferior (0);
+  current_inferior_ = add_inferior_silent (0);
   current_inferior_->incref ();
   current_inferior_->pspace = current_program_space;
   current_inferior_->aspace = current_program_space->aspace;
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 22008a005b..6550d50d53 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -220,6 +220,10 @@  extern enum stop_stack_kind stop_stack_dummy;
 
 extern int stopped_by_random_signal;
 
+/* Print notices on inferior events (attach, detach, etc.), set with
+   `set print inferior-events'.  */
+extern int print_inferior_events;
+
 /* STEP_OVER_ALL means step over all subroutine calls.
    STEP_OVER_UNDEBUGGABLE means step over calls to undebuggable functions.
    STEP_OVER_NONE means don't step over any subroutine calls.  */
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 45fe36a717..4ac5bde303 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -461,14 +461,14 @@  holding the child stopped.  Try \"set detach-on-fork\" or \
 	      remove_breakpoints_pid (ptid_get_pid (inferior_ptid));
 	    }
 
-	  if (info_verbose || debug_infrun)
+	  if (print_inferior_events)
 	    {
 	      /* Ensure that we have a process ptid.  */
 	      ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
 
 	      target_terminal::ours_for_output ();
 	      fprintf_filtered (gdb_stdlog,
-				_("Detaching after %s from child %s.\n"),
+				_("[Detaching after %s from child %s.]\n"),
 				has_vforked ? "vfork" : "fork",
 				target_pid_to_str (process_ptid));
 	    }
@@ -489,7 +489,7 @@  holding the child stopped.  Try \"set detach-on-fork\" or \
 	  scoped_restore_current_pspace_and_thread restore_pspace_thread;
 
 	  inferior_ptid = child_ptid;
-	  add_thread (inferior_ptid);
+	  add_thread_silent (inferior_ptid);
 	  set_current_inferior (child_inf);
 	  child_inf->symfile_flags = SYMFILE_NO_READ;
 
@@ -549,11 +549,11 @@  holding the child stopped.  Try \"set detach-on-fork\" or \
       struct inferior *parent_inf, *child_inf;
       struct program_space *parent_pspace;
 
-      if (info_verbose || debug_infrun)
+      if (print_inferior_events)
 	{
 	  target_terminal::ours_for_output ();
 	  fprintf_filtered (gdb_stdlog,
-			    _("Attaching after %s %s to child %s.\n"),
+			    _("[Attaching after %s %s to child %s.]\n"),
 			    target_pid_to_str (parent_ptid),
 			    has_vforked ? "vfork" : "fork",
 			    target_pid_to_str (child_ptid));
@@ -594,15 +594,15 @@  holding the child stopped.  Try \"set detach-on-fork\" or \
 	}
       else if (detach_fork)
 	{
-	  if (info_verbose || debug_infrun)
+	  if (print_inferior_events)
 	    {
 	      /* Ensure that we have a process ptid.  */
 	      ptid_t process_ptid = pid_to_ptid (ptid_get_pid (child_ptid));
 
 	      target_terminal::ours_for_output ();
 	      fprintf_filtered (gdb_stdlog,
-				_("Detaching after fork from "
-				  "child %s.\n"),
+				_("[Detaching after fork from "
+				  "child %s.]\n"),
 				target_pid_to_str (process_ptid));
 	    }
 
@@ -616,7 +616,7 @@  holding the child stopped.  Try \"set detach-on-fork\" or \
 	 informing the solib layer about this new process.  */
 
       inferior_ptid = child_ptid;
-      add_thread (inferior_ptid);
+      add_thread_silent (inferior_ptid);
       set_current_inferior (child_inf);
 
       /* If this is a vfork child, then the address-space is shared
@@ -956,22 +956,22 @@  handle_vfork_child_exec_or_exit (int exec)
 	  inf->aspace = NULL;
 	  inf->pspace = NULL;
 
-	  if (debug_infrun || info_verbose)
+	  if (print_inferior_events)
 	    {
 	      target_terminal::ours_for_output ();
 
 	      if (exec)
 		{
 		  fprintf_filtered (gdb_stdlog,
-				    _("Detaching vfork parent process "
-				      "%d after child exec.\n"),
+				    _("[Detaching vfork parent process "
+				      "%d after child exec.]\n"),
 				    inf->vfork_parent->pid);
 		}
 	      else
 		{
 		  fprintf_filtered (gdb_stdlog,
-				    _("Detaching vfork parent process "
-				      "%d after child exit.\n"),
+				    _("[Detaching vfork parent process "
+				      "%d after child exit.]\n"),
 				    inf->vfork_parent->pid);
 		}
 	    }
diff --git a/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp b/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp
index dbe554eff3..6da2751b45 100644
--- a/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp
+++ b/gdb/testsuite/gdb.base/attach-non-pgrp-leader.exp
@@ -30,6 +30,7 @@  if { [build_executable ${testfile}.exp ${testfile} $srcfile {debug}] == -1 } {
 
 proc do_test {} {
     global binfile
+    global decimal
 
     set test_spawn_id [spawn_wait_for_attach $binfile]
     set parent_pid [spawn_id_get_pid $test_spawn_id]
@@ -52,7 +53,7 @@  proc do_test {} {
 	}
 
 	gdb_test "detach" \
-	    "Detaching from program: .*process $parent_pid"
+	    "Detaching from program: .*process $parent_pid\r\n\\\[Inferior $decimal detached\\\]"
     }
 
     # Start over, and attach to the child this time.
@@ -67,7 +68,7 @@  proc do_test {} {
 	gdb_continue_to_breakpoint "marker"
 
 	gdb_test "detach" \
-	    "Detaching from program: .*process $child_pid"
+	    "Detaching from program: .*process $child_pid\r\n\\\[Inferior $decimal detached\\\]"
     }
 
     kill_wait_spawned_process $test_spawn_id
diff --git a/gdb/testsuite/gdb.base/attach.exp b/gdb/testsuite/gdb.base/attach.exp
index d315c2792e..42cf6b8328 100644
--- a/gdb/testsuite/gdb.base/attach.exp
+++ b/gdb/testsuite/gdb.base/attach.exp
@@ -53,6 +53,7 @@  proc do_attach_tests {} {
     global testfile
     global subdir
     global timeout
+    global decimal
     
     # Figure out a regular expression that will match the sysroot,
     # noting that the default sysroot is "target:", and also noting
@@ -194,7 +195,7 @@  proc do_attach_tests {} {
     # Detach the process.
    
     gdb_test "detach" \
-	"Detaching from program: .*$escapedbinfile, process $testpid" \
+	"Detaching from program: .*$escapedbinfile, process $testpid\r\n\\\[Inferior $decimal detached\\\]" \
 	"attach1 detach"
 
     # Wait a bit for gdb to finish detaching
diff --git a/gdb/testsuite/gdb.base/catch-syscall.exp b/gdb/testsuite/gdb.base/catch-syscall.exp
index 2a8bf27e5c..20fa041155 100644
--- a/gdb/testsuite/gdb.base/catch-syscall.exp
+++ b/gdb/testsuite/gdb.base/catch-syscall.exp
@@ -179,7 +179,7 @@  proc check_for_program_end {} {
     # Deleting the catchpoints
     delete_breakpoints
 
-    gdb_continue_to_end
+    gdb_continue_to_end "" continue 1
 }
 
 proc test_catch_syscall_without_args {} {
@@ -250,7 +250,7 @@  proc test_catch_syscall_with_wrong_args {} {
 	# If it doesn't, everything is right (since we don't have
 	# a syscall named "mlock" in it).  Otherwise, this is a failure.
 	set thistest "catch syscall with unused syscall ($syscall_name)"
-	gdb_continue_to_end $thistest
+	gdb_continue_to_end $thistest continue 1
     }
 }
 
diff --git a/gdb/testsuite/gdb.base/foll-fork.exp b/gdb/testsuite/gdb.base/foll-fork.exp
index a715b7fa9d..9e8fe99542 100644
--- a/gdb/testsuite/gdb.base/foll-fork.exp
+++ b/gdb/testsuite/gdb.base/foll-fork.exp
@@ -110,13 +110,13 @@  proc test_follow_fork { who detach cmd } {
 	# Set up the output we expect to see after we run.
 	set expected_re ""
 	if {$who == "child"} {
-	    set expected_re "Attaching after.* fork to.*"
+	    set expected_re "\\\[Attaching after.* fork to.*"
 	    if {$detach == "on"} {
-		append expected_re "Detaching after fork from .*"
+		append expected_re "\\\[Detaching after fork from .*"
 	    }
 	    append expected_re "set breakpoint here.*"
 	} elseif {$who == "parent" && $detach == "on"} {
-	    set expected_re "Detaching after fork from .*set breakpoint here.*"
+	    set expected_re "\\\[Detaching after fork from .*set breakpoint here.*"
 	} else {
 	    set expected_re ".*set breakpoint here.*"
 	}
@@ -217,7 +217,7 @@  proc catch_fork_child_follow {} {
 	"Temporary breakpoint.*, line $bp_after_fork.*" \
 	"set follow-fork child, tbreak"
 
-    set expected_re "Attaching after.* fork to.*Detaching after fork from"
+    set expected_re "\\\[Attaching after.* fork to.*\\\[Detaching after fork from"
     append expected_re ".* at .*$bp_after_fork.*"
     gdb_test "continue" $expected_re "set follow-fork child, hit tbreak"
 
@@ -305,7 +305,7 @@  proc tcatch_fork_parent_follow {} {
 	"set follow-fork parent, tbreak"
 
     gdb_test "continue" \
-	"Detaching after fork from.* at .*$bp_after_fork.*" \
+	"\\\[Detaching after fork from.* at .*$bp_after_fork.*" \
 	"set follow-fork parent, hit tbreak"
 
     # The child has been detached; allow time for any output it might
@@ -398,10 +398,6 @@  By default, the debugger will follow the parent process..*" \
     if [runto_main] then { tcatch_fork_parent_follow }
 }
 
-# The "Detaching..." and "Attaching..." messages may be hidden by
-# default.
-gdb_test_no_output "set verbose"
-
 # This is a test of gdb's ability to follow the parent, child or both
 # parent and child of a Unix fork() system call.
 #
diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp
index 6aa4edd9fe..ddda2d6143 100644
--- a/gdb/testsuite/gdb.base/foll-vfork.exp
+++ b/gdb/testsuite/gdb.base/foll-vfork.exp
@@ -55,10 +55,6 @@  proc setup_gdb {} {
 
     clean_restart $testfile
 
-    # The "Detaching..." and "Attaching..." messages may be hidden by
-    # default.
-    gdb_test_no_output "set verbose"
-
     if ![runto_main] {
 	return -code return
     }
@@ -103,7 +99,7 @@  proc vfork_parent_follow_through_step {} {
 
    set test "step"
    gdb_test_multiple "next" $test {
-       -re "Detaching after vfork from.*if \\(pid == 0\\).*$gdb_prompt " {
+       -re "\\\[Detaching after vfork from.*if \\(pid == 0\\).*$gdb_prompt " {
 	   pass $test
        }
    }
@@ -128,7 +124,7 @@  proc vfork_parent_follow_to_bp {} {
 
    set test "continue to bp"
    gdb_test_multiple "continue" $test {
-       -re ".*Detaching after vfork from child process.*Breakpoint.*${bp_location}.*$gdb_prompt " {
+       -re ".*\\\[Detaching after vfork from child process.*Breakpoint.*${bp_location}.*$gdb_prompt " {
 	   pass $test
        }
    }
@@ -153,7 +149,7 @@  proc vfork_child_follow_to_exit {} {
 	  # PR gdb/14766
 	  fail "$test"
       }
-      -re "Attaching after.* vfork to.*Detaching vfork parent .* after child exit.*$gdb_prompt " {
+       -re "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent .* after child exit.*$gdb_prompt " {
 	  pass $test
       }
    }
@@ -177,7 +173,7 @@  proc vfork_and_exec_child_follow_to_main_bp {} {
 
    set test "continue to bp"
    gdb_test_multiple "continue" $test {
-      -re "Attaching after.* vfork to.*Detaching vfork parent.*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$gdb_prompt " {
+      -re "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent.*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$gdb_prompt " {
 	  pass $test
       }
    }
@@ -203,7 +199,7 @@  proc vfork_and_exec_child_follow_through_step {} {
    # before it execs.  Thus, "next" lands on the next line after
    # the vfork.
    gdb_test_multiple "next" $test {
-       -re "Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " {
+       -re "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " {
 	   pass "$test"
        }
    }
@@ -341,7 +337,7 @@  proc vfork_relations_in_info_inferiors { variant } {
 
    set test "step over vfork"
    gdb_test_multiple "next" $test {
-       -re "Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " {
+       -re "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " {
 	   pass "$test"
        }
    }
diff --git a/gdb/testsuite/gdb.base/fork-detach-info.c b/gdb/testsuite/gdb.base/fork-detach-info.c
new file mode 100644
index 0000000000..182a363dcc
--- /dev/null
+++ b/gdb/testsuite/gdb.base/fork-detach-info.c
@@ -0,0 +1,37 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2007-2018 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 <stdlib.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+  pid_t child;
+
+  child = fork ();
+  switch (child)
+    {
+      case -1:
+	abort ();
+      case 0:
+      default:
+	break;
+    }
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/fork-detach-info.exp b/gdb/testsuite/gdb.base/fork-detach-info.exp
new file mode 100644
index 0000000000..aa9a85c0d5
--- /dev/null
+++ b/gdb/testsuite/gdb.base/fork-detach-info.exp
@@ -0,0 +1,68 @@ 
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2007-2018 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/>.
+
+if { [use_gdb_stub] || [target_info gdb_protocol] == "extended-remote" } {
+    untested "not supported on gdbserver"
+    return
+}
+
+standard_testfile
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile debug] } {
+    return -1
+}
+
+# This is the expected output for each of the test combinations
+# below.  The order here is important:
+#
+#    follow-fork: child; detach-on-fork: on; inferior-events: on
+#    follow-fork: child; detach-on-fork: on; inferior-events: off
+#    follow-fork: child; detach-on-fork: off; inferior-events: on
+#    follow-fork: child; detach-on-fork: off; inferior-events: off
+#    follow-fork: parent; detach-on-fork: on; inferior-events: on
+#    follow-fork: parent; detach-on-fork: on; inferior-events: off
+#    follow-fork: parent; detach-on-fork: off; inferior-events: on
+#    follow-fork: parent; detach-on-fork: off; inferior-events: off
+set expected_output [list \
+    "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Detaching after fork from child process $decimal\\.\\\]\r\n\\\[Inferior $decimal detached\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
+    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
+    "\\\[Attaching after process $decimal fork to child process $decimal\\.\\\]\r\n\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
+    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
+    "\\\[Detaching after fork from child process $decimal\\.\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
+    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
+    "\\\[New inferior $decimal\\\]\r\n\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]" \
+    "\\\[Inferior $decimal \\(process $decimal\\) exited normally\\\]"]
+
+set i 0
+
+foreach_with_prefix follow_fork_mode { "child" "parent" } {
+    foreach_with_prefix detach_on_fork { "on" "off" } {
+	foreach_with_prefix print_inferior_events { "on" "off" } {
+	    clean_restart $binfile
+	    gdb_test_no_output "set follow-fork-mode $follow_fork_mode"
+	    gdb_test_no_output "set detach-on-fork $detach_on_fork"
+	    gdb_test_no_output "set print inferior-events $print_inferior_events"
+
+	    set output [lindex $expected_output $i]
+	    # Always add the "Starting program..." string so that we
+	    # match exactly the lines we want.
+	    set output "Starting program: $binfile\\s*\r\n$output"
+	    set i [expr $i + 1]
+	    gdb_test "run" $output
+	}
+    }
+}
diff --git a/gdb/testsuite/gdb.threads/clone-attach-detach.exp b/gdb/testsuite/gdb.threads/clone-attach-detach.exp
index 1fbdc95ffc..07b10f534b 100644
--- a/gdb/testsuite/gdb.threads/clone-attach-detach.exp
+++ b/gdb/testsuite/gdb.threads/clone-attach-detach.exp
@@ -56,7 +56,7 @@  for {set attempt 1} {$attempt <= $attempts} {incr attempt} {
 	    "1.*${thread_re}.*\r\n.*2.*${thread_re}.*" \
 	    "info threads shows two LWPs"
 
-	gdb_test "detach" "Detaching from .*, process $testpid"
+	gdb_test "detach" "Detaching from .*, process $testpid\r\n\\\[Inferior $decimal detached\\\]"
     }
 }
 
@@ -91,7 +91,7 @@  for {set attempt 1} {$attempt <= $attempts} {incr attempt} {
 	    "1.*${thread_re}.*\\(running\\)\r\n.*2.*${thread_re}.*\\(running\\)" \
 	    "info threads shows two LWPs"
 
-	gdb_test "detach" "Detaching from .*, process $testpid"
+	gdb_test "detach" "Detaching from .*, process $testpid\r\n\\\[Inferior $decimal detached\\\]"
     }
 }
 
diff --git a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
index e05acb1711..515c25c341 100644
--- a/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
+++ b/gdb/testsuite/gdb.threads/process-dies-while-detaching.exp
@@ -82,7 +82,7 @@  proc detach_and_expect_exit {inf_output_re test} {
     global gdb_prompt
 
     return_if_fail [gdb_test_multiple "detach" $test {
-	-re "Detaching from .*, process $decimal" {
+	-re "Detaching from .*, process $decimal\r\n\\\[Inferior $decimal detached\\\]" {
 	}
     }]
 
@@ -169,7 +169,7 @@  proc do_detach {multi_process cmd child_exit} {
 			 && [target_info gdb_protocol] == "remote"}]
 
     if {$multi_process} {
-	gdb_test "detach" "Detaching from .*, process $decimal" \
+	gdb_test "detach" "Detaching from .*, process $decimal\r\n\\\[Inferior $decimal detached\\\]" \
 	    "detach child"
 
 	gdb_test "inferior 1" "\[Switching to inferior $decimal\].*" \
@@ -193,7 +193,7 @@  proc do_detach {multi_process cmd child_exit} {
 	    set extra ""
 	}
 	if {$cmd == "detach"} {
-	    gdb_test "detach" "Detaching from .*, process $decimal$extra"
+	    gdb_test "detach" "Detaching from .*, process $decimal\r\n\\\[Inferior $decimal detached\\\]$extra"
 	} elseif {$cmd == "continue"} {
 	    gdb_test "continue" $continue_re
 	} else {