From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10567 invoked by alias); 9 Nov 2009 03:18:25 -0000 Received: (qmail 10557 invoked by uid 22791); 9 Nov 2009 03:18:22 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail-px0-f189.google.com (HELO mail-px0-f189.google.com) (209.85.216.189) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 09 Nov 2009 03:18:17 +0000 Received: by pxi27 with SMTP id 27so751217pxi.25 for ; Sun, 08 Nov 2009 19:18:15 -0800 (PST) MIME-Version: 1.0 Received: by 10.142.6.2 with SMTP id 2mr699625wff.90.1257736695123; Sun, 08 Nov 2009 19:18:15 -0800 (PST) In-Reply-To: <4AF31C1F.2000405@vmware.com> References: <4AECE12F.3000704@vmware.com> <4AF31C1F.2000405@vmware.com> From: Hui Zhu Date: Mon, 09 Nov 2009 03:18:00 -0000 Message-ID: Subject: Re: [RFA] Fix hw watchpoints in process record. To: Michael Snyder Cc: "gdb-patches@sourceware.org" Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-11/txt/msg00131.txt.bz2 Still not very well, with the old program: (gdb) start Temporary breakpoint 1 at 0x80483c1: file 1.c, line 20. Starting program: /home/teawater/gdb/a.out warning: the debug information found in "/lib/ld-2.7.so" does not match "/lib/ld-linux.so.2" (CRC mismatch). warning: the debug information found in "/lib/tls/i686/cmov/libc-2.7.so" does not match "/lib/tls/i686/cmov/libc.so.6" (CRC mismatch). Temporary breakpoint 1, main () at 1.c:20 20 int b =3D 0; (gdb) record (gdb) n During symbol reading, incomplete CFI data; unspecified registers (e.g., eax) at 0x80483be. 21 int c =3D 1; (gdb) 24 printf ("a =3D %d b =3D %d c =3D %d\n", a, b, c); (gdb) hw Undefined command: "hw". Try "help". (gdb) hb Hardware assisted breakpoint 2 at 0x80483cf: file 1.c, line 24. (gdb) c Continuing. a =3D 0 b =3D 0 c =3D 1 a =3D 3 a =3D 3 b =3D 3 c =3D 1 a =3D 3 b =3D 3 c =3D 2 a =3D 1 b =3D 3 c =3D 2 The next instruction is syscall exit_group. It will make the program exit. Do you want to stop the program?([y] or n) Process record: inferior program stopped. Program received signal SIGTRAP, Trace/breakpoint trap. 0xb7fe3405 in __kernel_vsyscall () (gdb) rc Continuing. Breakpoint 2, main () at 1.c:24 24 printf ("a =3D %d b =3D %d c =3D %d\n", a, b, c); (gdb) rc Continuing. No more reverse-execution history. main () at 1.c:20 20 int b =3D 0; (gdb) c Continuing. Program received signal SIGTRAP, Trace/breakpoint trap. 0x080483d0 in main () at 1.c:24 24 printf ("a =3D %d b =3D %d c =3D %d\n", a, b, c); (gdb) c Continuing. No more reverse-execution history. 0xb7fe3405 in __kernel_vsyscall () (gdb) rc Continuing. No more reverse-execution history. main () at 1.c:20 20 int b =3D 0; (gdb) c Continuing. No more reverse-execution history. 0xb7fe3405 in __kernel_vsyscall () (gdb) rc Continuing. No more reverse-execution history. main () at 1.c:20 20 int b =3D 0; (gdb) info b Num Type Disp Enb Address What 2 hw breakpoint keep y 0x080483cf in main at 1.c:24 breakpoint already hit 1 time (gdb) c Continuing. No more reverse-execution history. 0xb7fe3405 in __kernel_vsyscall () Thanks, Hui On Fri, Nov 6, 2009 at 02:40, Michael Snyder wrote: > Hui Zhu wrote: >> >> Hi Michael, >> >> I do some test with this patch. =A0But sometime hb didn't work in replay >> mode. > > OK, thanks, I see the problem. > > Try this patch instead. > > > 2009-10-31 =A0Michael Snyder =A0 > =A0 =A0 =A0 =A0Make hardware watchpoints work for process record. > =A0 =A0 =A0 =A0* breakpoint.c (watchpoint_check_1): Abstracted from > watchpoint_check. > =A0 =A0 =A0 =A0(watchpoint_check_2): Check_error entry point for above. > =A0 =A0 =A0 =A0(watchpoint_check): Call watchpoint_check_1. > =A0 =A0 =A0 =A0(hw_watchpoint_check): New function. =A0Return true if > =A0 =A0 =A0 =A0a hardware watchpoint expression has changed. > =A0 =A0 =A0 =A0* breakpoint.h (hw_watchpoint_check): Export. > > =A0 =A0 =A0 =A0* record.c (record_beneath_to_stopped_by_watchpoint): New = pointer. > =A0 =A0 =A0 =A0(record_open): Initialize above pointer. > =A0 =A0 =A0 =A0(record_stopped_by_watchpoint): New target method. > =A0 =A0 =A0 =A0(record_wait): Check to see if hitting hardware watchpoint. > > Index: gdb/breakpoint.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gdb.orig/breakpoint.c =A0 =A0 =A0 2009-11-05 09:54:36.000000000 -0800 > +++ gdb/breakpoint.c =A0 =A02009-11-05 10:19:07.000000000 -0800 > @@ -3075,18 +3075,13 @@ > =A0#define BP_TEMPFLAG 1 > =A0#define BP_HARDWAREFLAG 2 > > -/* Check watchpoint condition. =A0*/ > - > =A0static int > -watchpoint_check (void *p) > +watchpoint_check_1 (void *p, struct value **new_valp) > =A0{ > - =A0bpstat bs =3D (bpstat) p; > - =A0struct breakpoint *b; > + =A0struct breakpoint *b =3D p; > =A0 struct frame_info *fr; > =A0 int within_current_scope; > > - =A0b =3D bs->breakpoint_at->owner; > - > =A0 if (b->exp_valid_block =3D=3D NULL) > =A0 =A0 within_current_scope =3D 1; > =A0 else > @@ -3137,20 +3132,16 @@ > =A0 =A0 =A0 =A0 =A0we might be in the middle of evaluating a function cal= l. =A0*/ > > =A0 =A0 =A0 struct value *mark =3D value_mark (); > - =A0 =A0 =A0struct value *new_val; > > - =A0 =A0 =A0fetch_watchpoint_value (b->exp, &new_val, NULL, NULL); > - =A0 =A0 =A0if ((b->val !=3D NULL) !=3D (new_val !=3D NULL) > - =A0 =A0 =A0 =A0 || (b->val !=3D NULL && !value_equal (b->val, new_val))) > + =A0 =A0 =A0fetch_watchpoint_value (b->exp, new_valp, NULL, NULL); > + =A0 =A0 =A0if ((b->val !=3D NULL) !=3D (*new_valp !=3D NULL) > + =A0 =A0 =A0 =A0 || (b->val !=3D NULL && !value_equal (b->val, *new_valp= ))) > =A0 =A0 =A0 =A0{ > - =A0 =A0 =A0 =A0 if (new_val !=3D NULL) > + =A0 =A0 =A0 =A0 if (*new_valp !=3D NULL) > =A0 =A0 =A0 =A0 =A0 =A0{ > - =A0 =A0 =A0 =A0 =A0 =A0 release_value (new_val); > + =A0 =A0 =A0 =A0 =A0 =A0 release_value (*new_valp); > =A0 =A0 =A0 =A0 =A0 =A0 =A0value_free_to_mark (mark); > =A0 =A0 =A0 =A0 =A0 =A0} > - =A0 =A0 =A0 =A0 bs->old_val =3D b->val; > - =A0 =A0 =A0 =A0 b->val =3D new_val; > - =A0 =A0 =A0 =A0 b->val_valid =3D 1; > =A0 =A0 =A0 =A0 =A0/* We will stop here */ > =A0 =A0 =A0 =A0 =A0return WP_VALUE_CHANGED; > =A0 =A0 =A0 =A0} > @@ -3181,8 +3172,9 @@ > =A0 =A0 =A0 =A0 =A0(uiout, "reason", async_reason_lookup > (EXEC_ASYNC_WATCHPOINT_SCOPE)); > =A0 =A0 =A0 ui_out_text (uiout, "\nWatchpoint "); > =A0 =A0 =A0 ui_out_field_int (uiout, "wpnum", b->number); > - =A0 =A0 =A0ui_out_text (uiout, " deleted because the program has left t= he block > in\n\ > -which its expression is valid.\n"); > + =A0 =A0 =A0ui_out_text (uiout, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0" deleted because the program has le= ft the block in\n\ > +which its expression is valid.\n"); > > =A0 =A0 =A0 if (b->related_breakpoint) > =A0 =A0 =A0 =A0b->related_breakpoint->disposition =3D disp_del_at_next_st= op; > @@ -3192,6 +3184,36 @@ > =A0 =A0 } > =A0} > > +static int > +watchpoint_check_2 (void *p) > +{ > + =A0struct value *notused; > + > + =A0return watchpoint_check_1 (p, ¬used); > +} > + > +/* Check watchpoint condition. =A0*/ > + > +static int > +watchpoint_check (void *p) > +{ > + =A0bpstat bs =3D (bpstat) p; > + =A0struct value *new_val; > + =A0struct breakpoint *b; > + =A0int ret; > + > + =A0b =3D bs->breakpoint_at->owner; > + =A0ret =3D watchpoint_check_1 (b, &new_val); > + > + =A0if (ret =3D=3D WP_VALUE_CHANGED) > + =A0 =A0{ > + =A0 =A0 =A0bs->old_val =3D b->val; > + =A0 =A0 =A0b->val =3D new_val; > + =A0 =A0 =A0b->val_valid =3D 1; > + =A0 =A0} > + =A0return ret; > +} > + > =A0/* Return true if it looks like target has stopped due to hitting > =A0 =A0breakpoint location BL. =A0This function does not check if we > =A0 =A0should stop, only if BL explains the stop. =A0 */ > @@ -3250,6 +3272,29 @@ > =A0 return 1; > =A0} > > +int > +hw_watchpoint_check (void) > +{ > + =A0struct breakpoint *b; > + =A0struct value *new_val; > + > + =A0ALL_BREAKPOINTS (b) > + =A0 =A0if (b->type =3D=3D bp_hardware_watchpoint > + =A0 =A0 =A0 || b->type =3D=3D bp_access_watchpoint) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 char *msg > + =A0 =A0 =A0 =A0 =3D xstrprintf (_("Error evaluating expression for watc= hpoint > %d\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 b->number); > + =A0 =A0 =A0 struct cleanup *cleanups =3D make_cleanup (xfree, msg); > + =A0 =A0 =A0 int e =3D catch_errors (watchpoint_check_2, b, msg, RETURN_= MASK_ALL); > + =A0 =A0 =A0 do_cleanups (cleanups); > + =A0 =A0 =A0 if (e =3D=3D WP_VALUE_CHANGED) > + =A0 =A0 =A0 =A0 return 1; =A0 =A0 /* should stop */ > + =A0 =A0 =A0} > + =A0return 0; =A0 =A0 =A0 =A0 =A0 =A0/* don't stop */ > +} > + > + > =A0/* If BS refers to a watchpoint, determine if the watched values > =A0 =A0has actually changed, and we should stop. =A0If not, set BS->stop > =A0 =A0to 0. =A0*/ > @@ -3267,7 +3312,7 @@ > =A0 =A0 =A0 CORE_ADDR addr; > =A0 =A0 =A0 struct value *v; > =A0 =A0 =A0 int must_check_value =3D 0; > - > + > =A0 =A0 =A0 if (b->type =3D=3D bp_watchpoint) > =A0 =A0 =A0 =A0/* For a software watchpoint, we must always check the > =A0 =A0 =A0 =A0 =A0 watched value. =A0*/ > @@ -3284,7 +3329,7 @@ > =A0 =A0 =A0 =A0 =A0 value. =A0Access and read watchpoints are out of luck= ; without > =A0 =A0 =A0 =A0 =A0 a data address, we can't figure it out. =A0*/ > =A0 =A0 =A0 =A0must_check_value =3D 1; > - > + > =A0 =A0 =A0 if (must_check_value) > =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0char *message =3D xstrprintf ("Error evaluating expres= sion for > watchpoint %d\n", > Index: gdb/breakpoint.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gdb.orig/breakpoint.h =A0 =A0 =A0 2009-11-05 09:54:36.000000000 -0800 > +++ gdb/breakpoint.h =A0 =A02009-11-05 10:13:18.000000000 -0800 > @@ -978,4 +978,6 @@ > =A0 =A0is newly allocated; the caller should free when done with it. =A0*/ > =A0extern VEC(breakpoint_p) *all_tracepoints (void); > > +extern int hw_watchpoint_check (void); > + > =A0#endif /* !defined (BREAKPOINT_H) */ > Index: gdb/record.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gdb.orig/record.c =A0 2009-11-05 09:54:36.000000000 -0800 > +++ gdb/record.c =A0 =A0 =A0 =A02009-11-05 10:24:30.000000000 -0800 > @@ -224,6 +224,7 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct bp_target_info *); > =A0static int (*record_beneath_to_remove_breakpoint) (struct gdbarch *, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct bp_target_info *); > +static int (*record_beneath_to_stopped_by_watchpoint) (void); > > =A0/* Alloc and free functions for record_reg, record_mem, and record_end > =A0 =A0entries. =A0*/ > @@ -770,6 +771,7 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0struct bp_target_info *); > =A0static int (*tmp_to_remove_breakpoint) (struct gdbarch *, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0struct bp_target_info *); > +static int (*tmp_to_stopped_by_watchpoint) (void); > > =A0static void record_restore (void); > > @@ -894,6 +896,8 @@ > =A0 =A0 =A0 =A0tmp_to_insert_breakpoint =3D t->to_insert_breakpoint; > =A0 =A0 =A0 if (!tmp_to_remove_breakpoint) > =A0 =A0 =A0 =A0tmp_to_remove_breakpoint =3D t->to_remove_breakpoint; > + =A0 =A0 =A0if (!tmp_to_stopped_by_watchpoint) > + =A0 =A0 =A0 tmp_to_stopped_by_watchpoint =3D t->to_stopped_by_watchpoin= t; > =A0 =A0 } > =A0 if (!tmp_to_xfer_partial) > =A0 =A0 error (_("Could not find 'to_xfer_partial' method on the target > stack.")); > @@ -915,6 +919,7 @@ > =A0 record_beneath_to_xfer_partial =3D tmp_to_xfer_partial; > =A0 record_beneath_to_insert_breakpoint =3D tmp_to_insert_breakpoint; > =A0 record_beneath_to_remove_breakpoint =3D tmp_to_remove_breakpoint; > + =A0record_beneath_to_stopped_by_watchpoint =3D tmp_to_stopped_by_watchp= oint; > > =A0 if (current_target.to_stratum =3D=3D core_stratum) > =A0 =A0 record_core_open_1 (name, from_tty); > @@ -1010,6 +1015,9 @@ > =A0 =A0 record_list =3D record_list->prev; > =A0} > > +/* Flag set to TRUE for target_stopped_by_watchpoint. =A0*/ > +static int record_hw_watchpoint =3D 0; > + > =A0/* "to_wait" target method for process record target. > > =A0 =A0In record mode, the target is always run in singlestep mode > @@ -1069,21 +1077,27 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct regcache *regcache; > > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Yes -- check if there is a breakpoin= t. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Yes -- check if there is a breakpoin= t or watchpoint. > =A0*/ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0registers_changed (); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0regcache =3D get_current_regcache (); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tmp_pc =3D regcache_read_pc (regcache); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (breakpoint_inserted_here_p (get_re= gcache_aspace > (regcache), > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 tmp_pc)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 tmp_pc) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 || target_stopped_by_watchpoint= ()) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* There is a breakpoint. =A0GD= B will want to stop. =A0*/ > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdbarch *gdbarch =3D get= _regcache_arch > (regcache); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* There is a breakpoint, or wa= tchpoint. > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GDB will want to stop. = =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!target_stopped_by_watchpoi= nt ()) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdbarch *gdbarch > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D get_regcache_ar= ch (regcache); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0CORE_ADDR decr_pc_after_break > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D gdbarch_decr_pc_after_= break (gdbarch); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (decr_pc_after_break) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0regcache_write_pc (regcach= e, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 tmp_pc + decr_pc_after_break); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0else > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* There is not a breakpoint, = and gdb is not > @@ -1116,9 +1130,10 @@ > =A0 =A0 =A0 struct cleanup *old_cleanups =3D make_cleanup (record_wait_cl= eanups, 0); > =A0 =A0 =A0 CORE_ADDR tmp_pc; > > + =A0 =A0 =A0record_hw_watchpoint =3D 0; > =A0 =A0 =A0 status->kind =3D TARGET_WAITKIND_STOPPED; > > - =A0 =A0 =A0/* Check breakpoint when forward execute. =A0*/ > + =A0 =A0 =A0/* Check for breakpoint or watchpoint when forward execute. = =A0*/ > =A0 =A0 =A0 if (execution_direction =3D=3D EXEC_FORWARD) > =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0tmp_pc =3D regcache_read_pc (regcache); > @@ -1136,6 +1151,15 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gdbar= ch_decr_pc_after_break (gdbarch)); > =A0 =A0 =A0 =A0 =A0 =A0 =A0goto replay_out; > =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 set_executing (inferior_ptid, 0); > + =A0 =A0 =A0 =A0 if (hw_watchpoint_check ()) > + =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 if (record_debug) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_stdlog, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "Pr= ocess record: hit hw watchpoint.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 record_hw_watchpoint =3D 1; > + =A0 =A0 =A0 =A0 =A0 } > + > =A0 =A0 =A0 =A0} > > =A0 =A0 =A0 record_get_sig =3D 0; > @@ -1155,6 +1179,7 @@ > =A0 =A0 =A0 =A0 stop. =A0*/ > =A0 =A0 =A0 do > =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 set_executing (inferior_ptid, 0); > =A0 =A0 =A0 =A0 =A0/* Check for beginning and end of log. =A0*/ > =A0 =A0 =A0 =A0 =A0if (execution_direction =3D=3D EXEC_REVERSE > =A0 =A0 =A0 =A0 =A0 =A0 =A0&& record_list =3D=3D &record_first) > @@ -1219,6 +1244,15 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 gdbarch_decr_pc_after_break > (gdbarch)); > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0continue_flag =3D 0; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* check watchpoint */ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (hw_watchpoint_check ()) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (record_debug) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 fprintf_unfiltered (gdb_std= log, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 "Process record: hit hw > watchpoint.\n"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 record_hw_watchpoint =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue_flag =3D 0; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Check target signal */ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (record_list->u.end.sigval !=3D TAR= GET_SIGNAL_0) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* FIXME: better way to check */ > @@ -1238,6 +1272,7 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (record_list->next) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_list =3D record_list->next; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 set_executing (inferior_ptid, 1); > =A0 =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0} > =A0 =A0 =A0 while (continue_flag); > @@ -1260,6 +1295,16 @@ > =A0 return inferior_ptid; > =A0} > > +/* to_stopped_by_watchpoint method */ > +static int > +record_stopped_by_watchpoint (void) > +{ > + =A0if (RECORD_IS_REPLAY) > + =A0 =A0return record_hw_watchpoint; > + =A0else > + =A0 =A0return record_beneath_to_stopped_by_watchpoint (); > +} > + > =A0/* "to_disconnect" method for process record target. =A0*/ > > =A0static void > @@ -1599,6 +1644,7 @@ > =A0 /* Add bookmark target methods. =A0*/ > =A0 record_ops.to_get_bookmark =3D record_get_bookmark; > =A0 record_ops.to_goto_bookmark =3D record_goto_bookmark; > + =A0record_ops.to_stopped_by_watchpoint =3D record_stopped_by_watchpoint; > =A0 record_ops.to_magic =3D OPS_MAGIC; > =A0} > > @@ -1807,6 +1853,7 @@ > =A0 /* Add bookmark target methods. =A0*/ > =A0 record_core_ops.to_get_bookmark =3D record_get_bookmark; > =A0 record_core_ops.to_goto_bookmark =3D record_goto_bookmark; > + =A0record_core_ops.to_stopped_by_watchpoint =3D record_stopped_by_watch= point; > =A0 record_core_ops.to_magic =3D OPS_MAGIC; > =A0} > > Index: gdb/NEWS > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gdb.orig/NEWS =A0 =A0 =A0 2009-11-05 09:54:36.000000000 -0800 > +++ gdb/NEWS =A0 =A02009-11-05 10:13:18.000000000 -0800 > @@ -88,6 +88,10 @@ > =A0 creates a new one. =A0This is useful to be able to restart the old > =A0 executable after the inferior having done an exec call. > > +* Bug fixes > + > +Process record now works correctly with hardware watchpoints. > + > =A0*** Changes in GDB 7.0 > > =A0* GDB now has an interface for JIT compilation. =A0Applications that > Index: gdb/testsuite/gdb.reverse/watch-reverse.exp > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gdb.orig/testsuite/gdb.reverse/watch-reverse.exp =A0 =A02009-11-05 > 09:54:36.000000000 -0800 > +++ gdb/testsuite/gdb.reverse/watch-reverse.exp 2009-11-05 > 10:13:18.000000000 -0800 > @@ -38,8 +38,8 @@ > =A0 =A0 # FIXME: command ought to acknowledge, so we can test if it succe= eded. > =A0} > > -# Only software watchpoints can be used in reverse > -gdb_test "set can-use-hw-watchpoints 0" "" "" > +# Test software watchpoints > +gdb_test "set can-use-hw-watchpoints 0" "" "disable hw watchpoints" > > =A0gdb_test "break marker1" \ > =A0 =A0 "Breakpoint $decimal at $hex: file .*$srcfile, line $decimal.*" \ > @@ -122,3 +122,81 @@ > =A0gdb_test "continue" \ > =A0 =A0 ".*\[Ww\]atchpoint.*ival3.*Old value =3D 0.*New value =3D -1.*iva= l3 =3D count; > ival4 =3D count;.*" \ > =A0 =A0 "watchpoint hit in reverse, fifth time" > + > +gdb_test "set can-use-hw-watchpoints 1" "" "enable hw watchpoints" > + > +### > +### > +### > + > +# FIXME 'set exec-dir' command should give some output so we can test. > +gdb_test "set exec-direction forward" "" "set forward" > + > +# Continue until first change, from -1 to 0 > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D -1.*New value =3D 0.*iv= al3 =3D > count; ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, first time" > + > +# Continue until the next change, from 0 to 1. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 0.*New value =3D 1.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, second time" > + > +# Continue until the next change, from 1 to 2. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 1.*New value =3D 2.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, third time" > + > +# Continue until the next change, from 2 to 3. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 2.*New value =3D 3.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, fourth time" > + > +# Continue until the next change, from 3 to 4. > +# Note that this one is outside the loop. > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 3.*New value =3D 4.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, fifth time" > + > +# Continue until we hit the finishing marker function. > +# Make sure we hit no more watchpoints. > + > +gdb_test "continue" "marker2 .*" "replay forward to marker2" > + > +### > +### > +### > + > +# FIXME 'set exec-dir' command should give some output so we can test. > +gdb_test "set exec-direction reverse" "" "set reverse" > + > +# Reverse until the previous change, from 4 to 3 > +# Note that this one is outside the loop > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 4.*New value =3D 3.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, first time" > + > +# Reverse until the previous change, from 3 to 2. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 3.*New value =3D 2.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, second time" > + > +# Reverse until the previous change, from 2 to 1. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 2.*New value =3D 1.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, third time" > + > +# Reverse until the previous change, from 1 to 0. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 1.*New value =3D 0.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, fourth time" > + > +# Reverse until first change, from 0 to -1 > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 0.*New value =3D -1.*iv= al3 =3D > count; ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, fifth time" > + > Index: gdb/testsuite/gdb.reverse/watch-precsave.exp > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gdb.orig/testsuite/gdb.reverse/watch-precsave.exp =A0 2009-11-05 > 09:54:36.000000000 -0800 > +++ gdb/testsuite/gdb.reverse/watch-precsave.exp =A0 =A0 =A0 =A02009-11-05 > 10:13:18.000000000 -0800 > @@ -1,4 +1,4 @@ > -# Copyright 2008, 2009 Free Software Foundation, Inc. > +# Copyright 2009 Free Software Foundation, Inc. > > =A0# This program is free software; you can redistribute it and/or modify > =A0# it under the terms of the GNU General Public License as published by > @@ -140,3 +140,81 @@ > =A0gdb_test "continue" \ > =A0 =A0 ".*\[Ww\]atchpoint.*ival3.*Old value =3D 0.*New value =3D -1.*iva= l3 =3D count; > ival4 =3D count;.*" \ > =A0 =A0 "watchpoint hit in reverse, fifth time" > + > +gdb_test "set can-use-hw-watchpoints 1" "" "enable hw watchpoints" > + > +### > +### > +### > + > +# FIXME 'set exec-dir' command should give some output so we can test. > +gdb_test "set exec-direction forward" "" "set forward" > + > +# Continue until first change, from -1 to 0 > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D -1.*New value =3D 0.*iv= al3 =3D > count; ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, first time" > + > +# Continue until the next change, from 0 to 1. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 0.*New value =3D 1.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, second time" > + > +# Continue until the next change, from 1 to 2. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 1.*New value =3D 2.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, third time" > + > +# Continue until the next change, from 2 to 3. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 2.*New value =3D 3.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, fourth time" > + > +# Continue until the next change, from 3 to 4. > +# Note that this one is outside the loop. > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 3.*New value =3D 4.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit, forward replay, fifth time" > + > +# Continue until we hit the finishing marker function. > +# Make sure we hit no more watchpoints. > + > +gdb_test "continue" "marker2 .*" "replay forward to marker2" > + > +### > +### > +### > + > +# FIXME 'set exec-dir' command should give some output so we can test. > +gdb_test "set exec-direction reverse" "" "set reverse" > + > +# Reverse until the previous change, from 4 to 3 > +# Note that this one is outside the loop > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 4.*New value =3D 3.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, first time" > + > +# Reverse until the previous change, from 3 to 2. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 3.*New value =3D 2.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, second time" > + > +# Reverse until the previous change, from 2 to 1. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 2.*New value =3D 1.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, third time" > + > +# Reverse until the previous change, from 1 to 0. > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 1.*New value =3D 0.*iva= l3 =3D count; > ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, fourth time" > + > +# Reverse until first change, from 0 to -1 > + > +gdb_test "continue" \ > + =A0 =A0".*\[Ww\]atchpoint.*ival3.*Old value =3D 0.*New value =3D -1.*iv= al3 =3D > count; ival4 =3D count;.*" \ > + =A0 =A0"watchpoint hit in reverse, HW, fifth time" > + > >