diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 1c98bbd031..6d1f5f7af5 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2018-06-14 Pedro Alves + + * gdb.base/fork-running-state.c: Include . + (exit_if_relative_exits): New. + (fork_child): If 'exit_if_relative_exits' is true, exit if the parent + exits. + (fork_parent): If 'exit_if_relative_exits' is true, exit if the + child exits. + 2018-06-14 Tom de Vries PR cli/22573 diff --git a/gdb/testsuite/gdb.base/fork-running-state.c b/gdb/testsuite/gdb.base/fork-running-state.c index 65ca942ea0..0037cb5a5e 100644 --- a/gdb/testsuite/gdb.base/fork-running-state.c +++ b/gdb/testsuite/gdb.base/fork-running-state.c @@ -19,9 +19,15 @@ #include #include #include +#include int save_parent; +/* Variable set by GDB. If true, then a fork child (or parent) exits + if its parent (or child) exits. Otherwise the process waits + forever until either GDB or the alarm kills it. */ +volatile int exit_if_relative_exits = 0; + /* The fork child. Just runs forever. */ static int @@ -31,7 +37,20 @@ fork_child (void) alarm (180); while (1) - pause (); + { + if (exit_if_relative_exits) + { + sleep (1); + + /* Exit if GDB kills the parent. */ + if (getppid () != save_parent) + break; + if (kill (getppid (), 0) != 0) + break; + } + else + pause (); + } return 0; } @@ -45,7 +64,23 @@ fork_parent (void) alarm (180); while (1) - pause (); + { + if (exit_if_relative_exits) + { + int res = wait (NULL); + if (res == -1 && errno == EINTR) + continue; + else if (res == -1) + { + perror ("wait"); + return 1; + } + else + return 0; + } + else + pause (); + } return 0; } diff --git a/gdb/testsuite/gdb.base/fork-running-state.exp b/gdb/testsuite/gdb.base/fork-running-state.exp index 27ed8a43e9..c15bc53f7a 100644 --- a/gdb/testsuite/gdb.base/fork-running-state.exp +++ b/gdb/testsuite/gdb.base/fork-running-state.exp @@ -70,6 +70,13 @@ proc do_test { detach_on_fork follow_fork non_stop schedule_multiple } { gdb_test_no_output "set schedule-multiple $schedule_multiple" } + # If we're detaching from the parent (or child), then tell it to + # exit itself when its child (or parent) exits. If we stay + # attached, we take care of killing it. + if {$detach_on_fork == "on"} { + gdb_test "print exit_if_relative_exits = 1" " = 1" + } + set test "continue &" gdb_test_multiple $test $test { -re "$gdb_prompt " {