old-cross-binutils/gdb/testsuite/gdb.base/watch-bitfields.c
Patrick Palka bb9d5f81c3 Fix PR12526: -location watchpoints for bitfield arguments
PR 12526 reports that -location watchpoints against bitfield arguments
trigger false positives when bits around the bitfield, but not the
bitfield itself, are modified.

This happens because -location watchpoints naturally operate at the
byte level, not at the bit level.  When the address of a bitfield
lvalue is taken, information about the bitfield (i.e. its offset and
size) is lost in the process.

This information must first be retained throughout the lifetime of the
-location watchpoint.  This patch achieves this by adding two new
fields to the watchpoint struct: val_bitpos and val_bitsize.  These
fields are set when a watchpoint is first defined in watch_command_1.
They are both equal to zero if the watchpoint is not a -location
watchpoint or if the argument is not a bitfield.

Then these bitfield parameters are used inside update_watchpoint and
watchpoint_check to extract the actual value of the bitfield from the
watchpoint address, with the help of a local helper function
extract_bitfield_from_watchpoint_value.

Finally when creating a HW breakpoint pointing to a bitfield, we
optimize the address and length of the breakpoint.  By skipping over
the bytes that don't cover the bitfield, this step reduces the
frequency at which a read watchpoint for the bitfield is triggered.
It also reduces the number of times a false-positive call to
check_watchpoint is triggered for a write watchpoint.

gdb/
	PR breakpoints/12526
	* breakpoint.h (struct watchpoint): New fields val_bitpos and
	val_bitsize.
	* breakpoint.c (watch_command_1): Use these fields to retain
	bitfield information.
	(extract_bitfield_from_watchpoint_value): New function.
	(watchpoint_check): Use it.
	(update_watchpoint): Use it.  Optimize the address and length of a
	HW watchpoint pointing to a bitfield.
	* value.h (unpack_value_bitfield): New prototype.
	* value.c (unpack_value_bitfield): Make extern.

gdb/testsuite/
	PR breakpoints/12526
	* gdb.base/watch-bitfields.exp: New file.
	* gdb.base/watch-bitfields.c: New file.
2014-09-16 17:40:06 +01:00

54 lines
1.1 KiB
C

/* This testcase is part of GDB, the GNU debugger.
Copyright 2014 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/>. */
struct foo
{
unsigned long a:1;
unsigned char b:2;
unsigned long c:3;
char d:4;
int e:5;
char f:6;
int g:7;
long h:8;
} q = { 0 };
int
main (void)
{
q.a = 1;
q.b = 2;
q.c = 3;
q.d = 4;
q.e = 5;
q.f = 6;
q.g = -7;
q.h = -8;
q.a--;
q.h--;
q.c--;
q.b--;
q.e--;
q.d--;
q.c--;
q.f--;
q.g--;
q.h--;
return 0;
}