]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/testsuite/gdb.threads/watchpoint-fork-child.c
update copyright year range in GDB files
[thirdparty/binutils-gdb.git] / gdb / testsuite / gdb.threads / watchpoint-fork-child.c
CommitLineData
4403d8e9
JK
1/* Test case for forgotten hw-watchpoints after fork()-off of a process.
2
61baf725 3 Copyright 2012-2017 Free Software Foundation, Inc.
4403d8e9
JK
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
7785b880 9 the Free Software Foundation; either version 3 of the License, or
4403d8e9
JK
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
7785b880 18 along with this program; if not, see <http://www.gnu.org/licenses/>. */
4403d8e9 19
1e903e32
PA
20#include "watchpoint-fork.h"
21
4403d8e9
JK
22#include <string.h>
23#include <errno.h>
24#include <unistd.h>
25#include <assert.h>
26#include <signal.h>
27#include <stdio.h>
28
4403d8e9
JK
29/* `pid_t' may not be available. */
30
31static volatile int usr1_got;
32
33static void
34handler_usr1 (int signo)
35{
36 usr1_got++;
37}
38
39void
40forkoff (int nr)
41{
42 int child, save_parent = getpid ();
43 int i;
44 struct sigaction act, oldact;
45#ifdef THREAD
46 void *thread_result;
47#endif
48
49 memset (&act, 0, sizeof act);
50 act.sa_flags = SA_RESTART;
51 act.sa_handler = handler_usr1;
52 sigemptyset (&act.sa_mask);
53 i = sigaction (SIGUSR1, &act, &oldact);
54 assert (i == 0);
55
56 child = fork ();
57 switch (child)
58 {
59 case -1:
60 assert (0);
61 default:
62 printf ("parent%d: %d\n", nr, (int) child);
63
64 /* Sleep for a while to possibly get incorrectly ATTACH_THREADed by GDB
65 tracing the child fork with no longer valid thread/lwp entries of the
66 parent. */
67
68 i = sleep (2);
69 assert (i == 0);
70
71 /* We must not get caught here (against a forgotten breakpoint). */
72
73 var++;
74 marker ();
75
76#ifdef THREAD
77 /* And neither got caught our thread. */
78
79 step = 99;
80 i = pthread_join (thread, &thread_result);
81 assert (i == 0);
82 assert (thread_result == (void *) 99UL);
83#endif
84
85 /* Be sure our child knows we did not get caught above. */
86
87 i = kill (child, SIGUSR1);
88 assert (i == 0);
89
90 /* Sleep for a while to check GDB's `info threads' no longer tracks us in
91 the child fork. */
92
93 i = sleep (2);
94 assert (i == 0);
95
96 _exit (0);
97 case 0:
98 printf ("child%d: %d\n", nr, (int) getpid ());
99
100 /* Let the parent signal us about its success. Be careful of races. */
101
102 for (;;)
103 {
104 /* Parent either died (and USR1_GOT is zero) or it succeeded. */
105 if (getppid () != save_parent)
106 break;
107 if (kill (getppid (), 0) != 0)
108 break;
109 /* Parent succeeded? */
110 if (usr1_got)
111 break;
112
113#ifdef THREAD
114 i = pthread_yield ();
115 assert (i == 0);
116#endif
117 }
118 assert (usr1_got);
119
120 /* We must get caught here (against a false watchpoint removal). */
121
122 marker ();
123 }
124
125 i = sigaction (SIGUSR1, &oldact, NULL);
126 assert (i == 0);
127}