From e66408edfdc94395f4a59bbe360abb222ccc48ea Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Thu, 29 Apr 2010 16:33:16 +0000 Subject: [PATCH] PR gdb/11557 gdb/ * regcache.c (registers_changed): Rename to ... (registers_changed_ptid): ... this, and only delete register cache entries matching the ptid filter argument. (registers_changed): Reimplement on top of registers_changed_ptid. * regcache.h (registers_changed_ptid): Declare. * target.c (target_resume): Flush register caches. gdb/testsuite/ * gdb.mi/mi-ns-stale-regcache.exp, gdb.mi/ns-stale-regcache.c: New files. --- gdb/ChangeLog | 11 ++++ gdb/regcache.c | 29 +++++++-- gdb/regcache.h | 1 + gdb/target.c | 1 + gdb/testsuite/ChangeLog | 7 +++ gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp | 88 +++++++++++++++++++++++++++ gdb/testsuite/gdb.mi/ns-stale-regcache.c | 30 +++++++++ 7 files changed, 161 insertions(+), 6 deletions(-) create mode 100644 gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp create mode 100644 gdb/testsuite/gdb.mi/ns-stale-regcache.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7b9f195..86384a8 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2010-04-29 Pedro Alves + + PR gdb/11557 + + * regcache.c (registers_changed): Rename to ... + (registers_changed_ptid): ... this, and only delete register cache + entries matching the ptid filter argument. + (registers_changed): Reimplement on top of registers_changed_ptid. + * regcache.h (registers_changed_ptid): Declare. + * target.c (target_resume): Flush register caches. + 2010-04-29 Phil Muldoon Tom Tromey Thiago Jung Bauermann diff --git a/gdb/regcache.c b/gdb/regcache.c index d6f58fe..c3fcd9d 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -518,15 +518,27 @@ regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid) Indicate that registers may have changed, so invalidate the cache. */ void -registers_changed (void) +registers_changed_ptid (ptid_t ptid) { - struct regcache_list *list, *next; + struct regcache_list *list, **list_link; - for (list = current_regcache; list; list = next) + list = current_regcache; + list_link = ¤t_regcache; + while (list) { - next = list->next; - regcache_xfree (list->regcache); - xfree (list); + if (ptid_match (list->regcache->ptid, ptid)) + { + struct regcache_list *dead = list; + + *list_link = list->next; + regcache_xfree (list->regcache); + list = *list_link; + xfree (dead); + continue; + } + + list_link = &list->next; + list = *list_link; } current_regcache = NULL; @@ -545,6 +557,11 @@ registers_changed (void) alloca (0); } +void +registers_changed (void) +{ + registers_changed_ptid (minus_one_ptid); +} void regcache_raw_read (struct regcache *regcache, int regnum, gdb_byte *buf) diff --git a/gdb/regcache.h b/gdb/regcache.h index d870960..8cd40fa 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -159,5 +159,6 @@ extern void regcache_cpy (struct regcache *dest, struct regcache *src); extern void regcache_cpy_no_passthrough (struct regcache *dest, struct regcache *src); extern void registers_changed (void); +extern void registers_changed_ptid (ptid_t); #endif /* REGCACHE_H */ diff --git a/gdb/target.c b/gdb/target.c index 3d47cc4..f93a706 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -2192,6 +2192,7 @@ target_resume (ptid_t ptid, int step, enum target_signal signal) step ? "step" : "continue", target_signal_to_name (signal)); + registers_changed_ptid (ptid); set_executing (ptid, 1); set_running (ptid, 1); clear_inline_frame_state (ptid); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 5b276db..410d871 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-04-29 Pedro Alves + + PR gdb/11557 + + * gdb.mi/mi-ns-stale-regcache.exp, gdb.mi/ns-stale-regcache.c: New + files. + 2010-04-29 Phil Muldoon * gdb.python/py-param.exp: New File. diff --git a/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp new file mode 100644 index 0000000..a98e702 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-ns-stale-regcache.exp @@ -0,0 +1,88 @@ +# Copyright 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 +# 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 . + +# Regression test for PR11557. Make sure we don't end up with a stale +# register cache just after resuming a thread. + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if {[mi_gdb_start]} { + continue +} + +proc mi_nonstop_resume { command test } { + if { [mi_send_resuming_command $command $test] != 0 } { + # If a resume fails, assume non-stop is broken or unsupported + # for this target. We have logged a FAIL or UNSUPPORTED; skip + # the remaining tests to limit timeouts. + return -code continue + } +} + +# +# Start here +# +set testfile "ns-stale-regcache" +set srcfile "$testfile.c" +set binfile "$objdir/$subdir/mi-$testfile" + +set options [list debug incdir=$objdir] +if {[gdb_compile "$srcdir/$subdir/$srcfile" \ + $binfile executable $options] != "" } { + return -1 +} + +mi_gdb_reinitialize_dir $srcdir/$subdir +mi_gdb_load $binfile + +set supported 0 +send_gdb "-gdb-show non-stop\n" +gdb_expect { + -re ".*\\^done,value=\"off\",supported=\"(\[^\"\]+)\"\r\n$mi_gdb_prompt$" { + if { $expect_out(1,string) == "1" } { + set supported 1 + } + } + -re ".$mi_gdb_prompt$" { + } +} + +mi_gdb_test "-gdb-set non-stop 1" ".*" +mi_gdb_test "-gdb-set target-async 1" ".*" +detect_async + +if { [mi_run_to_main] < 0 } { + perror "mi-ns-stale-regcache.exp tests suppressed" + continue +} + +# Check that register and stack info don't end up stale after resuming +# a thread. +mi_nonstop_resume "exec-continue" "resume thread" + +mi_gdb_test "-data-evaluate-expression \$pc" \ + "\\^error,msg=\".*\"" "no stale register cache of resumed thread" + +mi_gdb_test "-stack-info-frame" \ + "\\^error,msg=\".*\"" "no stale frame info of resumed thread" + +# Check that the thread is still running. If the above tests passed, +# we want it to be for the right reasons. +mi_check_thread_states {"running"} "main thread still running" + +mi_gdb_exit diff --git a/gdb/testsuite/gdb.mi/ns-stale-regcache.c b/gdb/testsuite/gdb.mi/ns-stale-regcache.c new file mode 100644 index 0000000..0e51f75 --- /dev/null +++ b/gdb/testsuite/gdb.mi/ns-stale-regcache.c @@ -0,0 +1,30 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . +*/ + +#include + +int +main (int argc, char **argv) +{ + volatile int my_number = 1; + + while (my_number > 0) + { + usleep (1); + } +} -- 2.7.4