]> git.pld-linux.org Git - packages/gdb.git/blob - gdb-6.6-multifork-debugreg.patch
- obsolete file
[packages/gdb.git] / gdb-6.6-multifork-debugreg.patch
1 http://sourceware.org/ml/gdb-patches/2008-01/msg00042.html
2 [ Backported for GDB-6.6 (only removed the new file inclusion). ]
3
4 +
5
6 2007-09-16  Daniel Jacobowitz  <dan@codesourcery.com>
7             Jeff Johnston  <jjohnstn@redhat.com>
8
9         * gdb.texinfo (Setting Watchpoints): Adjust warning text about
10         multi-threaded watchpoints.
11
12 2007-12-15  Jan Kratochvil  <jan.kratochvil@redhat.com>
13
14         * gdb.texinfo (Setting Watchpoints): New paragraph on the software
15         watchpoints safety wrt `set scheduler-locking'.
16
17 2008-03-01  Jan Kratochvil  <jan.kratochvil@redhat.com>
18
19         Port to GDB-6.8pre.
20
21 2008-03-31  Jan Kratochvil  <jan.kratochvil@redhat.com>
22
23         * gdb.threads/watchpoint-fork-forkoff.c (forkoff): New delay after the
24         parent/child messages to fix a race.
25
26 2008-05-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
27
28         * s390-nat.c (s390_fix_watch_points): Fix its compilation failure
29         - rename it to S390_FIX_WATCH_POINTS_LIST.
30
31 Index: gdb-6.8.50.20090209/gdb/amd64-linux-nat.c
32 ===================================================================
33 --- gdb-6.8.50.20090209.orig/gdb/amd64-linux-nat.c      2009-02-09 16:02:27.000000000 +0100
34 +++ gdb-6.8.50.20090209/gdb/amd64-linux-nat.c   2009-02-09 16:03:30.000000000 +0100
35 @@ -408,25 +408,43 @@ amd64_linux_dr_set (ptid_t ptid, int reg
36  void
37  amd64_linux_dr_set_control (unsigned long control)
38  {
39 -  struct lwp_info *lp;
40 -  ptid_t ptid;
41 -
42    amd64_linux_dr[DR_CONTROL] = control;
43 -  ALL_LWPS (lp, ptid)
44 -    amd64_linux_dr_set (ptid, DR_CONTROL, control);
45 +
46 +  /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
47 +     not listed for ALL_LWPS.  */
48 +
49 +  if (ptid_get_lwp (inferior_ptid) == 0)
50 +    amd64_linux_dr_set (inferior_ptid, DR_CONTROL, control);
51 +  else
52 +    {
53 +      struct lwp_info *lp;
54 +      ptid_t ptid;
55 +
56 +      ALL_LWPS (lp, ptid)
57 +       amd64_linux_dr_set (ptid, DR_CONTROL, control);
58 +    }
59  }
60  
61  void
62  amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
63  {
64 -  struct lwp_info *lp;
65 -  ptid_t ptid;
66 -
67    gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
68  
69    amd64_linux_dr[DR_FIRSTADDR + regnum] = addr;
70 -  ALL_LWPS (lp, ptid)
71 -    amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
72 +
73 +  /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
74 +     not listed for ALL_LWPS.  */
75 +
76 +  if (ptid_get_lwp (inferior_ptid) == 0)
77 +    amd64_linux_dr_set (inferior_ptid, DR_FIRSTADDR + regnum, addr);
78 +  else
79 +    {
80 +      struct lwp_info *lp;
81 +      ptid_t ptid;
82 +
83 +      ALL_LWPS (lp, ptid)
84 +       amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
85 +    }
86  }
87  
88  void
89 @@ -451,6 +469,41 @@ amd64_linux_new_thread (ptid_t ptid)
90  
91    amd64_linux_dr_set (ptid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
92  }
93 +
94 +/* TO_FOLLOW_FORK stores here the PID under DETACH_BREAKPOINTS for the child
95 +   process of traced FORK.  We must clear such watchpoints only once during
96 +   DETACH_BREAKPOINTS.  */
97 +
98 +static int amd64_linux_detach_breakpoints_pid;
99 +
100 +/* Remove a watchpoint that watched the memory region which starts at
101 +   address ADDR, whose length is LEN bytes, and for accesses of the
102 +   type TYPE.  Return 0 on success, -1 on failure.  */
103 +int
104 +amd64_linux_remove_watchpoint (CORE_ADDR addr, int len, int type)
105 +{
106 +  if (ptid_get_pid (inferior_ptid) == amd64_linux_detach_breakpoints_pid)
107 +    return 0;
108 +  /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions.  */
109 +  amd64_linux_detach_breakpoints_pid = 0;
110 +
111 +  return i386_remove_watchpoint (addr, len, type);
112 +}
113 +
114 +static void
115 +amd64_linux_detach_breakpoints (int detached_pid)
116 +{
117 +  struct cleanup *old_chain = save_inferior_ptid ();
118 +  int i;
119 +
120 +  amd64_linux_detach_breakpoints_pid = detached_pid;
121 +  /* Depend on `!is_lwp (inferior_ptid)' for the I386_* macros.  */
122 +  inferior_ptid = pid_to_ptid (detached_pid);
123 +
124 +  i386_detach_breakpoints (detached_pid);
125 +
126 +  do_cleanups (old_chain);
127 +}
128  \f
129  
130  /* This function is called by libthread_db as part of its handling of
131 @@ -755,6 +808,42 @@ amd64_linux_siginfo_fixup (struct siginf
132      return 0;
133  }
134  
135 +static int (*amd64_linux_super_follow_fork) (struct target_ops *ops,
136 +                                            int follow_child);
137 +
138 +/* We need to duplicate the LINUX_CHILD_FOLLOW_FORK behavior here and catch its
139 +   called DETACH_BREAKPOINTS to avoid corrupting our local registers mirror.  */
140 +
141 +static int
142 +amd64_linux_follow_fork (struct target_ops *ops, int follow_child)
143 +{
144 +  ptid_t last_ptid;
145 +  struct target_waitstatus last_status;
146 +  int has_vforked;
147 +  int parent_pid, child_pid;
148 +
149 +  get_last_target_status (&last_ptid, &last_status);
150 +  has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
151 +  parent_pid = ptid_get_lwp (last_ptid);
152 +  if (parent_pid == 0)
153 +    parent_pid = ptid_get_pid (last_ptid);
154 +  child_pid = ptid_get_lwp (last_status.value.related_pid);
155 +  if (child_pid == 0)
156 +    child_pid = ptid_get_pid (last_status.value.related_pid);
157 +
158 +  if (! follow_child)
159 +    {
160 +      amd64_linux_detach_breakpoints (child_pid);
161 +    }
162 +  else
163 +    {
164 +      if (! has_vforked)
165 +       amd64_linux_detach_breakpoints (child_pid);
166 +    }
167 +
168 +  return (*amd64_linux_super_follow_fork) (ops, follow_child);
169 +}
170 +
171  /* Provide a prototype to silence -Wmissing-prototypes.  */
172  void _initialize_amd64_linux_nat (void);
173  
174 @@ -791,6 +880,9 @@ _initialize_amd64_linux_nat (void)
175    linux_elfcore_write_prstatus = amd64_linux_elfcore_write_prstatus;
176    linux_elfcore_write_prfpreg = amd64_linux_elfcore_write_prfpreg;
177  
178 +  amd64_linux_super_follow_fork = t->to_follow_fork;
179 +  t->to_follow_fork = amd64_linux_follow_fork;
180 +
181    /* Register the target.  */
182    linux_nat_add_target (t);
183    linux_nat_set_new_thread (t, amd64_linux_new_thread);
184 Index: gdb-6.8.50.20090209/gdb/config/i386/nm-i386.h
185 ===================================================================
186 --- gdb-6.8.50.20090209.orig/gdb/config/i386/nm-i386.h  2009-01-03 06:57:54.000000000 +0100
187 +++ gdb-6.8.50.20090209/gdb/config/i386/nm-i386.h       2009-02-09 16:02:42.000000000 +0100
188 @@ -120,6 +120,8 @@ extern int i386_stopped_by_watchpoint (v
189  
190  #endif /* I386_WATCHPOINTS_IN_TARGET_VECTOR */
191  
192 +extern void i386_detach_breakpoints (int detached_pid);
193 +
194  #endif /* I386_USE_GENERIC_WATCHPOINTS */
195  
196  #endif /* NM_I386_H */
197 Index: gdb-6.8.50.20090209/gdb/i386-linux-nat.c
198 ===================================================================
199 --- gdb-6.8.50.20090209.orig/gdb/i386-linux-nat.c       2009-01-03 06:57:51.000000000 +0100
200 +++ gdb-6.8.50.20090209/gdb/i386-linux-nat.c    2009-02-09 16:02:42.000000000 +0100
201 @@ -634,21 +634,42 @@ i386_linux_dr_set_control (unsigned long
202    ptid_t ptid;
203  
204    i386_linux_dr[DR_CONTROL] = control;
205 -  ALL_LWPS (lp, ptid)
206 -    i386_linux_dr_set (ptid, DR_CONTROL, control);
207 +
208 +  /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
209 +     not listed for ALL_LWPS.  */
210 +
211 +  if (ptid_get_lwp (inferior_ptid) == 0)
212 +    i386_linux_dr_set (inferior_ptid, DR_CONTROL, control);
213 +  else
214 +    {
215 +      struct lwp_info *lp;
216 +      ptid_t ptid;
217 +
218 +      ALL_LWPS (lp, ptid)
219 +       i386_linux_dr_set (ptid, DR_CONTROL, control);
220 +    }
221  }
222  
223  void
224  i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
225  {
226 -  struct lwp_info *lp;
227 -  ptid_t ptid;
228 -
229    gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
230  
231    i386_linux_dr[DR_FIRSTADDR + regnum] = addr;
232 -  ALL_LWPS (lp, ptid)
233 -    i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
234 +
235 +  /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
236 +     not listed for ALL_LWPS.  */
237 +
238 +  if (ptid_get_lwp (inferior_ptid) == 0)
239 +    i386_linux_dr_set (inferior_ptid, DR_FIRSTADDR + regnum, addr);
240 +  else
241 +    {
242 +      struct lwp_info *lp;
243 +      ptid_t ptid;
244 +
245 +      ALL_LWPS (lp, ptid)
246 +       i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
247 +    }
248  }
249  
250  void
251 @@ -673,6 +694,41 @@ i386_linux_new_thread (ptid_t ptid)
252  
253    i386_linux_dr_set (ptid, DR_CONTROL, i386_linux_dr[DR_CONTROL]);
254  }
255 +
256 +/* TO_FOLLOW_FORK stores here the PID under DETACH_BREAKPOINTS for the child
257 +   process of traced FORK.  We must clear such watchpoints only once during
258 +   DETACH_BREAKPOINTS.  */
259 +
260 +static int i386_linux_detach_breakpoints_pid;
261 +
262 +/* Remove a watchpoint that watched the memory region which starts at
263 +   address ADDR, whose length is LEN bytes, and for accesses of the
264 +   type TYPE.  Return 0 on success, -1 on failure.  */
265 +int
266 +i386_linux_remove_watchpoint (CORE_ADDR addr, int len, int type)
267 +{
268 +  if (ptid_get_pid (inferior_ptid) == i386_linux_detach_breakpoints_pid)
269 +    return 0;
270 +  /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions.  */
271 +  i386_linux_detach_breakpoints_pid = 0;
272 +
273 +  return i386_remove_watchpoint (addr, len, type);
274 +}
275 +
276 +static void
277 +i386_linux_detach_breakpoints (int detached_pid)
278 +{
279 +  struct cleanup *old_chain = save_inferior_ptid ();
280 +  int i;
281 +
282 +  i386_linux_detach_breakpoints_pid = detached_pid;
283 +  /* Depend on `!is_lwp (inferior_ptid)' for the I386_* macros.  */
284 +  inferior_ptid = pid_to_ptid (detached_pid);
285 +
286 +  i386_detach_breakpoints (detached_pid);
287 +
288 +  do_cleanups (old_chain);
289 +}
290  \f
291  
292  /* Called by libthread_db.  Returns a pointer to the thread local
293 @@ -812,6 +868,40 @@ i386_linux_child_post_startup_inferior (
294    super_post_startup_inferior (ptid);
295  }
296  
297 +static int (*i386_linux_super_follow_fork) (struct target_ops *ops,
298 +                                           int follow_child);
299 +
300 +/* We need to duplicate the LINUX_CHILD_FOLLOW_FORK behavior here and catch its
301 +   called DETACH_BREAKPOINTS to avoid corrupting our local registers mirror.  */
302 +
303 +static int
304 +i386_linux_follow_fork (struct target_ops *ops, int follow_child)
305 +{
306 +  ptid_t last_ptid;
307 +  struct target_waitstatus last_status;
308 +  int has_vforked;
309 +  int parent_pid, child_pid;
310 +
311 +  get_last_target_status (&last_ptid, &last_status);
312 +  has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
313 +  parent_pid = ptid_get_lwp (last_ptid);
314 +  if (parent_pid == 0)
315 +    parent_pid = ptid_get_pid (last_ptid);
316 +  child_pid = ptid_get_pid (last_status.value.related_pid);
317 +
318 +  if (! follow_child)
319 +    {
320 +      i386_linux_detach_breakpoints (child_pid);
321 +    }
322 +  else
323 +    {
324 +      if (! has_vforked)
325 +       i386_linux_detach_breakpoints (child_pid);
326 +    }
327 +
328 +  return (*i386_linux_super_follow_fork) (ops, follow_child);
329 +}
330 +
331  void
332  _initialize_i386_linux_nat (void)
333  {
334 @@ -833,6 +923,9 @@ _initialize_i386_linux_nat (void)
335    t->to_fetch_registers = i386_linux_fetch_inferior_registers;
336    t->to_store_registers = i386_linux_store_inferior_registers;
337  
338 +  i386_linux_super_follow_fork = t->to_follow_fork;
339 +  t->to_follow_fork = i386_linux_follow_fork;
340 +
341    /* Register the target.  */
342    linux_nat_add_target (t);
343    linux_nat_set_new_thread (t, i386_linux_new_thread);
344 Index: gdb-6.8.50.20090209/gdb/i386-nat.c
345 ===================================================================
346 --- gdb-6.8.50.20090209.orig/gdb/i386-nat.c     2009-01-03 06:57:51.000000000 +0100
347 +++ gdb-6.8.50.20090209/gdb/i386-nat.c  2009-02-09 16:02:42.000000000 +0100
348 @@ -546,6 +546,17 @@ i386_remove_watchpoint (CORE_ADDR addr, 
349    return retval;
350  }
351  
352 +void
353 +i386_detach_breakpoints (int detached_pid)
354 +{
355 +  int i;
356 +
357 +  /* Do not touch any DR_MIRROR or DR_CONTROL_MIRROR mirrors here.  */
358 +  I386_DR_LOW_SET_CONTROL (0);
359 +  ALL_DEBUG_REGISTERS(i)
360 +    I386_DR_LOW_RESET_ADDR (i);
361 +}
362 +
363  /* Return non-zero if we can watch a memory region that starts at
364     address ADDR and whose length is LEN bytes.  */
365  
366 Index: gdb-6.8.50.20090209/gdb/ia64-linux-nat.c
367 ===================================================================
368 --- gdb-6.8.50.20090209.orig/gdb/ia64-linux-nat.c       2009-02-09 15:48:43.000000000 +0100
369 +++ gdb-6.8.50.20090209/gdb/ia64-linux-nat.c    2009-02-09 16:02:42.000000000 +0100
370 @@ -583,6 +583,12 @@ ia64_linux_insert_watchpoint (CORE_ADDR 
371    return 0;
372  }
373  
374 +/* TO_FOLLOW_FORK stores here the PID under DETACH_BREAKPOINTS for the child
375 +   process of traced FORK.  We must clear such watchpoints only once during
376 +   DETACH_BREAKPOINTS.  */
377 +
378 +static int ia64_linux_detach_breakpoints_pid;
379 +
380  static int
381  ia64_linux_remove_watchpoint (CORE_ADDR addr, int len, int type)
382  {
383 @@ -590,6 +596,11 @@ ia64_linux_remove_watchpoint (CORE_ADDR 
384    long dbr_addr, dbr_mask;
385    int max_watchpoints = 4;
386  
387 +  if (ptid_get_pid (inferior_ptid) == ia64_linux_detach_breakpoints_pid)
388 +    return 0;
389 +  /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions.  */
390 +  ia64_linux_detach_breakpoints_pid = 0;
391 +
392    if (len <= 0 || !is_power_of_2 (len))
393      return -1;
394  
395 @@ -617,6 +628,22 @@ ia64_linux_remove_watchpoint (CORE_ADDR 
396  }
397  
398  static void
399 +ia64_linux_detach_breakpoints (int detached_pid)
400 +{
401 +  int idx, i;
402 +  long dbr_addr, dbr_mask;
403 +  int max_watchpoints = 4;
404 +
405 +  ia64_linux_detach_breakpoints_pid = detached_pid;
406 +
407 +  /* Do not touch any DEBUG_REGISTERS mirrors here.  */
408 +  dbr_addr = 0;
409 +  dbr_mask = 0;
410 +  for (idx = 0; idx < max_watchpoints; idx++)
411 +    store_debug_register_pair (ptid_build (detached_pid, 0, 0), idx, &dbr_addr, &dbr_mask);
412 +}
413 +
414 +static void
415  ia64_linux_new_thread (ptid_t ptid)
416  {
417    int i, any;
418 @@ -805,6 +832,40 @@ ia64_linux_xfer_partial (struct target_o
419                              offset, len);
420  }
421  
422 +static int (*ia64_linux_super_follow_fork) (struct target_ops *ops,
423 +                                           int follow_child);
424 +
425 +/* We need to duplicate the LINUX_CHILD_FOLLOW_FORK behavior here and catch its
426 +   called DETACH_BREAKPOINTS to avoid corrupting our local registers mirror.  */
427 +
428 +int
429 +ia64_linux_follow_fork (struct target_ops *ops, int follow_child)
430 +{
431 +  ptid_t last_ptid;
432 +  struct target_waitstatus last_status;
433 +  int has_vforked;
434 +  int parent_pid, child_pid;
435 +
436 +  get_last_target_status (&last_ptid, &last_status);
437 +  has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
438 +  parent_pid = ptid_get_lwp (last_ptid);
439 +  if (parent_pid == 0)
440 +    parent_pid = ptid_get_pid (last_ptid);
441 +  child_pid = ptid_get_pid (last_status.value.related_pid);
442 +
443 +  if (! follow_child)
444 +    {
445 +      ia64_linux_detach_breakpoints (child_pid);
446 +    }
447 +  else
448 +    {
449 +      if (! has_vforked)
450 +       ia64_linux_detach_breakpoints (child_pid);
451 +    }
452 +
453 +  return (*ia64_linux_super_follow_fork) (ops, follow_child);
454 +}
455 +
456  void _initialize_ia64_linux_nat (void);
457  
458  /*
459 @@ -899,6 +960,9 @@ _initialize_ia64_linux_nat (void)
460    t->to_insert_watchpoint = ia64_linux_insert_watchpoint;
461    t->to_remove_watchpoint = ia64_linux_remove_watchpoint;
462  
463 +  ia64_linux_super_follow_fork = t->to_follow_fork;
464 +  t->to_follow_fork = ia64_linux_follow_fork;
465 +
466    /* Register the target.  */
467    linux_nat_add_target (t);
468    linux_nat_set_new_thread (t, ia64_linux_new_thread);
469 Index: gdb-6.8.50.20090209/gdb/ppc-linux-nat.c
470 ===================================================================
471 --- gdb-6.8.50.20090209.orig/gdb/ppc-linux-nat.c        2009-01-03 06:57:52.000000000 +0100
472 +++ gdb-6.8.50.20090209/gdb/ppc-linux-nat.c     2009-02-09 16:02:42.000000000 +0100
473 @@ -1118,6 +1118,12 @@ ppc_linux_insert_watchpoint (CORE_ADDR a
474    return 0;
475  }
476  
477 +/* TO_FOLLOW_FORK stores here the PID under DETACH_BREAKPOINTS for the child
478 +   process of traced FORK.  We must clear such watchpoints only once during
479 +   DETACH_BREAKPOINTS.  */
480 +
481 +static int ppc_linux_detach_breakpoints_pid;
482 +
483  static int
484  ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw)
485  {
486 @@ -1125,6 +1131,11 @@ ppc_linux_remove_watchpoint (CORE_ADDR a
487    ptid_t ptid;
488    long dabr_value = 0;
489  
490 +  if (ptid_get_pid (inferior_ptid) == ppc_linux_detach_breakpoints_pid)
491 +    return 0;
492 +  /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions.  */
493 +  ppc_linux_detach_breakpoints_pid = 0;
494 +
495    saved_dabr_value = 0;
496    ALL_LWPS (lp, ptid)
497      if (ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value) < 0)
498 @@ -1138,6 +1149,15 @@ ppc_linux_new_thread (ptid_t ptid)
499    ptrace (PTRACE_SET_DEBUGREG, TIDGET (ptid), 0, saved_dabr_value);
500  }
501  
502 +static void
503 +ppc_linux_detach_breakpoints (int detached_pid)
504 +{
505 +  ppc_linux_detach_breakpoints_pid = detached_pid;
506 +
507 +  /* Do not touch the SAVED_DABR_VALUE mirror here.  */
508 +  ptrace (PTRACE_SET_DEBUGREG, detached_pid, 0, 0);
509 +}
510 +
511  static int
512  ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
513  {
514 @@ -1318,6 +1338,40 @@ ppc_linux_read_description (struct targe
515    return isa205? tdesc_powerpc_isa205_32l : tdesc_powerpc_32l;
516  }
517  
518 +static int (*ppc_linux_super_follow_fork) (struct target_ops *ops,
519 +                                          int follow_child);
520 +
521 +/* We need to duplicate the LINUX_CHILD_FOLLOW_FORK behavior here and catch its
522 +   called DETACH_BREAKPOINTS to avoid corrupting our local registers mirror.  */
523 +
524 +int
525 +ppc_linux_follow_fork (struct target_ops *ops, int follow_child)
526 +{
527 +  ptid_t last_ptid;
528 +  struct target_waitstatus last_status;
529 +  int has_vforked;
530 +  int parent_pid, child_pid;
531 +
532 +  get_last_target_status (&last_ptid, &last_status);
533 +  has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
534 +  parent_pid = ptid_get_lwp (last_ptid);
535 +  if (parent_pid == 0)
536 +    parent_pid = ptid_get_pid (last_ptid);
537 +  child_pid = ptid_get_pid (last_status.value.related_pid);
538 +
539 +  if (! follow_child)
540 +    {
541 +      ppc_linux_detach_breakpoints (child_pid);
542 +    }
543 +  else
544 +    {
545 +      if (! has_vforked)
546 +       ppc_linux_detach_breakpoints (child_pid);
547 +    }
548 +
549 +  return (*ppc_linux_super_follow_fork) (ops, follow_child);
550 +}
551 +
552  void _initialize_ppc_linux_nat (void);
553  
554  void
555 @@ -1343,6 +1397,9 @@ _initialize_ppc_linux_nat (void)
556  
557    t->to_read_description = ppc_linux_read_description;
558  
559 +  ppc_linux_super_follow_fork = t->to_follow_fork;
560 +  t->to_follow_fork = ppc_linux_follow_fork;
561 +
562    /* Register the target.  */
563    linux_nat_add_target (t);
564    linux_nat_set_new_thread (t, ppc_linux_new_thread);
565 Index: gdb-6.8.50.20090209/gdb/s390-nat.c
566 ===================================================================
567 --- gdb-6.8.50.20090209.orig/gdb/s390-nat.c     2007-11-07 07:36:57.000000000 +0100
568 +++ gdb-6.8.50.20090209/gdb/s390-nat.c  2009-02-09 16:02:42.000000000 +0100
569 @@ -283,21 +283,15 @@ s390_stopped_by_watchpoint (void)
570  }
571  
572  static void
573 -s390_fix_watch_points (ptid_t ptid)
574 +s390_fix_watch_points_list (int tid, struct watch_area *area_list)
575  {
576 -  int tid;
577 -
578    per_struct per_info;
579    ptrace_area parea;
580  
581    CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
582    struct watch_area *area;
583  
584 -  tid = TIDGET (ptid);
585 -  if (tid == 0)
586 -    tid = PIDGET (ptid);
587 -
588 -  for (area = watch_base; area; area = area->next)
589 +  for (area = area_list; area; area = area->next)
590      {
591        watch_lo_addr = min (watch_lo_addr, area->lo_addr);
592        watch_hi_addr = max (watch_hi_addr, area->hi_addr);
593 @@ -309,7 +303,7 @@ s390_fix_watch_points (ptid_t ptid)
594    if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0)
595      perror_with_name (_("Couldn't retrieve watchpoint status"));
596  
597 -  if (watch_base)
598 +  if (area_list)
599      {
600        per_info.control_regs.bits.em_storage_alteration = 1;
601        per_info.control_regs.bits.storage_alt_space_ctl = 1;
602 @@ -326,6 +320,18 @@ s390_fix_watch_points (ptid_t ptid)
603      perror_with_name (_("Couldn't modify watchpoint status"));
604  }
605  
606 +static void
607 +s390_fix_watch_points (ptid_t ptid)
608 +{
609 +  int tid;
610 +
611 +  tid = TIDGET (ptid);
612 +  if (tid == 0)
613 +    tid = PIDGET (ptid);
614 +
615 +  s390_fix_watch_points_list (tid, watch_base);
616 +}
617 +
618  static int
619  s390_insert_watchpoint (CORE_ADDR addr, int len, int type)
620  {
621 @@ -347,6 +353,12 @@ s390_insert_watchpoint (CORE_ADDR addr, 
622    return 0;
623  }
624  
625 +/* TO_FOLLOW_FORK stores here the PID under DETACH_BREAKPOINTS for the child
626 +   process of traced FORK.  We must clear such watchpoints only once during
627 +   DETACH_BREAKPOINTS.  */
628 +
629 +static int s390_detach_breakpoints_pid;
630 +
631  static int
632  s390_remove_watchpoint (CORE_ADDR addr, int len, int type)
633  {
634 @@ -354,6 +366,11 @@ s390_remove_watchpoint (CORE_ADDR addr, 
635    ptid_t ptid;
636    struct watch_area *area, **parea;
637  
638 +  if (ptid_get_pid (inferior_ptid) == s390_detach_breakpoints_pid)
639 +    return 0;
640 +  /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions.  */
641 +  s390_detach_breakpoints_pid = 0;
642 +
643    for (parea = &watch_base; *parea; parea = &(*parea)->next)
644      if ((*parea)->lo_addr == addr
645         && (*parea)->hi_addr == addr + len - 1)
646 @@ -361,8 +378,10 @@ s390_remove_watchpoint (CORE_ADDR addr, 
647  
648    if (!*parea)
649      {
650 +#if 0 /* Red Hat fork/threads watchpoints changes may trigger it.  */
651        fprintf_unfiltered (gdb_stderr,
652                           "Attempt to remove nonexistent watchpoint.\n");
653 +#endif
654        return -1;
655      }
656  
657 @@ -375,6 +394,15 @@ s390_remove_watchpoint (CORE_ADDR addr, 
658    return 0;
659  }
660  
661 +static void
662 +s390_detach_breakpoints (int detached_pid)
663 +{
664 +  s390_detach_breakpoints_pid = detached_pid;
665 +
666 +  /* Do not touch the WATCH_BASE here.  */
667 +  s390_fix_watch_points_list (detached_pid, NULL);
668 +}
669 +
670  static int
671  s390_can_use_hw_breakpoint (int type, int cnt, int othertype)
672  {
673 @@ -387,6 +415,39 @@ s390_region_ok_for_hw_watchpoint (CORE_A
674    return 1;
675  }
676  
677 +static int (*s390_super_follow_fork) (struct target_ops *ops, int follow_child);
678 +
679 +/* We need to duplicate the LINUX_CHILD_FOLLOW_FORK behavior here and catch its
680 +   called DETACH_BREAKPOINTS to avoid corrupting our local registers mirror.  */
681 +
682 +int
683 +s390_follow_fork (struct target_ops *ops, int follow_child)
684 +{
685 +  ptid_t last_ptid;
686 +  struct target_waitstatus last_status;
687 +  int has_vforked;
688 +  int parent_pid, child_pid;
689 +
690 +  get_last_target_status (&last_ptid, &last_status);
691 +  has_vforked = (last_status.kind == TARGET_WAITKIND_VFORKED);
692 +  parent_pid = ptid_get_lwp (last_ptid);
693 +  if (parent_pid == 0)
694 +    parent_pid = ptid_get_pid (last_ptid);
695 +  child_pid = ptid_get_pid (last_status.value.related_pid);
696 +
697 +  if (! follow_child)
698 +    {
699 +      s390_detach_breakpoints (child_pid);
700 +    }
701 +  else
702 +    {
703 +      if (! has_vforked)
704 +       s390_detach_breakpoints (child_pid);
705 +    }
706 +
707 +  return (*s390_super_follow_fork) (ops, follow_child);
708 +}
709 +
710  
711  void _initialize_s390_nat (void);
712  
713 @@ -410,6 +471,9 @@ _initialize_s390_nat (void)
714    t->to_insert_watchpoint = s390_insert_watchpoint;
715    t->to_remove_watchpoint = s390_remove_watchpoint;
716  
717 +  s390_super_follow_fork = t->to_follow_fork;
718 +  t->to_follow_fork = s390_follow_fork;
719 +
720    /* Register the target.  */
721    linux_nat_add_target (t);
722    linux_nat_set_new_thread (t, s390_fix_watch_points);
723 Index: gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c
724 ===================================================================
725 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
726 +++ gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork-forkoff.c     2009-02-09 16:02:42.000000000 +0100
727 @@ -0,0 +1,172 @@
728 +/* Test case for forgotten hw-watchpoints after fork()-off of a process.
729 +
730 +   Copyright 2008
731 +   Free Software Foundation, Inc.
732 +
733 +   This file is part of GDB.
734 +
735 +   This program is free software; you can redistribute it and/or modify
736 +   it under the terms of the GNU General Public License as published by
737 +   the Free Software Foundation; either version 2 of the License, or
738 +   (at your option) any later version.
739 +
740 +   This program is distributed in the hope that it will be useful,
741 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
742 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
743 +   GNU General Public License for more details.
744 +
745 +   You should have received a copy of the GNU General Public License
746 +   along with this program; if not, write to the Free Software
747 +   Foundation, Inc., 59 Temple Place - Suite 330,
748 +   Boston, MA 02111-1307, USA.  */
749 +
750 +#include <string.h>
751 +#include <errno.h>
752 +
753 +static void delay (void)
754 +{
755 +  int i = usleep (1000000 / 100);
756 +  assert (i == 0 || errno == EINTR);
757 +}
758 +
759 +#if defined FOLLOW_PARENT
760 +
761 +static void forkoff (int nr)
762 +{
763 +  pid_t child, pid_got;
764 +  int exit_code = 42 + nr;
765 +  int status, i;
766 +
767 +  child = fork ();
768 +  switch (child)
769 +    {
770 +    case -1:
771 +      assert (0);
772 +    case 0:
773 +      printf ("child%d: %d\n", nr, (int) getpid ());
774 +      /* Delay to get both the "child%d" and "parent%d" message printed without
775 +        a race breaking expect by its endless wait on `$gdb_prompt$':
776 +        Breakpoint 3, breakpoint () at ../../../gdb/testsuite/gdb.threads/watchpoint-fork.c:33
777 +        33      }
778 +        (gdb) parent2: 14223  */
779 +      i = sleep (1);
780 +      assert (i == 0);
781 +
782 +      /* We must not get caught here (against a forgotten breakpoint).  */
783 +      var++;
784 +      breakpoint ();
785 +
786 +      _exit (exit_code);
787 +    default:
788 +      printf ("parent%d: %d\n", nr, (int) child);
789 +      /* Delay to get both the "child%d" and "parent%d" message printed, see
790 +        above.  */
791 +      i = sleep (1);
792 +      assert (i == 0);
793 +
794 +      pid_got = wait (&status);
795 +      assert (pid_got == child);
796 +      assert (WIFEXITED (status));
797 +      assert (WEXITSTATUS (status) == exit_code);
798 +
799 +      /* We must get caught here (against a false watchpoint removal).  */
800 +      breakpoint ();
801 +    }
802 +}
803 +
804 +#elif defined FOLLOW_CHILD
805 +
806 +static volatile int usr1_got;
807 +
808 +static void handler_usr1 (int signo)
809 +{
810 +  usr1_got++;
811 +}
812 +
813 +static void forkoff (int nr)
814 +{
815 +  pid_t child;
816 +  int i, loop;
817 +  struct sigaction act, oldact;
818 +#ifdef THREAD
819 +  void *thread_result;
820 +#endif
821 +
822 +  memset (&act, 0, sizeof act);
823 +  act.sa_flags = SA_RESTART;
824 +  act.sa_handler = handler_usr1;
825 +  sigemptyset (&act.sa_mask);
826 +  i = sigaction (SIGUSR1, &act, &oldact);
827 +  assert (i == 0);
828 +
829 +  child = fork ();
830 +  switch (child)
831 +    {
832 +    case -1:
833 +      assert (0);
834 +    default:
835 +      printf ("parent%d: %d\n", nr, (int) child);
836 +
837 +      /* Sleep for a while to possibly get incorrectly ATTACH_THREADed by GDB
838 +         tracing the child fork with no longer valid thread/lwp entries of the
839 +         parent.  */
840 +
841 +      i = sleep (2);
842 +      assert (i == 0);
843 +
844 +      /* We must not get caught here (against a forgotten breakpoint).  */
845 +
846 +      var++;
847 +      breakpoint ();
848 +
849 +#ifdef THREAD
850 +      /* And neither got caught our thread.  */
851 +
852 +      step = 99;
853 +      i = pthread_join (thread, &thread_result);
854 +      assert (i == 0);
855 +      assert (thread_result == (void *) 99UL);
856 +#endif
857 +
858 +      /* Be sure our child knows we did not get caught above.  */
859 +
860 +      i = kill (child, SIGUSR1);
861 +      assert (i == 0);
862 +
863 +      /* Sleep for a while to check GDB's `info threads' no longer tracks us in
864 +         the child fork.  */
865 +
866 +      i = sleep (2);
867 +      assert (i == 0);
868 +
869 +      _exit (0);
870 +    case 0:
871 +      printf ("child%d: %d\n", nr, (int) getpid ());
872 +
873 +      /* Let the parent signal us about its success.  Be careful of races.  */
874 +
875 +      for (loop = 0; loop < 1000; loop++)
876 +        {
877 +         /* Parent either died (and USR1_GOT is zero) or it succeeded.  */
878 +         if (kill (getppid (), 0) != 0)
879 +           break;
880 +         /* Parent succeeded?  */
881 +         if (usr1_got)
882 +           break;
883 +
884 +         delay ();
885 +       }
886 +      assert (usr1_got);
887 +
888 +      /* We must get caught here (against a false watchpoint removal).  */
889 +
890 +      breakpoint ();
891 +    }
892 +
893 +  i = sigaction (SIGUSR1, &oldact, NULL);
894 +  assert (i == 0);
895 +}
896 +
897 +#else
898 +# error "!FOLLOW_PARENT && !FOLLOW_CHILD"
899 +#endif
900 Index: gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c
901 ===================================================================
902 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
903 +++ gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork-mt.c  2009-02-09 16:02:42.000000000 +0100
904 @@ -0,0 +1,154 @@
905 +/* Test case for forgotten hw-watchpoints after fork()-off of a process.
906 +
907 +   Copyright 2008
908 +   Free Software Foundation, Inc.
909 +
910 +   This file is part of GDB.
911 +
912 +   This program is free software; you can redistribute it and/or modify
913 +   it under the terms of the GNU General Public License as published by
914 +   the Free Software Foundation; either version 2 of the License, or
915 +   (at your option) any later version.
916 +
917 +   This program is distributed in the hope that it will be useful,
918 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
919 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
920 +   GNU General Public License for more details.
921 +
922 +   You should have received a copy of the GNU General Public License
923 +   along with this program; if not, write to the Free Software
924 +   Foundation, Inc., 59 Temple Place - Suite 330,
925 +   Boston, MA 02111-1307, USA.  */
926 +
927 +#include <assert.h>
928 +#include <unistd.h>
929 +#include <sys/wait.h>
930 +#include <stdio.h>
931 +#include <stdlib.h>
932 +#include <pthread.h>
933 +
934 +#include <asm/unistd.h>
935 +#include <unistd.h>
936 +#define gettid() syscall (__NR_gettid)
937 +
938 +/* Non-atomic `var++' should not hurt as we synchronize the threads by the STEP
939 +   variable.  Hit-comments need to be duplicite there to catch both at-stops
940 +   and behind-stops, depending on the target.  */
941 +
942 +static volatile int var;
943 +
944 +static void dummy (void)
945 +{
946 +}
947 +
948 +static void breakpoint (void)
949 +{
950 +}
951 +
952 +/* Include here the functions:
953 +   static void forkoff (int nr);
954 +   static void delay (void);  */
955 +
956 +static pthread_t thread;
957 +static volatile int step;
958 +#define THREAD
959 +
960 +#include "watchpoint-fork-forkoff.c"
961 +
962 +static void *start (void *arg)
963 +{
964 +  if (step >= 3)
965 +    goto step_3;
966 +
967 +  while (step != 1)
968 +    delay ();
969 +
970 +  var++;       /* validity-thread-B */
971 +  dummy ();    /* validity-thread-B */
972 +  step = 2;
973 +  while (step != 3)
974 +    {
975 +      if (step == 99)
976 +        goto step_99;
977 +      delay ();
978 +    }
979 +
980 +step_3:
981 +  if (step >= 5)
982 +    goto step_5;
983 +
984 +  var++;       /* after-fork1-B */
985 +  dummy ();    /* after-fork1-B */
986 +  step = 4;
987 +  while (step != 5)
988 +    {
989 +      if (step == 99)
990 +        goto step_99;
991 +      delay ();
992 +    }
993 +
994 +step_5:
995 +  var++;       /* after-fork2-B */
996 +  dummy ();    /* after-fork2-B */
997 +  return (void *) 5UL;
998 +
999 +step_99:
1000 +  /* We must not get caught here (against a forgotten breakpoint).  */
1001 +  var++;
1002 +  breakpoint ();
1003 +  return (void *) 99UL;
1004 +}
1005 +
1006 +int main (void)
1007 +{
1008 +  int i;
1009 +  void *thread_result;
1010 +
1011 +  setbuf (stdout, NULL);
1012 +  printf ("main: %d\n", (int) gettid ());
1013 +
1014 +  /* General watchpoints validity.  */
1015 +  var++;       /* validity-first */
1016 +  dummy ();    /* validity-first */
1017 +
1018 +  i = pthread_create (&thread, NULL, start, NULL);
1019 +  assert (i == 0);
1020 +
1021 +  var++;       /* validity-thread-A */
1022 +  dummy ();    /* validity-thread-A */
1023 +  step = 1;
1024 +  while (step != 2)
1025 +    delay ();
1026 +
1027 +  /* Hardware watchpoints got disarmed here.  */
1028 +  forkoff (1);
1029 +
1030 +  var++;       /* after-fork1-A */
1031 +  dummy ();    /* after-fork1-A */
1032 +  step = 3;
1033 +#ifdef FOLLOW_CHILD
1034 +  /* Spawn new thread as it was deleted in the child of FORK.  */
1035 +  i = pthread_create (&thread, NULL, start, NULL);
1036 +  assert (i == 0);
1037 +#endif
1038 +  while (step != 4)
1039 +    delay ();
1040 +
1041 +  /* A sanity check for double hardware watchpoints removal.  */
1042 +  forkoff (2);
1043 +
1044 +  var++;       /* after-fork2-A */
1045 +  dummy ();    /* after-fork2-A */
1046 +  step = 5;
1047 +#ifdef FOLLOW_CHILD
1048 +  /* Spawn new thread as it was deleted in the child of FORK.  */
1049 +  i = pthread_create (&thread, NULL, start, NULL);
1050 +  assert (i == 0);
1051 +#endif
1052 +
1053 +  i = pthread_join (thread, &thread_result);
1054 +  assert (i == 0);
1055 +  assert (thread_result == (void *) 5UL);
1056 +
1057 +  return 0;
1058 +}
1059 Index: gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork.c
1060 ===================================================================
1061 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
1062 +++ gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork.c     2009-02-09 16:02:42.000000000 +0100
1063 @@ -0,0 +1,56 @@
1064 +/* Test case for forgotten hw-watchpoints after fork()-off of a process.
1065 +
1066 +   Copyright 2008
1067 +   Free Software Foundation, Inc.
1068 +
1069 +   This file is part of GDB.
1070 +
1071 +   This program is free software; you can redistribute it and/or modify
1072 +   it under the terms of the GNU General Public License as published by
1073 +   the Free Software Foundation; either version 2 of the License, or
1074 +   (at your option) any later version.
1075 +
1076 +   This program is distributed in the hope that it will be useful,
1077 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
1078 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1079 +   GNU General Public License for more details.
1080 +
1081 +   You should have received a copy of the GNU General Public License
1082 +   along with this program; if not, write to the Free Software
1083 +   Foundation, Inc., 59 Temple Place - Suite 330,
1084 +   Boston, MA 02111-1307, USA.  */
1085 +
1086 +#include <assert.h>
1087 +#include <unistd.h>
1088 +#include <sys/wait.h>
1089 +#include <stdio.h>
1090 +#include <stdlib.h>
1091 +
1092 +static volatile int var;
1093 +
1094 +static void breakpoint (void)
1095 +{
1096 +}
1097 +
1098 +/* Include here the function:
1099 +   static void forkoff (int nr);  */
1100 +
1101 +#include "watchpoint-fork-forkoff.c"
1102 +
1103 +int main (void)
1104 +{
1105 +  setbuf (stdout, NULL);
1106 +  printf ("main: %d\n", (int) getpid ());
1107 +
1108 +  /* General watchpoints validity.  */
1109 +  var++;
1110 +  /* Hardware watchpoints got disarmed here.  */
1111 +  forkoff (1);
1112 +  /* This watchpoint got lost before.  */
1113 +  var++;
1114 +  /* A sanity check for double hardware watchpoints removal.  */
1115 +  forkoff (2);
1116 +  var++;
1117 +
1118 +  return 0;
1119 +}
1120 Index: gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork.exp
1121 ===================================================================
1122 --- /dev/null   1970-01-01 00:00:00.000000000 +0000
1123 +++ gdb-6.8.50.20090209/gdb/testsuite/gdb.threads/watchpoint-fork.exp   2009-02-09 16:02:42.000000000 +0100
1124 @@ -0,0 +1,140 @@
1125 +# Copyright 2008 Free Software Foundation, Inc.
1126 +
1127 +# This program is free software; you can redistribute it and/or modify
1128 +# it under the terms of the GNU General Public License as published by
1129 +# the Free Software Foundation; either version 3 of the License, or
1130 +# (at your option) any later version.
1131 +#
1132 +# This program is distributed in the hope that it will be useful,
1133 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1134 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1135 +# GNU General Public License for more details.
1136 +#
1137 +# You should have received a copy of the GNU General Public License
1138 +# along with this program.  If not, see <http://www.gnu.org/licenses/>.
1139 +
1140 +# Test case for forgotten hw-watchpoints after fork()-off of a process.
1141 +
1142 +proc test {type symbol} {
1143 +    global objdir subdir srcdir
1144 +
1145 +    global pf_prefix
1146 +    set prefix_test $pf_prefix
1147 +    lappend pf_prefix "$type:"
1148 +    set prefix_mt $pf_prefix
1149 +
1150 +    # no threads
1151 +
1152 +    set pf_prefix $prefix_mt
1153 +    lappend pf_prefix "singlethreaded:"
1154 +
1155 +    set testfile watchpoint-fork
1156 +    set srcfile ${testfile}.c
1157 +    set binfile ${objdir}/${subdir}/${testfile}
1158 +
1159 +    if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug additional_flags=-D$symbol"] != "" } {
1160 +       untested "Couldn't compile test program"
1161 +       return -1
1162 +    }
1163 +
1164 +    gdb_exit
1165 +    gdb_start
1166 +    gdb_reinitialize_dir $srcdir/$subdir
1167 +    gdb_load ${binfile}
1168 +
1169 +    gdb_test "set follow-fork-mode $type"
1170 +    # Testcase uses it for the `follow-fork-mode child' type.
1171 +    gdb_test "handle SIGUSR1 nostop noprint pass"
1172 +
1173 +    if { ![runto_main] } then {
1174 +       gdb_suppress_tests
1175 +       return
1176 +    }
1177 +
1178 +    # Install the watchpoint only after getting into MAIN - workaround some PPC
1179 +    # problem.
1180 +    gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint"
1181 +
1182 +    # It is never hit but it should not be left over in the fork()ed-off child.
1183 +    gdb_breakpoint "breakpoint"
1184 +
1185 +    gdb_test "continue" \
1186 +            "atchpoint 2: var.*Old value = 0.*New value = 1.*forkoff *\\(1\\).*" "watchpoints work"
1187 +    gdb_test "continue" \
1188 +            "reakpoint 3, breakpoint.*" "breakpoint after the first fork"
1189 +    gdb_test "continue" \
1190 +            "atchpoint 2: var.*Old value = 1.*New value = 2.*forkoff *\\(2\\).*" "watchpoint after the first fork"
1191 +    gdb_test "continue" \
1192 +            "reakpoint 3, breakpoint.*" "breakpoint after the second fork"
1193 +    gdb_test "continue" \
1194 +            "atchpoint 2: var.*Old value = 2.*New value = 3.*return *0;" "watchpoint after the second fork"
1195 +    gdb_test "continue" "Continuing..*Program exited normally." "finish"
1196 +
1197 +
1198 +    # threads
1199 +
1200 +    set pf_prefix $prefix_mt
1201 +    lappend pf_prefix "multithreaded:"
1202 +
1203 +    set testfile watchpoint-fork-mt
1204 +    set srcfile ${testfile}.c
1205 +    set binfile ${objdir}/${subdir}/${testfile}
1206 +
1207 +    if  { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug additional_flags=-D$symbol"] != "" } {
1208 +       untested "Couldn't compile test program"
1209 +       return -1
1210 +    }
1211 +
1212 +    gdb_exit
1213 +    gdb_start
1214 +    gdb_reinitialize_dir $srcdir/$subdir
1215 +    gdb_load ${binfile}
1216 +
1217 +    gdb_test "set follow-fork-mode $type"
1218 +    # Testcase uses it for the `follow-fork-mode child' type.
1219 +    gdb_test "handle SIGUSR1 nostop noprint pass"
1220 +
1221 +    if { ![runto_main] } then {
1222 +       gdb_suppress_tests
1223 +       return
1224 +    }
1225 +
1226 +    # Install the watchpoint only after getting into MAIN - workaround some PPC
1227 +    # problem.
1228 +    gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint"
1229 +
1230 +    # It is never hit but it should not be left over in the fork()ed-off child.
1231 +    gdb_breakpoint "breakpoint"
1232 +
1233 +    gdb_test "continue" \
1234 +            "atchpoint 2: var.*Old value = 0.*New value = 1.*validity-first.*" "singlethread watchpoints work"
1235 +    gdb_test "continue" \
1236 +            "atchpoint 2: var.*Old value = 1.*New value = 2.*validity-thread-A.*" "multithreaded watchpoints work at A"
1237 +    gdb_test "continue" \
1238 +            "atchpoint 2: var.*Old value = 2.*New value = 3.*validity-thread-B.*" "multithreaded watchpoints work at B"
1239 +    gdb_test "continue" \
1240 +            "reakpoint 3, breakpoint.*" "breakpoint (A) after the first fork"
1241 +    gdb_test "continue" \
1242 +            "atchpoint 2: var.*Old value = 3.*New value = 4.*after-fork1-A.*" "watchpoint A after the first fork"
1243 +    gdb_test "continue" \
1244 +            "atchpoint 2: var.*Old value = 4.*New value = 5.*after-fork1-B.*" "watchpoint B after the first fork"
1245 +    gdb_test "continue" \
1246 +            "reakpoint 3, breakpoint.*" "breakpoint (A) after the second fork"
1247 +    gdb_test "continue" \
1248 +            "atchpoint 2: var.*Old value = 5.*New value = 6.*after-fork2-A.*" "watchpoint A after the second fork"
1249 +    gdb_test "continue" \
1250 +            "atchpoint 2: var.*Old value = 6.*New value = 7.*after-fork2-B.*" "watchpoint B after the second fork"
1251 +    gdb_test "continue" "Continuing..*Program exited normally." "finish"
1252 +
1253 +
1254 +    # cleanup
1255 +
1256 +    set pf_prefix $prefix_test
1257 +}
1258 +
1259 +test parent FOLLOW_PARENT
1260 +
1261 +# Only GNU/Linux is known to support `set follow-fork-mode child'.
1262 +if {[istarget "*-*-linux*"]} {
1263 +    test child FOLLOW_CHILD
1264 +}
1265 Index: gdb-6.8.50.20090209/gdb/doc/gdb.texinfo
1266 ===================================================================
1267 --- gdb-6.8.50.20090209.orig/gdb/doc/gdb.texinfo        2009-02-09 16:02:35.000000000 +0100
1268 +++ gdb-6.8.50.20090209/gdb/doc/gdb.texinfo     2009-02-09 16:02:42.000000000 +0100
1269 @@ -3588,6 +3588,14 @@ confident that no other thread can becom
1270  software watchpoints as usual.  However, @value{GDBN} may not notice
1271  when a non-current thread's activity changes the expression.  (Hardware
1272  watchpoints, in contrast, watch an expression in all threads.)
1273 +
1274 +Software watchpoints single-step the current thread to track the changes.
1275 +Other threads are left freely running on @code{continue}; therefore, their
1276 +changes cannot be caught.  To get more reliable software watchpoints, please
1277 +use @code{set scheduler-locking on}.  The default for Red Hat/Fedora
1278 +@value{GDBN} is @code{set scheduler-locking step}, which makes the software
1279 +watchpoints safe for the @code{step} command, but not for the @code{continue}
1280 +command.  @xref{Thread Stops}.
1281  @end quotation
1282  
1283  @xref{set remote hardware-watchpoint-limit}.
1284 Index: gdb-6.8.50.20090209/gdb/config/i386/nm-linux.h
1285 ===================================================================
1286 --- gdb-6.8.50.20090209.orig/gdb/config/i386/nm-linux.h 2009-01-03 06:57:54.000000000 +0100
1287 +++ gdb-6.8.50.20090209/gdb/config/i386/nm-linux.h      2009-02-09 16:02:42.000000000 +0100
1288 @@ -46,6 +46,16 @@ extern void i386_linux_dr_reset_addr (in
1289  extern unsigned long i386_linux_dr_get_status (void);
1290  #define I386_DR_LOW_GET_STATUS() \
1291    i386_linux_dr_get_status ()
1292 +
1293 +/* Remove a watchpoint that watched the memory region which starts at
1294 + *    address ADDR, whose length is LEN bytes, and for accesses of the
1295 + *       type TYPE.  Return 0 on success, -1 on failure.  */
1296 +extern int i386_linux_remove_watchpoint (CORE_ADDR addr, int len, int type);
1297 +
1298 +/* Override basic i386 macros for watchpoint and hardware breakpoint
1299 +   insertion/removal to support threads.  */
1300 +#define target_remove_watchpoint(addr, len, type) \
1301 +  i386_linux_remove_watchpoint (addr, len, type)
1302  \f
1303  
1304  #ifdef HAVE_PTRACE_GETFPXREGS
1305 Index: gdb-6.8.50.20090209/gdb/config/i386/nm-linux64.h
1306 ===================================================================
1307 --- gdb-6.8.50.20090209.orig/gdb/config/i386/nm-linux64.h       2009-01-03 06:57:54.000000000 +0100
1308 +++ gdb-6.8.50.20090209/gdb/config/i386/nm-linux64.h    2009-02-09 16:02:42.000000000 +0100
1309 @@ -51,4 +51,14 @@ extern unsigned long amd64_linux_dr_get_
1310  #define I386_DR_LOW_GET_STATUS() \
1311    amd64_linux_dr_get_status ()
1312  
1313 +/* Remove a watchpoint that watched the memory region which starts at
1314 + *    address ADDR, whose length is LEN bytes, and for accesses of the
1315 + *       type TYPE.  Return 0 on success, -1 on failure.  */
1316 +extern int amd64_linux_remove_watchpoint (CORE_ADDR addr, int len, int type);
1317 +
1318 +/* Override basic amd64 macros for watchpoint and hardware breakpoint
1319 +   insertion/removal to support threads.  */
1320 +#define target_remove_watchpoint(addr, len, type) \
1321 +  amd64_linux_remove_watchpoint (addr, len, type)
1322 +
1323  #endif /* nm-linux64.h */
1324 Index: gdb-6.8.50.20090209/gdb/target.h
1325 ===================================================================
1326 --- gdb-6.8.50.20090209.orig/gdb/target.h       2009-02-09 15:49:25.000000000 +0100
1327 +++ gdb-6.8.50.20090209/gdb/target.h    2009-02-09 16:02:42.000000000 +0100
1328 @@ -1113,7 +1113,9 @@ extern char *normal_pid_to_str (ptid_t p
1329  #ifndef target_insert_watchpoint
1330  #define        target_insert_watchpoint(addr, len, type)       \
1331       (*current_target.to_insert_watchpoint) (addr, len, type)
1332 +#endif
1333  
1334 +#ifndef target_remove_watchpoint
1335  #define        target_remove_watchpoint(addr, len, type)       \
1336       (*current_target.to_remove_watchpoint) (addr, len, type)
1337  #endif
This page took 0.173382 seconds and 3 git commands to generate.