1 http://sourceware.org/ml/gdb-patches/2008-01/msg00042.html
2 [ Backported for GDB-6.6 (only removed the new file inclusion). ]
6 2007-09-16 Daniel Jacobowitz <dan@codesourcery.com>
7 Jeff Johnston <jjohnstn@redhat.com>
9 * gdb.texinfo (Setting Watchpoints): Adjust warning text about
10 multi-threaded watchpoints.
12 2007-12-15 Jan Kratochvil <jan.kratochvil@redhat.com>
14 * gdb.texinfo (Setting Watchpoints): New paragraph on the software
15 watchpoints safety wrt `set scheduler-locking'.
17 2008-03-01 Jan Kratochvil <jan.kratochvil@redhat.com>
21 2008-03-31 Jan Kratochvil <jan.kratochvil@redhat.com>
23 * gdb.threads/watchpoint-fork-forkoff.c (forkoff): New delay after the
24 parent/child messages to fix a race.
26 2008-05-28 Jan Kratochvil <jan.kratochvil@redhat.com>
28 * s390-nat.c (s390_fix_watch_points): Fix its compilation failure
29 - rename it to S390_FIX_WATCH_POINTS_LIST.
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
37 amd64_linux_dr_set_control (unsigned long control)
39 - struct lwp_info *lp;
42 amd64_linux_dr[DR_CONTROL] = control;
44 - amd64_linux_dr_set (ptid, DR_CONTROL, control);
46 + /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
47 + not listed for ALL_LWPS. */
49 + if (ptid_get_lwp (inferior_ptid) == 0)
50 + amd64_linux_dr_set (inferior_ptid, DR_CONTROL, control);
53 + struct lwp_info *lp;
57 + amd64_linux_dr_set (ptid, DR_CONTROL, control);
62 amd64_linux_dr_set_addr (int regnum, CORE_ADDR addr)
64 - struct lwp_info *lp;
67 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
69 amd64_linux_dr[DR_FIRSTADDR + regnum] = addr;
71 - amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
73 + /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
74 + not listed for ALL_LWPS. */
76 + if (ptid_get_lwp (inferior_ptid) == 0)
77 + amd64_linux_dr_set (inferior_ptid, DR_FIRSTADDR + regnum, addr);
80 + struct lwp_info *lp;
84 + amd64_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
89 @@ -451,6 +469,41 @@ amd64_linux_new_thread (ptid_t ptid)
91 amd64_linux_dr_set (ptid, DR_CONTROL, amd64_linux_dr[DR_CONTROL]);
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. */
98 +static int amd64_linux_detach_breakpoints_pid;
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. */
104 +amd64_linux_remove_watchpoint (CORE_ADDR addr, int len, int type)
106 + if (ptid_get_pid (inferior_ptid) == amd64_linux_detach_breakpoints_pid)
108 + /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions. */
109 + amd64_linux_detach_breakpoints_pid = 0;
111 + return i386_remove_watchpoint (addr, len, type);
115 +amd64_linux_detach_breakpoints (int detached_pid)
117 + struct cleanup *old_chain = save_inferior_ptid ();
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);
124 + i386_detach_breakpoints (detached_pid);
126 + do_cleanups (old_chain);
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
135 +static int (*amd64_linux_super_follow_fork) (struct target_ops *ops,
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. */
142 +amd64_linux_follow_fork (struct target_ops *ops, int follow_child)
145 + struct target_waitstatus last_status;
147 + int parent_pid, child_pid;
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);
158 + if (! follow_child)
160 + amd64_linux_detach_breakpoints (child_pid);
165 + amd64_linux_detach_breakpoints (child_pid);
168 + return (*amd64_linux_super_follow_fork) (ops, follow_child);
171 /* Provide a prototype to silence -Wmissing-prototypes. */
172 void _initialize_amd64_linux_nat (void);
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;
178 + amd64_linux_super_follow_fork = t->to_follow_fork;
179 + t->to_follow_fork = amd64_linux_follow_fork;
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
190 #endif /* I386_WATCHPOINTS_IN_TARGET_VECTOR */
192 +extern void i386_detach_breakpoints (int detached_pid);
194 #endif /* I386_USE_GENERIC_WATCHPOINTS */
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
204 i386_linux_dr[DR_CONTROL] = control;
205 - ALL_LWPS (lp, ptid)
206 - i386_linux_dr_set (ptid, DR_CONTROL, control);
208 + /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
209 + not listed for ALL_LWPS. */
211 + if (ptid_get_lwp (inferior_ptid) == 0)
212 + i386_linux_dr_set (inferior_ptid, DR_CONTROL, control);
215 + struct lwp_info *lp;
218 + ALL_LWPS (lp, ptid)
219 + i386_linux_dr_set (ptid, DR_CONTROL, control);
224 i386_linux_dr_set_addr (int regnum, CORE_ADDR addr)
226 - struct lwp_info *lp;
229 gdb_assert (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR);
231 i386_linux_dr[DR_FIRSTADDR + regnum] = addr;
232 - ALL_LWPS (lp, ptid)
233 - i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
235 + /* I386_DETACH_BREAKPOINTS may need to reset the registers on single process
236 + not listed for ALL_LWPS. */
238 + if (ptid_get_lwp (inferior_ptid) == 0)
239 + i386_linux_dr_set (inferior_ptid, DR_FIRSTADDR + regnum, addr);
242 + struct lwp_info *lp;
245 + ALL_LWPS (lp, ptid)
246 + i386_linux_dr_set (ptid, DR_FIRSTADDR + regnum, addr);
251 @@ -673,6 +694,41 @@ i386_linux_new_thread (ptid_t ptid)
253 i386_linux_dr_set (ptid, DR_CONTROL, i386_linux_dr[DR_CONTROL]);
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. */
260 +static int i386_linux_detach_breakpoints_pid;
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. */
266 +i386_linux_remove_watchpoint (CORE_ADDR addr, int len, int type)
268 + if (ptid_get_pid (inferior_ptid) == i386_linux_detach_breakpoints_pid)
270 + /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions. */
271 + i386_linux_detach_breakpoints_pid = 0;
273 + return i386_remove_watchpoint (addr, len, type);
277 +i386_linux_detach_breakpoints (int detached_pid)
279 + struct cleanup *old_chain = save_inferior_ptid ();
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);
286 + i386_detach_breakpoints (detached_pid);
288 + do_cleanups (old_chain);
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);
297 +static int (*i386_linux_super_follow_fork) (struct target_ops *ops,
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. */
304 +i386_linux_follow_fork (struct target_ops *ops, int follow_child)
307 + struct target_waitstatus last_status;
309 + int parent_pid, child_pid;
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);
318 + if (! follow_child)
320 + i386_linux_detach_breakpoints (child_pid);
325 + i386_linux_detach_breakpoints (child_pid);
328 + return (*i386_linux_super_follow_fork) (ops, follow_child);
332 _initialize_i386_linux_nat (void)
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;
338 + i386_linux_super_follow_fork = t->to_follow_fork;
339 + t->to_follow_fork = i386_linux_follow_fork;
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,
353 +i386_detach_breakpoints (int detached_pid)
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);
363 /* Return non-zero if we can watch a memory region that starts at
364 address ADDR and whose length is LEN bytes. */
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
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. */
378 +static int ia64_linux_detach_breakpoints_pid;
381 ia64_linux_remove_watchpoint (CORE_ADDR addr, int len, int type)
383 @@ -590,6 +596,11 @@ ia64_linux_remove_watchpoint (CORE_ADDR
384 long dbr_addr, dbr_mask;
385 int max_watchpoints = 4;
387 + if (ptid_get_pid (inferior_ptid) == ia64_linux_detach_breakpoints_pid)
389 + /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions. */
390 + ia64_linux_detach_breakpoints_pid = 0;
392 if (len <= 0 || !is_power_of_2 (len))
395 @@ -617,6 +628,22 @@ ia64_linux_remove_watchpoint (CORE_ADDR
399 +ia64_linux_detach_breakpoints (int detached_pid)
402 + long dbr_addr, dbr_mask;
403 + int max_watchpoints = 4;
405 + ia64_linux_detach_breakpoints_pid = detached_pid;
407 + /* Do not touch any DEBUG_REGISTERS mirrors here. */
410 + for (idx = 0; idx < max_watchpoints; idx++)
411 + store_debug_register_pair (ptid_build (detached_pid, 0, 0), idx, &dbr_addr, &dbr_mask);
415 ia64_linux_new_thread (ptid_t ptid)
418 @@ -805,6 +832,40 @@ ia64_linux_xfer_partial (struct target_o
422 +static int (*ia64_linux_super_follow_fork) (struct target_ops *ops,
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. */
429 +ia64_linux_follow_fork (struct target_ops *ops, int follow_child)
432 + struct target_waitstatus last_status;
434 + int parent_pid, child_pid;
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);
443 + if (! follow_child)
445 + ia64_linux_detach_breakpoints (child_pid);
450 + ia64_linux_detach_breakpoints (child_pid);
453 + return (*ia64_linux_super_follow_fork) (ops, follow_child);
456 void _initialize_ia64_linux_nat (void);
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;
463 + ia64_linux_super_follow_fork = t->to_follow_fork;
464 + t->to_follow_fork = ia64_linux_follow_fork;
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
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. */
481 +static int ppc_linux_detach_breakpoints_pid;
484 ppc_linux_remove_watchpoint (CORE_ADDR addr, int len, int rw)
486 @@ -1125,6 +1131,11 @@ ppc_linux_remove_watchpoint (CORE_ADDR a
490 + if (ptid_get_pid (inferior_ptid) == ppc_linux_detach_breakpoints_pid)
492 + /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions. */
493 + ppc_linux_detach_breakpoints_pid = 0;
495 saved_dabr_value = 0;
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);
503 +ppc_linux_detach_breakpoints (int detached_pid)
505 + ppc_linux_detach_breakpoints_pid = detached_pid;
507 + /* Do not touch the SAVED_DABR_VALUE mirror here. */
508 + ptrace (PTRACE_SET_DEBUGREG, detached_pid, 0, 0);
512 ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
514 @@ -1318,6 +1338,40 @@ ppc_linux_read_description (struct targe
515 return isa205? tdesc_powerpc_isa205_32l : tdesc_powerpc_32l;
518 +static int (*ppc_linux_super_follow_fork) (struct target_ops *ops,
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. */
525 +ppc_linux_follow_fork (struct target_ops *ops, int follow_child)
528 + struct target_waitstatus last_status;
530 + int parent_pid, child_pid;
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);
539 + if (! follow_child)
541 + ppc_linux_detach_breakpoints (child_pid);
546 + ppc_linux_detach_breakpoints (child_pid);
549 + return (*ppc_linux_super_follow_fork) (ops, follow_child);
552 void _initialize_ppc_linux_nat (void);
555 @@ -1343,6 +1397,9 @@ _initialize_ppc_linux_nat (void)
557 t->to_read_description = ppc_linux_read_description;
559 + ppc_linux_super_follow_fork = t->to_follow_fork;
560 + t->to_follow_fork = ppc_linux_follow_fork;
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)
573 -s390_fix_watch_points (ptid_t ptid)
574 +s390_fix_watch_points_list (int tid, struct watch_area *area_list)
581 CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0;
582 struct watch_area *area;
584 - tid = TIDGET (ptid);
586 - tid = PIDGET (ptid);
588 - for (area = watch_base; area; area = area->next)
589 + for (area = area_list; area; area = area->next)
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"));
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"));
607 +s390_fix_watch_points (ptid_t ptid)
611 + tid = TIDGET (ptid);
613 + tid = PIDGET (ptid);
615 + s390_fix_watch_points_list (tid, watch_base);
619 s390_insert_watchpoint (CORE_ADDR addr, int len, int type)
621 @@ -347,6 +353,12 @@ s390_insert_watchpoint (CORE_ADDR addr,
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. */
629 +static int s390_detach_breakpoints_pid;
632 s390_remove_watchpoint (CORE_ADDR addr, int len, int type)
634 @@ -354,6 +366,11 @@ s390_remove_watchpoint (CORE_ADDR addr,
636 struct watch_area *area, **parea;
638 + if (ptid_get_pid (inferior_ptid) == s390_detach_breakpoints_pid)
640 + /* FOLLOW-FORK-MODE CHILD runs later the CHILD with no restrictions. */
641 + s390_detach_breakpoints_pid = 0;
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,
650 +#if 0 /* Red Hat fork/threads watchpoints changes may trigger it. */
651 fprintf_unfiltered (gdb_stderr,
652 "Attempt to remove nonexistent watchpoint.\n");
657 @@ -375,6 +394,15 @@ s390_remove_watchpoint (CORE_ADDR addr,
662 +s390_detach_breakpoints (int detached_pid)
664 + s390_detach_breakpoints_pid = detached_pid;
666 + /* Do not touch the WATCH_BASE here. */
667 + s390_fix_watch_points_list (detached_pid, NULL);
671 s390_can_use_hw_breakpoint (int type, int cnt, int othertype)
673 @@ -387,6 +415,39 @@ s390_region_ok_for_hw_watchpoint (CORE_A
677 +static int (*s390_super_follow_fork) (struct target_ops *ops, int follow_child);
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. */
683 +s390_follow_fork (struct target_ops *ops, int follow_child)
686 + struct target_waitstatus last_status;
688 + int parent_pid, child_pid;
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);
697 + if (! follow_child)
699 + s390_detach_breakpoints (child_pid);
704 + s390_detach_breakpoints (child_pid);
707 + return (*s390_super_follow_fork) (ops, follow_child);
711 void _initialize_s390_nat (void);
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;
717 + s390_super_follow_fork = t->to_follow_fork;
718 + t->to_follow_fork = s390_follow_fork;
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
728 +/* Test case for forgotten hw-watchpoints after fork()-off of a process.
731 + Free Software Foundation, Inc.
733 + This file is part of GDB.
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.
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.
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. */
753 +static void delay (void)
755 + int i = usleep (1000000 / 100);
756 + assert (i == 0 || errno == EINTR);
759 +#if defined FOLLOW_PARENT
761 +static void forkoff (int nr)
763 + pid_t child, pid_got;
764 + int exit_code = 42 + nr;
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
778 + (gdb) parent2: 14223 */
782 + /* We must not get caught here (against a forgotten breakpoint). */
788 + printf ("parent%d: %d\n", nr, (int) child);
789 + /* Delay to get both the "child%d" and "parent%d" message printed, see
794 + pid_got = wait (&status);
795 + assert (pid_got == child);
796 + assert (WIFEXITED (status));
797 + assert (WEXITSTATUS (status) == exit_code);
799 + /* We must get caught here (against a false watchpoint removal). */
804 +#elif defined FOLLOW_CHILD
806 +static volatile int usr1_got;
808 +static void handler_usr1 (int signo)
813 +static void forkoff (int nr)
817 + struct sigaction act, oldact;
819 + void *thread_result;
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);
835 + printf ("parent%d: %d\n", nr, (int) child);
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
844 + /* We must not get caught here (against a forgotten breakpoint). */
850 + /* And neither got caught our thread. */
853 + i = pthread_join (thread, &thread_result);
855 + assert (thread_result == (void *) 99UL);
858 + /* Be sure our child knows we did not get caught above. */
860 + i = kill (child, SIGUSR1);
863 + /* Sleep for a while to check GDB's `info threads' no longer tracks us in
871 + printf ("child%d: %d\n", nr, (int) getpid ());
873 + /* Let the parent signal us about its success. Be careful of races. */
875 + for (loop = 0; loop < 1000; loop++)
877 + /* Parent either died (and USR1_GOT is zero) or it succeeded. */
878 + if (kill (getppid (), 0) != 0)
880 + /* Parent succeeded? */
888 + /* We must get caught here (against a false watchpoint removal). */
893 + i = sigaction (SIGUSR1, &oldact, NULL);
898 +# error "!FOLLOW_PARENT && !FOLLOW_CHILD"
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
905 +/* Test case for forgotten hw-watchpoints after fork()-off of a process.
908 + Free Software Foundation, Inc.
910 + This file is part of GDB.
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.
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.
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. */
929 +#include <sys/wait.h>
932 +#include <pthread.h>
934 +#include <asm/unistd.h>
936 +#define gettid() syscall (__NR_gettid)
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. */
942 +static volatile int var;
944 +static void dummy (void)
948 +static void breakpoint (void)
952 +/* Include here the functions:
953 + static void forkoff (int nr);
954 + static void delay (void); */
956 +static pthread_t thread;
957 +static volatile int step;
960 +#include "watchpoint-fork-forkoff.c"
962 +static void *start (void *arg)
970 + var++; /* validity-thread-B */
971 + dummy (); /* validity-thread-B */
984 + var++; /* after-fork1-B */
985 + dummy (); /* after-fork1-B */
995 + var++; /* after-fork2-B */
996 + dummy (); /* after-fork2-B */
997 + return (void *) 5UL;
1000 + /* We must not get caught here (against a forgotten breakpoint). */
1003 + return (void *) 99UL;
1009 + void *thread_result;
1011 + setbuf (stdout, NULL);
1012 + printf ("main: %d\n", (int) gettid ());
1014 + /* General watchpoints validity. */
1015 + var++; /* validity-first */
1016 + dummy (); /* validity-first */
1018 + i = pthread_create (&thread, NULL, start, NULL);
1021 + var++; /* validity-thread-A */
1022 + dummy (); /* validity-thread-A */
1027 + /* Hardware watchpoints got disarmed here. */
1030 + var++; /* after-fork1-A */
1031 + dummy (); /* after-fork1-A */
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);
1041 + /* A sanity check for double hardware watchpoints removal. */
1044 + var++; /* after-fork2-A */
1045 + dummy (); /* after-fork2-A */
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);
1053 + i = pthread_join (thread, &thread_result);
1055 + assert (thread_result == (void *) 5UL);
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
1064 +/* Test case for forgotten hw-watchpoints after fork()-off of a process.
1067 + Free Software Foundation, Inc.
1069 + This file is part of GDB.
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.
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.
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. */
1086 +#include <assert.h>
1087 +#include <unistd.h>
1088 +#include <sys/wait.h>
1090 +#include <stdlib.h>
1092 +static volatile int var;
1094 +static void breakpoint (void)
1098 +/* Include here the function:
1099 + static void forkoff (int nr); */
1101 +#include "watchpoint-fork-forkoff.c"
1105 + setbuf (stdout, NULL);
1106 + printf ("main: %d\n", (int) getpid ());
1108 + /* General watchpoints validity. */
1110 + /* Hardware watchpoints got disarmed here. */
1112 + /* This watchpoint got lost before. */
1114 + /* A sanity check for double hardware watchpoints removal. */
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
1125 +# Copyright 2008 Free Software Foundation, Inc.
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.
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.
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/>.
1140 +# Test case for forgotten hw-watchpoints after fork()-off of a process.
1142 +proc test {type symbol} {
1143 + global objdir subdir srcdir
1146 + set prefix_test $pf_prefix
1147 + lappend pf_prefix "$type:"
1148 + set prefix_mt $pf_prefix
1152 + set pf_prefix $prefix_mt
1153 + lappend pf_prefix "singlethreaded:"
1155 + set testfile watchpoint-fork
1156 + set srcfile ${testfile}.c
1157 + set binfile ${objdir}/${subdir}/${testfile}
1159 + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug additional_flags=-D$symbol"] != "" } {
1160 + untested "Couldn't compile test program"
1166 + gdb_reinitialize_dir $srcdir/$subdir
1167 + gdb_load ${binfile}
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"
1173 + if { ![runto_main] } then {
1174 + gdb_suppress_tests
1178 + # Install the watchpoint only after getting into MAIN - workaround some PPC
1180 + gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint"
1182 + # It is never hit but it should not be left over in the fork()ed-off child.
1183 + gdb_breakpoint "breakpoint"
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"
1200 + set pf_prefix $prefix_mt
1201 + lappend pf_prefix "multithreaded:"
1203 + set testfile watchpoint-fork-mt
1204 + set srcfile ${testfile}.c
1205 + set binfile ${objdir}/${subdir}/${testfile}
1207 + if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug additional_flags=-D$symbol"] != "" } {
1208 + untested "Couldn't compile test program"
1214 + gdb_reinitialize_dir $srcdir/$subdir
1215 + gdb_load ${binfile}
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"
1221 + if { ![runto_main] } then {
1222 + gdb_suppress_tests
1226 + # Install the watchpoint only after getting into MAIN - workaround some PPC
1228 + gdb_test "watch var" "atchpoint 2: var" "Set the watchpoint"
1230 + # It is never hit but it should not be left over in the fork()ed-off child.
1231 + gdb_breakpoint "breakpoint"
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"
1256 + set pf_prefix $prefix_test
1259 +test parent FOLLOW_PARENT
1261 +# Only GNU/Linux is known to support `set follow-fork-mode child'.
1262 +if {[istarget "*-*-linux*"]} {
1263 + test child FOLLOW_CHILD
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.)
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}.
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 ()
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);
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)
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 ()
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);
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)
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)
1334 +#ifndef target_remove_watchpoint
1335 #define target_remove_watchpoint(addr, len, type) \
1336 (*current_target.to_remove_watchpoint) (addr, len, type)