This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Fix shadow restoration when we have multiple locations at the same address
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Mon, 27 Dec 2010 20:04:45 +0000
- Subject: Fix shadow restoration when we have multiple locations at the same address
I was going to suggest to Yao to run the whole testsuite with
displaced stepping enabled, thought to try it first on x86_64
to see if it had regressed since last time I had tried
that myself. Well, a bunch of failures on break.exp appeared,
which, simplified, amount to:
> ./gdb -ex "set displaced on" -ex "set debug displaced on" ./testsuite/gdb.base/break
...
(gdb) b main
Breakpoint 1 at 0x4006a7: file ../../../src/gdb/testsuite/gdb.base/break.c, line 93.
(gdb) b mainb
(gdb) b main
Note: breakpoint 1 also set at pc 0x4006a7.
Breakpoint 2 at 0x4006a7: file ../../../src/gdb/testsuite/gdb.base/break.c, line 93.
(gdb) r
Starting program: /home/pedro/gdb/baseline/build/gdb/testsuite/gdb.base/break
displaced: stepping process 27496 now
displaced: saved 0x4005a2: 49 89 d1 5e 48 89 e2 48 83 e4 f0 50 54 49 c7 c0
displaced: copy 0x7ffff7dec5c0->0x4005a2: f3 c3 90 90 90 90 90 90 90 90 90 90 90 90 90 90
displaced: displaced pc to 0x4005a2
displaced: run 0x4005a2: f3 c3 90 90
displaced: restored 0x4005a2
displaced: fixup (0x7ffff7dec5c0, 0x4005a2), insn = 0xf3 0xc3 ...
displaced: stepping process 27496 now
displaced: saved 0x4005a2: 49 89 d1 5e 48 89 e2 48 83 e4 f0 50 54 49 c7 c0
displaced: copy 0x7ffff7dec5c0->0x4005a2: f3 c3 90 90 90 90 90 90 90 90 90 90 90 90 90 90
displaced: displaced pc to 0x4005a2
displaced: run 0x4005a2: f3 c3 90 90
displaced: restored 0x4005a2
displaced: fixup (0x7ffff7dec5c0, 0x4005a2), insn = 0xf3 0xc3 ...
Breakpoint 1, main (argc=1, argv=0x7fffffffe0d8, envp=0x7fffffffe0e8) at ../../../src/gdb/testsuite/gdb.base/break.c:93
93 if (argc == 12345) { /* an unlikely value < 2^16, in case uninited */ /* set breakpoint 6 here */
(gdb) c
Continuing.
displaced: stepping process 27496 now
displaced: saved 0x4005a2: 49 89 d1 5e 48 89 e2 48 83 e4 f0 50 54 49 c7 c0
displaced: copy 0x4006a7->0x4005a2: cc 7d fc 39 30 00 00 75 2e 48 8b 05 89 09 20 00
displaced: displaced pc to 0x4005a2
displaced: run 0x4005a2: cc 7d fc 39
displaced: restored 0x4005a2
displaced: fixup (0x4006a7, 0x4005a2), insn = 0xcc 0x7d ...
displaced: relocated %rip from 0x4005a3 to 0x4006a8
Program received signal SIGSEGV, Segmentation fault.
0x000000003a3c8477 in ?? ()
(gdb)
Notice:
> displaced: copy 0x4006a7->0x4005a2: cc 7d fc 39 30 00 00 75 2e 48 8b 05 89 09 20 00
^^
CC is the breakpoint insn. This revealed that we had a
bug in the shadow restoration code when we have multiple locations
at the same address. Fixed as below. Applied on HEAD and 7.2 branch.
--
Pedro Alves
2010-12-27 Pedro Alves <pedro@codesourcery.com>
gdb/
* breakpoint.c (breakpoint_restore_shadows): When looking for the
location with the lowest address that overlaps the memory range we
want to restore shadows for, account for multiple locations at the
same address.
---
gdb/breakpoint.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c 2010-12-27 19:34:39.000000000 +0000
+++ src/gdb/breakpoint.c 2010-12-27 19:35:11.000000000 +0000
@@ -1130,6 +1130,23 @@ breakpoint_restore_shadows (gdb_byte *bu
bc_r = bc;
}
+ /* Due to the binary search above, we need to make sure we pick the
+ first location that's at BC_L's address. E.g., if there are
+ multiple locations at the same address, BC_L may end up pointing
+ at a duplicate location, and miss the "master"/"inserted"
+ location. Say, given locations L1, L2 and L3 at addresses A and
+ B:
+
+ L1@A, L2@A, L3@B, ...
+
+ BC_L could end up pointing at location L2, while the "master"
+ location could be L1. Since the `loc->inserted' flag is only set
+ on "master" locations, we'd forget to restore the shadow of L1
+ and L2. */
+ while (bc_l > 0
+ && bp_location[bc_l]->address == bp_location[bc_l - 1]->address)
+ bc_l--;
+
/* Now do full processing of the found relevant range of elements. */
for (bc = bc_l; bc < bp_location_count; bc++)