]> Git Repo - binutils.git/blob - gdb/testsuite/gdb.threads/watchpoint-fork-mt.c
Automatic date update in version.in
[binutils.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-2022 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.037144 seconds and 4 git commands to generate.