]> git.pld-linux.org Git - packages/gdb.git/blame - gdb-6.6-multifork-debugreg.patch
- obsolete file
[packages/gdb.git] / gdb-6.6-multifork-debugreg.patch
CommitLineData
3a58abaf
AM
1http://sourceware.org/ml/gdb-patches/2008-01/msg00042.html
2[ Backported for GDB-6.6 (only removed the new file inclusion). ]
3
4+
5
62007-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
122007-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
172008-03-01 Jan Kratochvil <jan.kratochvil@redhat.com>
18
19 Port to GDB-6.8pre.
20
212008-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
262008-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
31Index: 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);
184Index: 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 */
197Index: 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);
344Index: 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
366Index: 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);
469Index: 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);
565Index: 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);
723Index: 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
900Index: 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+}
1059Index: 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+}
1120Index: 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+}
1265Index: 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}.
1284Index: 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
1305Index: 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 */
1324Index: 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.289853 seconds and 4 git commands to generate.