xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.threads/next-fork-other-thread.c (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 2022-2023 Free Software Foundation, Inc.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17 
18 #include <pthread.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 #include <errno.h>
23 #include <assert.h>
24 #include <limits.h>
25 
26 /* Number of threads doing forks.  */
27 #define N_FORKERS 4
28 
29 static void *
30 forker (void *arg)
31 {
32   for (;;)
33     {
34       pid_t pid = FORK_FUNC ();
35 
36       if (pid == 0)
37 	_exit (11);
38 
39       assert (pid > 0);
40 
41       /* Wait for children to exit.  */
42       int ret;
43       int stat;
44       do
45 	{
46 	  ret = waitpid (pid, &stat, 0);
47 	} while (ret == -1 && errno == EINTR);
48 
49       assert (ret == pid);
50       assert (WIFEXITED (stat));
51       assert (WEXITSTATUS (stat) == 11);
52 
53       /* We need a sleep, otherwise the forking threads spam events and the
54 	 stepping thread doesn't make progress.  Sleep for a bit less than
55 	 `sleep_a_bit` does, so that forks are likely to interrupt a "next".  */
56       usleep (40 * 1000);
57     }
58 
59   return NULL;
60 }
61 
62 static void
63 sleep_a_bit (void)
64 {
65   usleep (1000 * 50);
66 }
67 
68 int
69 main (void)
70 {
71   int i;
72 
73   alarm (60);
74 
75   pthread_t thread[N_FORKERS];
76   for (i = 0; i < N_FORKERS; ++i)
77     {
78       int ret = pthread_create (&thread[i], NULL, forker, NULL);
79       assert (ret == 0);
80     }
81 
82   for (i = 0; i < INT_MAX; ++i) /* for loop */
83     {
84       sleep_a_bit ();  /* break here */
85       sleep_a_bit ();  /* other line */
86     }
87 
88   for (i = 0; i < N_FORKERS; ++i)
89     pthread_join (thread[i], NULL);
90 
91   return 0;
92 }
93