diff options
author | Pedro Alves <palves@redhat.com> | 2013-06-28 12:36:48 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2013-06-28 12:36:48 +0000 |
commit | 4eb591088281a5374a828ea6bf6e25eb33d30e2a (patch) | |
tree | 09d4b1446c0d9e17b0d0ee9b122f9c81cc0548ba /gdb/value.h | |
parent | 257b6bec774c0b9ec2c52494fc4898f472fcdbb8 (diff) | |
download | gdb-4eb591088281a5374a828ea6bf6e25eb33d30e2a.zip gdb-4eb591088281a5374a828ea6bf6e25eb33d30e2a.tar.gz gdb-4eb591088281a5374a828ea6bf6e25eb33d30e2a.tar.bz2 |
[PR tui/14880] Fetch values before comparing their contents.
PR tui/14880 shows a reproducer that triggers this assertion:
int
value_available_contents_eq (const struct value *val1, int offset1,
const struct value *val2, int offset2,
int length)
{
int idx1 = 0, idx2 = 0;
/* This routine is used by printing routines, where we should
already have read the value. Note that we only know whether a
value chunk is available if we've tried to read it. */
gdb_assert (!val1->lazy && !val2->lazy);
(top-gdb) bt
#0 internal_error (file=0x88a26c "../../src/gdb/value.c", line=549, string=0x88a220 "%s: Assertion `%s' failed.") at ../../src/gdb/utils.c:844
#1 0x000000000057b9cd in value_available_contents_eq (val1=0x10fa900, offset1=0, val2=0x10f9e10, offset2=0, length=8) at ../../src/gdb/value.c:549
#2 0x00000000004fd756 in tui_get_register (frame=0xd5c430, data=0x109a548, regnum=0, changedp=0x109a560) at ../../src/gdb/tui/tui-regs.c:736
#3 0x00000000004fd111 in tui_check_register_values (frame=0xd5c430) at ../../src/gdb/tui/tui-regs.c:521
#4 0x0000000000501884 in tui_check_data_values (frame=0xd5c430) at ../../src/gdb/tui/tui-windata.c:234
#5 0x00000000004f976f in tui_selected_frame_level_changed_hook (level=1) at ../../src/gdb/tui/tui-hooks.c:222
#6 0x00000000006f0681 in select_frame (fi=0xd5c430) at ../../src/gdb/frame.c:1490
#7 0x00000000005dd94b in up_silently_base (count_exp=0x0) at ../../src/gdb/stack.c:2268
#8 0x00000000005dd985 in up_command (count_exp=0x0, from_tty=1) at ../../src/gdb/stack.c:2280
#9 0x00000000004dc5cf in do_cfunc (c=0xd3f720, args=0x0, from_tty=1) at ../../src/gdb/cli/cli-decode.c:113
#10 0x00000000004df664 in cmd_func (cmd=0xd3f720, args=0x0, from_tty=1) at ../../src/gdb/cli/cli-decode.c:1888
#11 0x00000000006e43e1 in execute_command (p=0xc7e6c2 "", from_tty=1) at ../../src/gdb/top.c:489
The fix is to fetch the value before comparing the contents. The
comment additions to value.h explain why it can't be
value_available_contents_eq itself that fetches the contents.
Tested on x86_64 Fedora 17.
gdb/
2013-06-28 Pedro Alves <palves@redhat.com>
PR tui/14880
* tui/tui-regs.c (tui_get_register): Fetch register value contents
before checking whether they're available.
* value.c (value_available_contents_eq): Change comment.
* value.h (value_available_contents_eq): Expand comment.
Diffstat (limited to 'gdb/value.h')
-rw-r--r-- | gdb/value.h | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/gdb/value.h b/gdb/value.h index 4e839d3..8a66aa4 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -463,7 +463,12 @@ extern void mark_value_bytes_unavailable (struct value *value, value_available_contents_eq(val, 4, val, 12, 2) => 1 value_available_contents_eq(val, 4, val, 12, 4) => 0 value_available_contents_eq(val, 3, val, 4, 4) => 0 -*/ + + We only know whether a value chunk is available if we've tried to + read it. As this routine is used by printing routines, which may + be printing values in the value history, long after the inferior is + gone, it works with const values. Therefore, this routine must not + be called with lazy values. */ extern int value_available_contents_eq (const struct value *val1, int offset1, const struct value *val2, int offset2, |