- Set the breakpoints always to all the ctors/dtors variants (BZ 301701).

- Fix non-threaded watchpoints CTRL-C regression on `set follow child'.
- Fix hardware watchpoints after inferior forks-off some process.
This commit is contained in:
Jan Kratochvil 2007-10-14 21:11:56 +00:00
parent 31f942e84f
commit 42bbf11750
6 changed files with 657 additions and 5 deletions

View File

@ -5,10 +5,28 @@
* linespec.c (add_minsym_members): Support also the `$allocate' and
`$delete' variants.
2007-10-05 Jan Kratochvil <jan.kratochvil@redhat.com>
* linespec.c (add_minsym_members): Support also the `$allocate' and
`$delete' variants.
(decode_variable): Renamed to ...
(decode_variable_1) ... here, its parameter NOT_FOUND_PTR and its
exception throwing was moved to ...
(decode_variable_not_found): ... a new function here.
(decode_variable): New function.
Index: gdb-6.5/gdb/linespec.c
===================================================================
--- gdb-6.5.orig/gdb/linespec.c 2006-01-10 20:14:43.000000000 -0200
+++ gdb-6.5/gdb/linespec.c 2006-07-07 01:04:56.000000000 -0300
@@ -37,6 +37,7 @@
#include "objc-lang.h"
#include "linespec.h"
#include "exceptions.h"
+#include "gdb_assert.h"
/* We share this one with symtab.c, but it is not exported widely. */
@@ -75,7 +75,8 @@ static struct symtabs_and_lines find_met
struct symbol *sym_class);
@ -438,3 +456,191 @@ Index: gdb-6.5/gdb/linespec.c
return i1;
}
@@ -1976,12 +2021,13 @@ decode_dollar (char *copy, int funfirstl
and do not issue an error message. */
static struct symtabs_and_lines
-decode_variable (char *copy, int funfirstline, char ***canonical,
- struct symtab *file_symtab, int *not_found_ptr)
+decode_variable_1 (char *copy, int funfirstline, char ***canonical,
+ struct symtab *file_symtab)
{
struct symbol *sym;
/* The symtab that SYM was found in. */
struct symtab *sym_symtab;
+ struct symtabs_and_lines retval;
struct minimal_symbol *msymbol;
@@ -2001,8 +2047,25 @@ decode_variable (char *copy, int funfirs
msymbol = lookup_minimal_symbol (copy, NULL, NULL);
if (msymbol != NULL)
- return minsym_found (funfirstline, msymbol);
+ {
+ retval = minsym_found (funfirstline, msymbol);
+
+ /* Create a `filename:linkage_symbol_name' reference. */
+ if (file_symtab == 0)
+ build_canonical_line_spec (retval.sals, SYMBOL_LINKAGE_NAME (msymbol),
+ canonical);
+
+ return retval;
+ }
+ retval.nelts = 0;
+ retval.sals = NULL;
+ return retval;
+}
+
+static void
+decode_variable_not_found (char *copy, int *not_found_ptr)
+{
if (!have_full_symbols () &&
!have_partial_symbols () && !have_minimal_symbols ())
error (_("No symbol table is loaded. Use the \"file\" command."));
@@ -2010,6 +2064,132 @@ decode_variable (char *copy, int funfirs
throw_error (NOT_FOUND_ERROR, _("Function \"%s\" not defined."), copy);
}
+/* Wrapper of DECODE_VARIABLE_1 collecting the results for all the found
+ VARIANTS of the symbol COPY. */
+
+static struct symtabs_and_lines
+decode_variable (char *copy, int funfirstline, char ***canonical,
+ struct symtab *file_symtab, int *not_found_ptr)
+{
+ char *src;
+ char *src_point;
+ char *s, *point;
+ /* Keep "" last as the trimming part always matches it. */
+ const char *variants[] = {"$base","$allocate","$delete",""};
+ int i;
+ char *dst, *dst_point;
+ struct
+ {
+ struct symtabs_and_lines sals;
+ char **canonical;
+ } found[ARRAY_SIZE (variants)];
+ struct symtabs_and_lines retval_sals;
+ char **retval_canonical = NULL; /* Shut up GCC. */
+ int filled;
+ int canonicals = 0; /* Shut up GCC. */
+
+ src = copy;
+ src_point = strchr (src, '(');
+ if (src_point == NULL)
+ {
+ struct symtabs_and_lines sals;
+
+ sals = decode_variable_1 (src, funfirstline, canonical, file_symtab);
+ if (sals.nelts > 0)
+ return sals;
+ decode_variable_not_found (copy, not_found_ptr);
+ /* NOTREACHED */
+ }
+
+ dst = xmalloc (strlen (src) + strlen ("$allocate") + 1);
+ dst_point = dst + (src_point - src);
+
+ memcpy (dst, src, src_point - src);
+
+ /* Trim out any variant markers there first. */
+ for (i = 0; i < ARRAY_SIZE (variants); i++)
+ {
+ size_t len = strlen (variants[i]);
+
+ if (dst_point - dst >= len
+ && memcmp (dst_point - len, variants[i], len) == 0)
+ {
+ dst_point -= len;
+ /* In fact it should not be needed here. */
+ break;
+ }
+ }
+
+ filled = 0;
+ /* And now try to append all of them. */
+ for (i = 0; i < ARRAY_SIZE (variants); i++)
+ {
+ size_t len = strlen (variants[i]);
+ struct minimal_symbol *minsym2;
+
+ memcpy (dst_point, variants[i], len);
+ strcpy (dst_point + len, src_point);
+
+ found[i].canonical = NULL;
+ found[i].sals = decode_variable_1 (dst, funfirstline,
+ (canonical == NULL ? NULL
+ : &found[i].canonical),
+ file_symtab);
+ filled += found[i].sals.nelts;
+ }
+ xfree (dst);
+ if (filled == 0)
+ {
+ decode_variable_not_found (copy, not_found_ptr);
+ /* NOTREACHED */
+ }
+
+ retval_sals.nelts = filled;
+ retval_sals.sals = xmalloc (filled * sizeof *retval_sals.sals);
+ if (canonical != NULL)
+ {
+ retval_canonical = xmalloc (filled * sizeof *retval_canonical);
+ canonicals = 0;
+ }
+ filled = 0;
+ for (i = 0; i < ARRAY_SIZE (variants); i++)
+ {
+ memcpy (&retval_sals.sals[filled], found[i].sals.sals,
+ found[i].sals.nelts * sizeof *retval_sals.sals);
+ xfree (found[i].sals.sals);
+ if (canonical != NULL)
+ {
+ if (found[i].canonical == NULL)
+ memset (&retval_canonical[filled], 0,
+ found[i].sals.nelts * sizeof *retval_canonical);
+ else
+ {
+ int j;
+
+ memcpy (&retval_canonical[filled], found[i].canonical,
+ found[i].sals.nelts * sizeof *retval_canonical);
+ for (j = 0; j < found[i].sals.nelts; j++)
+ if (found[i].canonical[j] != NULL)
+ canonicals++;
+ xfree (found[i].canonical);
+ }
+ }
+ filled += found[i].sals.nelts;
+ }
+ gdb_assert (filled == retval_sals.nelts);
+
+ if (canonical != NULL)
+ {
+ if (canonicals != 0)
+ *canonical = retval_canonical;
+ else
+ {
+ *canonical = NULL;
+ xfree (retval_canonical);
+ }
+ }
+ return retval_sals;
+}
diff -u -rup gdb-6.6-orig/gdb/Makefile.in gdb-6.6/gdb/Makefile.in
--- gdb-6.6-orig/gdb/Makefile.in 2007-10-05 15:22:37.000000000 +0200
+++ gdb-6.6/gdb/Makefile.in 2007-10-05 16:29:10.000000000 +0200
@@ -2266,7 +2266,7 @@ libunwind-frame.o: libunwind-frame.c $(d
linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
$(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
$(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) \
- $(objc_lang_h) $(linespec_h) $(exceptions_h)
+ $(objc_lang_h) $(linespec_h) $(exceptions_h) $(gdb_assert_h)
linux-fork.o: linux-fork.c $(defs_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) \
$(infcall_h) $(gdb_assert_h) $(gdb_string_h) $(linux_fork_h) \
$(linux_nat_h)

View File

@ -1,3 +1,14 @@
[base]
2007-10-13 Jan Kratochvil <jan.kratochvil@redhat.com>
* linux-nat.c (iterate_over_lwps): Fixed missing LWP initialization for
current INFERIOR_PTID.
2007-10-13 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/follow-child.exp, gdb.base/follow-child.c: New files.
Index: gdb-6.6/gdb/doc/observer.texi
===================================================================
--- gdb-6.6.orig/gdb/doc/observer.texi
@ -17,7 +28,7 @@ Index: gdb-6.6/gdb/linux-nat.c
===================================================================
--- gdb-6.6.orig/gdb/linux-nat.c
+++ gdb-6.6/gdb/linux-nat.c
@@ -803,11 +803,23 @@ iterate_over_lwps (int (*callback) (stru
@@ -803,11 +803,26 @@ iterate_over_lwps (int (*callback) (stru
{
struct lwp_info *lp, *lpnext;
@ -36,8 +47,11 @@ Index: gdb-6.6/gdb/linux-nat.c
+ {
+ /* We are calling iterate_over_lwps for a non-threaded program.
+ Initialize the lwp list to the inferior's ptid. */
+ lp = add_lwp (BUILD_LWP (GET_PID (inferior_ptid),
+ GET_PID (inferior_ptid)));
+ gdb_assert (!is_lwp (inferior_ptid));
+
+ inferior_ptid = BUILD_LWP (GET_PID (inferior_ptid),
+ GET_PID (inferior_ptid));
+ lp = add_lwp (inferior_ptid);
if ((*callback) (lp, data))
- return lp;
+ return lp;
@ -112,3 +126,95 @@ Index: gdb-6.6/gdb/target.h
/* Does target have enough data to do a run or attach command? */
diff -u -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-orig/gdb/testsuite/gdb.base/follow-child.c gdb-6.6/gdb/testsuite/gdb.base/follow-child.c
--- gdb-6.6-orig/gdb/testsuite/gdb.base/follow-child.c 2007-10-13 19:24:58.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.base/follow-child.c 2007-10-13 19:11:08.000000000 +0200
@@ -0,0 +1,29 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2007 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ Please email any bugs, comments, and/or additions to this file to:
+ bug-gdb@prep.ai.mit.edu */
+
+#include <unistd.h>
+
+int main()
+{
+ fork ();
+ sleep (60);
+ return 0;
+}
diff -u -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-orig/gdb/testsuite/gdb.base/follow-child.exp gdb-6.6/gdb/testsuite/gdb.base/follow-child.exp
--- gdb-6.6-orig/gdb/testsuite/gdb.base/follow-child.exp 2007-10-13 19:24:58.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.base/follow-child.exp 2007-10-13 19:24:21.000000000 +0200
@@ -0,0 +1,55 @@
+# Copyright 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile follow-child
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# For C programs, "start" should stop in main().
+
+gdb_test "set follow-fork-mode child" ""
+set test "started"
+# GDB_RUN_CMD already checks for `Starting program:'.
+gdb_run_cmd
+sleep 5
+send_gdb "\003"
+set test "break"
+gdb_test_multiple "" $test {
+ -re "Program received signal SIGINT.*$gdb_prompt $" {
+ pass $test
+ }
+ -re "\\\[New process \[0-9\]+\\\]" {
+ fail $test
+ }
+}

View File

@ -19,6 +19,8 @@ Index: gdb/testsuite/ChangeLog
* gdb.cp/constructortest.exp: Test BREAKPOINT_RE_SET for multiple PCs
by PIE.
* gdb.cp/constructortest.exp: Handle the change of settings breakpoints
always at all the ctor/dtor variants.
--- gdb-6.3/gdb/testsuite/gdb.cp/constructortest.cc.fix Fri Jan 21 17:06:56 2005
+++ gdb-6.3/gdb/testsuite/gdb.cp/constructortest.cc Fri Jan 21 17:05:18 2005
@ -124,7 +126,7 @@ Index: gdb/testsuite/ChangeLog
+}
--- gdb-6.3/gdb/testsuite/gdb.cp/constructortest.exp.fix Fri Jan 21 17:07:02 2005
+++ gdb-6.3/gdb/testsuite/gdb.cp/constructortest.exp Fri Jan 21 17:05:29 2005
@@ -0,0 +1,145 @@
@@ -0,0 +1,148 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2005, 2007 Free Software Foundation, Inc.
@ -222,6 +224,9 @@ Index: gdb/testsuite/ChangeLog
+gdb_test "break $second_line_dtor" ".*$second_line_dtor.*$second_line_dtor.*Multiple breakpoints were set.*" "break by line in destructor"
+gdb_continue_to_breakpoint "Second line ~A"
+gdb_test "bt" "#0.*A.*#1.*main.*" "Verify in in-charge A::~A second line"
+# FIXME: Analyse this case better.
+gdb_continue_to_breakpoint "Second line ~A"
+gdb_test "bt" "#0.*A.*#1.*main.*" "Verify in A::~A second line #2"
+gdb_continue_to_breakpoint "Second line ~A"
+gdb_test "bt" "#0.*A.*#1.*B.*#2.*main.*" "Verify in not-in-charge A::~A second line"
+

View File

@ -0,0 +1,284 @@
2007-10-14 Jan Kratochvil <jan.kratochvil@redhat.com>
Handle multiple different PIDs for the DR registers.
* i386-nat.c: Include "inferior.h".
(struct dr_mirror_status, dr_mirror_active, dr_mirror_fetch): New.
(dr_mirror, dr_status_mirror, dr_control_mirror, dr_ref_count):
Redefined using DR_MIRROR_ACTIVE.
(i386_cleanup_dregs): Clear the DR_MIRROR_ACTIVE content instead.
(i386_show_dr, i386_insert_aligned_watchpoint)
(i386_remove_aligned_watchpoint, i386_stopped_data_address)
(i386_stopped_by_hwbp): Call DR_MIRROR_FETCH.
* Makefile.in (i386-nat.o): Update dependencies.
2007-10-14 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/watchpoint-fork.exp, gdb.base/watchpoint-fork.c: New files.
[ Backported for GDB-6.6 (only removed the new file inclusion). ]
--- ./gdb/i386-nat.c 23 Aug 2007 18:08:34 -0000 1.16
+++ ./gdb/i386-nat.c 14 Oct 2007 15:00:31 -0000
@@ -165,11 +166,22 @@
/* Mirror the inferior's DRi registers. We keep the status and
control registers separated because they don't hold addresses. */
-static CORE_ADDR dr_mirror[DR_NADDR];
-static unsigned dr_status_mirror, dr_control_mirror;
+struct dr_mirror_status
+ {
+ /* Cyclic list. */
+ struct dr_mirror_status *next;
+ long lwp;
+ CORE_ADDR addr[DR_NADDR];
+ unsigned status, control;
+ int ref_count[DR_NADDR];
+ };
+struct dr_mirror_status *dr_mirror_active;
+#define dr_mirror (dr_mirror_active->addr)
+#define dr_status_mirror (dr_mirror_active->status)
+#define dr_control_mirror (dr_mirror_active->control)
/* Reference counts for each debug register. */
-static int dr_ref_count[DR_NADDR];
+#define dr_ref_count (dr_mirror_active->ref_count)
/* Whether or not to print the mirrored debug registers. */
static int maint_show_dr;
@@ -218,15 +230,19 @@ static int i386_handle_nonaligned_watchp
void
i386_cleanup_dregs (void)
{
- int i;
+ struct dr_mirror_status *first = dr_mirror_active;
- ALL_DEBUG_REGISTERS(i)
+ if (first == NULL)
+ return;
+ do
{
- dr_mirror[i] = 0;
- dr_ref_count[i] = 0;
+ struct dr_mirror_status *next = dr_mirror_active->next;
+
+ xfree (dr_mirror_active);
+ dr_mirror_active = next;
}
- dr_control_mirror = 0;
- dr_status_mirror = 0;
+ while (dr_mirror_active != first);
+ dr_mirror_active = NULL;
}
/* Reset all debug registers at each new startup to avoid missing
@@ -238,6 +254,40 @@ child_post_startup_inferior (ptid_t ptid
i386_cleanup_dregs ();
}
+static void
+dr_mirror_fetch (void)
+{
+ long lwp;
+ int i;
+
+ lwp = ptid_get_lwp (inferior_ptid);
+ if (lwp == 0)
+ lwp = ptid_get_pid (inferior_ptid);
+
+ if (dr_mirror_active == NULL)
+ {
+ dr_mirror_active = xzalloc (sizeof *dr_mirror_active);
+ dr_mirror_active->next = dr_mirror_active;
+ }
+ else
+ {
+ struct dr_mirror_status *first = dr_mirror_active;
+ do
+ {
+ if (dr_mirror_active->lwp == lwp)
+ return;
+ dr_mirror_active = dr_mirror_active->next;
+ }
+ while (dr_mirror_active != first);
+ dr_mirror_active = xzalloc (sizeof *dr_mirror_active);
+ dr_mirror_active->next = first->next;
+ first->next = dr_mirror_active;
+ }
+ dr_mirror_active->lwp = lwp;
+
+ /* All the registers left 0. */
+}
+
/* Print the values of the mirrored debug registers. This is called
when maint_show_dr is non-zero. To set that up, type "maint
show-debug-regs" at GDB's prompt. */
@@ -248,6 +298,8 @@ i386_show_dr (const char *func, CORE_ADD
{
int i;
+ dr_mirror_fetch ();
+
puts_unfiltered (func);
if (addr || len)
printf_unfiltered (" (addr=%lx, len=%d, type=%s)",
@@ -337,6 +389,8 @@ i386_insert_aligned_watchpoint (CORE_ADD
{
int i;
+ dr_mirror_fetch ();
+
/* First, look for an occupied debug register with the same address
and the same RW and LEN definitions. If we find one, we can
reuse it for this watchpoint as well (and save a register). */
@@ -397,6 +451,8 @@ i386_remove_aligned_watchpoint (CORE_ADD
{
int i, retval = -1;
+ dr_mirror_fetch ();
+
ALL_DEBUG_REGISTERS(i)
{
if (!I386_DR_VACANT (i)
@@ -569,6 +625,8 @@ i386_stopped_data_address (CORE_ADDR *ad
int i;
int rc = 0;
+ dr_mirror_fetch ();
+
dr_status_mirror = I386_DR_LOW_GET_STATUS ();
ALL_DEBUG_REGISTERS(i)
@@ -610,6 +668,8 @@ i386_stopped_by_hwbp (void)
{
int i;
+ dr_mirror_fetch ();
+
dr_status_mirror = I386_DR_LOW_GET_STATUS ();
if (maint_show_dr)
i386_show_dr ("stopped_by_hwbp", 0, 0, hw_execute);
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/watchpoint-fork.c 14 Oct 2007 15:00:32 -0000
@@ -0,0 +1,73 @@
+/* Test case for forgotten hw-watchpoints after fork()-off of a process.
+
+ Copyright 2007
+ Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <assert.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static volatile int var;
+
+static void breakpoint (void)
+{
+}
+
+static void forkoff (int nr)
+{
+ pid_t child, pid_got;
+ int exit_code = 42 + nr;
+ int status;
+
+ child = fork ();
+ switch (child)
+ {
+ case -1:
+ assert (0);
+ case 0:
+ printf ("child%d: %d\n", nr, (int) getpid ());
+ breakpoint ();
+ exit (exit_code);
+ default:
+ printf ("parent%d: %d\n", nr, (int) child);
+ pid_got = wait (&status);
+ assert (pid_got == child);
+ assert (WIFEXITED (status));
+ assert (WEXITSTATUS (status) == exit_code);
+ }
+}
+
+int main (void)
+{
+ setbuf (stdout, NULL);
+ printf ("main: %d\n", (int) getpid ());
+
+ /* Hardware watchpoints got disarmed here. */
+ forkoff (1);
+ /* This watchpoint got lost before. */
+ var++;
+ /* A sanity check for double hardware watchpoints removal. */
+ forkoff (2);
+ var++;
+
+ return 0;
+}
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ./gdb/testsuite/gdb.base/watchpoint-fork.exp 14 Oct 2007 15:00:32 -0000
@@ -0,0 +1,46 @@
+# Copyright 2007 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile watchpoint-fork
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+gdb_test "watch var" "atchpoint 1: var"
+# It is never hit but it should not be left over in the fork()ed-off child.
+gdb_breakpoint "breakpoint"
+gdb_run_cmd
+gdb_test "" \
+ "atchpoint 1: var.*Old value = 0.*New value = 1.*" "watchpoint first hit"
+gdb_test "continue" \
+ "atchpoint 1: var.*Old value = 1.*New value = 2.*" "watchpoint second hit"
+gdb_test "continue" "Continuing..*Program exited normally." "finish"

View File

@ -1244,3 +1244,45 @@ https://bugzilla.redhat.com/show_bug.cgi?id=328021
return TD_NOTHR;
/* Note the cast through uintptr_t: this interface only works if
http://sources.redhat.com/ml/gdb-patches/2007-07/msg00034.html
2007-07-02 Daniel Jacobowitz <dan@codesourcery.com>
* breakpoint.c (reattach_breakpoints): Do not use remove_breakpoint.
Call insert_bp_location.
[ Backported. ]
--- gdb-6.6/gdb/breakpoint.c.orig 2007-10-14 17:42:36.000000000 +0200
+++ gdb-6.6/gdb/breakpoint.c 2007-10-14 17:45:57.000000000 +0200
@@ -1313,20 +1313,19 @@
struct bp_location *b;
int val;
struct cleanup *old_chain = save_inferior_ptid ();
+ struct ui_file *tmp_error_stream = mem_fileopen ();
+ int dummy1 = 0, dummy2 = 0, dummy3 = 0;
+
+ make_cleanup_ui_file_delete (tmp_error_stream);
- /* Set inferior_ptid; remove_breakpoint uses this global. */
inferior_ptid = pid_to_ptid (pid);
ALL_BP_LOCATIONS (b)
{
if (b->inserted)
{
- remove_breakpoint (b, mark_inserted);
- if (b->loc_type == bp_loc_hardware_breakpoint)
- val = target_insert_hw_breakpoint (&b->target_info);
- else
- val = target_insert_breakpoint (&b->target_info);
- /* FIXME drow/2003-10-07: This doesn't handle any other kinds of
- breakpoints. It's wrong for watchpoints, for example. */
+ b->inserted = 0;
+ val = insert_bp_location (b, tmp_error_stream,
+ &dummy1, &dummy2, &dummy3);
if (val != 0)
{
do_cleanups (old_chain);

View File

@ -11,7 +11,7 @@ Name: gdb
Version: 6.6
# The release always contains a leading reserved number, start it at 1.
Release: 33%{?dist}
Release: 34%{?dist}
License: GPL
Group: Development/Debuggers
@ -383,6 +383,9 @@ Patch277: gdb-6.6-vdso-i386-on-amd64-warning.patch
# Fix debug load for sparse assembler files (such as vDSO32 for i386-on-x86_64).
Patch278: gdb-6.6-cu-ranges.patch
# Fix hardware watchpoints after inferior forks-off some process.
Patch280: gdb-6.6-multifork-debugreg-for-i386-and-x86_64.patch
BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext
BuildRequires: flex bison sharutils expat-devel
Requires: readline
@ -541,6 +544,7 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
%patch276 -p1
%patch277 -p1
%patch278 -p1
%patch280 -p1
# Change the version that gets printed at GDB startup, so it is RedHat
# specific.
@ -697,6 +701,11 @@ fi
# don't include the files in include, they are part of binutils
%changelog
* Sun Oct 14 2007 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.6-34
- Set the breakpoints always to all the ctors/dtors variants (BZ 301701).
- Fix non-threaded watchpoints CTRL-C regression on `set follow child'.
- Fix hardware watchpoints after inferior forks-off some process.
* Thu Oct 11 2007 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.6-33
- Fix gdbserver for threaded applications and recent glibc (BZ 328021).