merge from gcc
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.reverse / watch-reverse.c
CommitLineData
28d41a99
MS
1/* This testcase is part of GDB, the GNU debugger.
2
3 Copyright 2008, 2009
4 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include <stdio.h>
20#include <unistd.h>
21/*
22 * Since using watchpoints can be very slow, we have to take some pains to
23 * ensure that we don't run too long with them enabled or we run the risk
24 * of having the test timeout. To help avoid this, we insert some marker
25 * functions in the execution stream so we can set breakpoints at known
26 * locations, without worrying about invalidating line numbers by changing
27 * this file. We use null bodied functions are markers since gdb does
28 * not support breakpoints at labeled text points at this time.
29 *
30 * One place we need is a marker for when we start executing our tests
31 * instructions rather than any process startup code, so we insert one
32 * right after entering main(). Another is right before we finish, before
33 * we start executing any process termination code.
34 *
35 * Another problem we have to guard against, at least for the test
36 * suite, is that we need to ensure that the line that causes the
37 * watchpoint to be hit is still the current line when gdb notices
38 * the hit. Depending upon the specific code generated by the compiler,
39 * the instruction after the one that triggers the hit may be part of
40 * the same line or part of the next line. Thus we ensure that there
41 * are always some instructions to execute on the same line after the
42 * code that should trigger the hit.
43 */
44
45int count = -1;
46int ival1 = -1;
47int ival2 = -1;
48int ival3 = -1;
49int ival4 = -1;
50int ival5 = -1;
51char buf[10];
52struct foo
53{
54 int val;
55};
56struct foo struct1, struct2, *ptr1, *ptr2;
57
58int doread = 0;
59
60char *global_ptr;
61
62void marker1 ()
63{
64}
65
66void marker2 ()
67{
68}
69
70void marker4 ()
71{
72}
73
74void marker5 ()
75{
76}
77
78void marker6 ()
79{
80}
81
82#ifdef PROTOTYPES
83void recurser (int x)
84#else
85void recurser (x) int x;
86#endif
87{
88 int local_x;
89
90 if (x > 0)
91 recurser (x-1);
92 local_x = x;
93}
94
95void
96func2 ()
97{
98 int local_a;
99 static int static_b;
100
101 ival5++;
102 local_a = ival5;
103 static_b = local_a;
104}
105
106void
107func3 ()
108{
109 int x;
110 int y;
111
112 x = 0;
113 x = 1; /* second x assignment */
114 y = 1;
115 y = 2;
116}
117
118int
119func1 ()
120{
121 /* The point of this is that we will set a breakpoint at this call.
122
123 Then, if DECR_PC_AFTER_BREAK equals the size of a function call
124 instruction (true on a sun3 if this is gcc-compiled--FIXME we
125 should use asm() to make it work for any compiler, present or
126 future), then we will end up branching to the location just after
127 the breakpoint. And we better not confuse that with hitting the
128 breakpoint. */
129 func2 ();
130 return 73;
131}
132
133void
134func4 ()
135{
136 buf[0] = 3;
137 global_ptr = buf;
138 buf[0] = 7;
139}
140
141int main ()
142{
143#ifdef usestubs
144 set_debug_traps();
145 breakpoint();
146#endif
147 struct1.val = 1;
148 struct2.val = 2;
149 ptr1 = &struct1;
150 ptr2 = &struct2;
151 marker1 ();
152 func1 ();
153 for (count = 0; count < 4; count++) {
154 ival1 = count;
155 ival3 = count; ival4 = count;
156 }
157 ival1 = count; /* Outside loop */
158 ival2 = count;
159 ival3 = count; ival4 = count;
160 marker2 ();
161 if (doread)
162 {
163 static char msg[] = "type stuff for buf now:";
164 write (1, msg, sizeof (msg) - 1);
165 read (0, &buf[0], 5);
166 }
167 marker4 ();
168
169 /* We have a watchpoint on ptr1->val. It should be triggered if
170 ptr1's value changes. */
171 ptr1 = ptr2;
172
173 /* This should not trigger the watchpoint. If it does, then we
174 used the wrong value chain to re-insert the watchpoints or we
175 are not evaluating the watchpoint expression correctly. */
176 struct1.val = 5;
177 marker5 ();
178
179 /* We have a watchpoint on ptr1->val. It should be triggered if
180 ptr1's value changes. */
181 ptr1 = ptr2;
182
183 /* This should not trigger the watchpoint. If it does, then we
184 used the wrong value chain to re-insert the watchpoints or we
185 are not evaluating the watchpoint expression correctly. */
186 struct1.val = 5;
187 marker5 ();
188
189 /* We're going to watch locals of func2, to see that out-of-scope
190 watchpoints are detected and properly deleted.
191 */
192 marker6 ();
193
194 /* This invocation is used for watches of a single
195 local variable. */
196 func2 ();
197
198 /* This invocation is used for watches of an expression
199 involving a local variable. */
200 func2 ();
201
202 /* This invocation is used for watches of a static
203 (non-stack-based) local variable. */
204 func2 ();
205
206 /* This invocation is used for watches of a local variable
207 when recursion happens.
208 */
209 marker6 ();
210 recurser (2);
211
212 marker6 ();
213
214 func3 ();
215
216 func4 ();
217
218 return 0;
219}
This page took 0.0947170000000001 seconds and 4 git commands to generate.