Fix gdb.threads/tls-so_extern.exp with Clang
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.threads / watchpoint-fork-mt.c
1 /* Test case for forgotten hw-watchpoints after fork()-off of a process.
2
3 Copyright 2012-2020 Free Software Foundation, Inc.
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
9 the Free Software Foundation; either version 3 of the License, or
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
18 along with this program; if not, see <http://www.gnu.org/licenses/>. */
19
20 #include "watchpoint-fork.h"
21
22 #include <assert.h>
23 #include <unistd.h>
24 #include <sys/wait.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <pthread.h>
28
29 #include <asm/unistd.h>
30 #include <unistd.h>
31 #define gettid() syscall (__NR_gettid)
32
33 /* Non-atomic `var++' should not hurt as we synchronize the threads by the STEP
34 variable. Hit-comments need to be duplicated there to catch both at-stops
35 and behind-stops, depending on the target. */
36
37 volatile int var;
38
39 void
40 marker (void)
41 {
42 }
43
44 static void
45 empty (void)
46 {
47 }
48
49 static void
50 mark_exit (void)
51 {
52 }
53
54 pthread_t thread;
55 volatile int step;
56
57 static void *
58 start (void *arg)
59 {
60 int i;
61
62 if (step >= 3)
63 goto step_3;
64
65 while (step != 1)
66 {
67 i = pthread_yield ();
68 assert (i == 0);
69 }
70
71 var++; /* validity-thread-B */
72 empty (); /* validity-thread-B */
73 step = 2;
74 while (step != 3)
75 {
76 if (step == 99)
77 goto step_99;
78
79 i = pthread_yield ();
80 assert (i == 0);
81 }
82
83 step_3:
84 if (step >= 5)
85 goto step_5;
86
87 var++; /* after-fork1-B */
88 empty (); /* after-fork1-B */
89 step = 4;
90 while (step != 5)
91 {
92 if (step == 99)
93 goto step_99;
94
95 i = pthread_yield ();
96 assert (i == 0);
97 }
98
99 step_5:
100 var++; /* after-fork2-B */
101 empty (); /* after-fork2-B */
102 return (void *) 5UL;
103
104 step_99:
105 /* We must not get caught here (against a forgotten breakpoint). */
106 var++;
107 marker ();
108 return (void *) 99UL;
109 }
110
111 int
112 main (void)
113 {
114 int i;
115 void *thread_result;
116
117 #if DEBUG
118 setbuf (stdout, NULL);
119 printf ("main: %d\n", (int) gettid ());
120 #endif
121
122 /* General hardware breakpoints and watchpoints validity. */
123 marker ();
124 var++; /* validity-first */
125 empty (); /* validity-first */
126
127 i = pthread_create (&thread, NULL, start, NULL);
128 assert (i == 0);
129
130 var++; /* validity-thread-A */
131 empty (); /* validity-thread-A */
132 step = 1;
133 while (step != 2)
134 {
135 i = pthread_yield ();
136 assert (i == 0);
137 }
138
139 /* Hardware watchpoints got disarmed here. */
140 forkoff (1);
141
142 var++; /* after-fork1-A */
143 empty (); /* after-fork1-A */
144 step = 3;
145 #ifdef FOLLOW_CHILD
146 /* Spawn new thread as it was deleted in the child of FORK. */
147 i = pthread_create (&thread, NULL, start, NULL);
148 assert (i == 0);
149 #endif
150 while (step != 4)
151 {
152 i = pthread_yield ();
153 assert (i == 0);
154 }
155
156 /* A sanity check for double hardware watchpoints removal. */
157 forkoff (2);
158
159 var++; /* after-fork2-A */
160 empty (); /* after-fork2-A */
161 step = 5;
162 #ifdef FOLLOW_CHILD
163 /* Spawn new thread as it was deleted in the child of FORK. */
164 i = pthread_create (&thread, NULL, start, NULL);
165 assert (i == 0);
166 #endif
167
168 i = pthread_join (thread, &thread_result);
169 assert (i == 0);
170 assert (thread_result == (void *) 5UL);
171
172 mark_exit ();
173 return 0;
174 }
This page took 0.037382 seconds and 4 git commands to generate.