bb9d5f81c3
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.
54 lines
1.1 KiB
C
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;
|
|
}
|