mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 18:44:20 +08:00
[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.
This commit is contained in:
parent
257b6bec77
commit
4eb5910882
@ -1,3 +1,11 @@
|
||||
2013-06-28 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR tui/14880
|
||||
* tui/tui-regs.c (tui_get_register): Fetch value contents before
|
||||
checking if they're available.
|
||||
* value.c (value_available_contents_eq): Change comment.
|
||||
* value.h (value_available_contents_eq): Expand comment.
|
||||
|
||||
2013-06-27 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* target.c (find_run_target): Remove.
|
||||
|
@ -732,6 +732,13 @@ tui_get_register (struct frame_info *frame,
|
||||
struct gdbarch *gdbarch = get_frame_arch (frame);
|
||||
int size = register_size (gdbarch, regnum);
|
||||
|
||||
/* We only know whether a value chunk is available if we've
|
||||
tried to read it. */
|
||||
if (value_lazy (data->value))
|
||||
value_fetch_lazy (data->value);
|
||||
if (value_lazy (old_val))
|
||||
value_fetch_lazy (old_val);
|
||||
|
||||
if (value_optimized_out (data->value) != value_optimized_out (old_val)
|
||||
|| !value_available_contents_eq (data->value, 0,
|
||||
old_val, 0, size))
|
||||
|
@ -543,9 +543,7 @@ value_available_contents_eq (const struct value *val1, int offset1,
|
||||
{
|
||||
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. */
|
||||
/* See function description in value.h. */
|
||||
gdb_assert (!val1->lazy && !val2->lazy);
|
||||
|
||||
while (length > 0)
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user