https://gcc.gnu.org/g:56a683e3987cb8d0d33b4be9e8a83307a4cb8ba4

commit r17-5715-g56a683e3987cb8d0d33b4be9e8a83307a4cb8ba4
Author: Michael Morrell <[email protected]>
Date:   Tue Oct 27 13:17:38 2026 -0700

    testsuite: Wait for forked children in time-profiler-2.c and gcov-pr86536.c 
[PR111298]
    
    gcc.dg/tree-prof/time-profiler-2.c and gcc.misc-tests/gcov-pr86536.c
    call fork, and the parent returns from main without waiting for the
    child.  DejaGnu runs the test program on a pty, as the session leader.
    When the parent exits, the kernel hangs up the pty and sends SIGHUP to
    its foreground process group, so a child that is still running is
    killed before it writes its profile counts.  time-profiler-2.c then
    misses the child's call to bar, and its tp_first_run checks fail;
    gcov-pr86536.c reports a count of 1 instead of 2 for the lines after
    the fork.
    
    Natively the child usually finishes first, so this rarely shows.  Under
    a simulator it often does not: with user-mode QEMU both tests fail on
    every run, and with another simulator time-profiler-2.c fails
    intermittently.  Running the same programs on a pty with SIGHUP
    ignored, or without a pty, always keeps the child's counts.
    
    Make the parent wait for the child in both tests.  In gcov-pr86536.c
    the call goes on the blank line before the first count(2) line, so no
    annotated line moves: gcov.exp names its checks by line number, and
    the expected counts are unchanged.
    
    Assisted-by: Claude Opus 5.5
    
            PR testsuite/111298
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-prof/time-profiler-2.c: Require fork.  Include
            <sys/wait.h>.
            (main): Wait for the child process.
            * gcc.misc-tests/gcov-pr86536.c (main): Likewise.
    
    Signed-off-by: Michael Morrell <[email protected]>

Diff:
---
 gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c | 7 ++++++-
 gcc/testsuite/gcc.misc-tests/gcov-pr86536.c      | 4 ++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c 
b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
index eed0b1dd08d4..ace658bbc66d 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c
@@ -1,6 +1,8 @@
 /* { dg-options "-O2 -fdump-ipa-profile -fno-ipa-vrp" } */
+/* { dg-require-fork "" } */
 
 #include <unistd.h>
+#include <sys/wait.h>
 
 __attribute__ ((noinline))
 int foo()
@@ -39,7 +41,10 @@ int main ()
   if(f == 0) /* Child process.  */
     r = bar() - foo();
   else /* Parent process.  */
-    r = foo() - foo();
+    {
+      r = foo() - foo();
+      waitpid (f, NULL, 0); /* Wait for child to flush gcov data.  */
+    }
 
   return r;
 }
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr86536.c 
b/gcc/testsuite/gcc.misc-tests/gcov-pr86536.c
index febfacd92431..03b5219fa65e 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-pr86536.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-pr86536.c
@@ -15,9 +15,9 @@ main (void)
   int j = 22;            /* count(1) */
 
                          /* returns(200) */
-  fork ();               /* count(1)  */
+  pid_t pid = fork ();   /* count(1)  */
                          /* returns(end) */
-
+  if (pid > 0) waitpid (pid, NULL, 0); /* Wait for the child's counts.  */
   int i = 7;             /* count(2) */
   return 0;              /* count(2) */
 }

Reply via email to