This is the mail archive of the
archer@sourceware.org
mailing list for the Archer project.
bokenness of nested pretty printers
- From: ppluzhnikov at google dot com (Paul Pluzhnikov)
- To: archer at sourceware dot org
- Date: Thu, 16 Oct 2008 11:46:35 -0700 (PDT)
- Subject: bokenness of nested pretty printers
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta;t=1224182800; bh=b+TVJ8fSHPM/o29XC47sP3eRIRA=;h=DomainKey-Signature:To:Subject:MIME-version:Content-type: Content-Transfer-Encoding:Message-Id:Date:From; b=WHnBObXk4CH2VaDW9VuKipm58ZrBJV//EUzV7unFiOb0rGTgNoRqvvTKymx0huj7/k2C5aqQkp9fkV48h7uONg==
- Domainkey-signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns;h=to:subject:mime-version:content-type:content-transfer-encoding:message-id:date:from;b=MllFrR4lrCWdE3Ya4J00DhIukpHiH0SAtbswv/RHCE97ixmYr6u9dE0MFqKHpKlgLOMNcmFlU3zqJdho8c4vOw==
Greetings,
This came up as a glitch while trying to pretty-print STL list
of lists, but I now have a simpler test case.
Consider:
--- cut --- pp.c ---
struct s
{
int a;
int *b;
};
struct ss
{
struct s a;
struct s b;
};
void init_s(struct s *s, int a)
{
s->a = a;
s->b = &s->a;
}
void init_ss(struct ss *s, int a, int b)
{
init_s(&s->a, a);
init_s(&s->b, b);
}
int
main ()
{
struct ss ss;
init_ss(&ss, 1, 2);
return 0; /* break to inspect struct */
}
--- cut --- pp.c ---
And a pretty-printer to go with it:
--- cut --- pp.py ---
def pp_s(val):
a = val["a"]
b = val["b"]
if a.address() != b:
raise Exception("&a(%s) != b(%s)" % (str(a.address()), str(b)))
return " a={" + str(val["a"]) + "} b={" + str(val["b"]) + "}"
def pp_ss(val):
return "a={" + str(val["a"]) + "} b={" + str(val["b"]) + "}"
gdb.cli_pretty_printers['^struct s$'] = pp_s
gdb.cli_pretty_printers['^struct ss$'] = pp_ss
--- cut --- pp.py ---
This produces:
(gdb) print ss
$1 = Traceback (most recent call last):
File "<string>", line 6, in pp_s
Exception: &a(0x7fffffffe610) != b(0x7fffffffe620)
a={ a={1} b={0x7fffffffe610}} b={{a = 2, b = 0x7fffffffe620}}
In the case of (nested) STL lists, it is imperative that
val.address() give correct result, since that is the pretty-printing
loop termination condition.
I believe the problem is as follows:
common_val_print() gets correct value, which looks like this:
{lval = lval_memory, modifiable = 1, location = {address = 0x7fffffffe610}, offset = 0x8, ...
and invokes val_print() with correct value contents, but does not pass 'offset'.
val_print() later discovers python pretty-printer, and sythesizes a new value
(gdb/python/python.c:828), but at wrong address:
{lval = lval_memory, modifiable = 1, location = {address = 0x7fffffffe610}, offset = 0,
^^^^^^^^^^
Complete trace for where the "bad" value is below.
I think fixing this requires either that we pass down 'value' itself,
or at least 'value->offset'.
Comments?
#0 apply_val_pretty_printer (type=0xab02c8, valaddr=0xc87630 "\002", embedded_offset=0, address=140737488348688, stream=0xdb6a60, format=0, deref_ref=0, recurse=0,
pretty=Val_no_prettyprint, language=0x78ec40) at ../../gdb/python/python.c:829
#1 0x00000000004a2df9 in val_print (type=0xab02c8, valaddr=0xc87630 "\002", embedded_offset=0, address=140737488348688, stream=0xdb6a60, format=0, deref_ref=0, recurse=0,
pretty=Val_pretty_default, language=0x78ec40) at ../../gdb/valprint.c:240
#2 0x00000000004a3069 in common_val_print (val=0xc875c0, stream=0xdb6a60, format=0, deref_ref=0, recurse=0, pretty=Val_pretty_default, language=0x78ec40) at ../../gdb/valprint.c:316
#3 0x0000000000461ff7 in valpy_str (self=0x2aaaaac1a0d0) at ../../gdb/python/python-value.c:344
#4 0x00000000006a23c8 in PyObject_Str (v=0xac70d0) at ../../Objects/object.c:360
#5 0x00000000006a7d1c in string_new (type=0x952440, args=<value optimized out>, kwds=<value optimized out>) at ../../Objects/stringobject.c:3318
#6 0x00000000006b3183 in type_call (type=0xac70d0, args=0x2aaaaab0cb90, kwds=0x0) at ../../Objects/typeobject.c:421
#7 0x000000000067e720 in PyObject_Call (func=0xac70d0, arg=0xc87640, kw=0x7fffffffe610) at ../../Objects/abstract.c:1795
#8 0x00000000006d6eb4 in PyEval_EvalFrame (f=0x9ec7d0) at ../../Python/ceval.c:3776
#9 0x00000000006da364 in PyEval_EvalCodeEx (co=0x2aaaaabb0d50, globals=<value optimized out>, locals=<value optimized out>, args=0x2aaaaab0cb68, argcount=1, kws=0x0, kwcount=0, defs=0x0,
defcount=0, closure=0x0) at ../../Python/ceval.c:2741
#10 0x0000000000727a93 in function_call (func=0x2aaaaab09e60, arg=0x2aaaaab0cb50, kw=0x0) at ../../Objects/funcobject.c:548
#11 0x0000000000680b87 in PyObject_CallFunctionObjArgs (callable=0x2aaaaab09e60) at ../../Objects/abstract.c:1795
#12 0x000000000045b181 in pretty_print_one_value (func=0x2aaaaab09e60, value=0xddebf0, out_value=0x7fffffffdda8, children=1) at ../../gdb/python/python.c:765
#13 0x000000000045b2b5 in apply_pretty_printer (value=0xe0da90, out_value=0x7fffffffdda8) at ../../gdb/python/python.c:801
#14 0x00000000004a30d5 in value_print (val=0xe0da90, stream=0xa0cf70, format=0, raw=0, pretty=Val_pretty_default) at ../../gdb/valprint.c:338
#15 0x00000000004a5711 in print_formatted (val=0xe0da90, format=0, size=0, raw=0, stream=0xa0cf70) at ../../gdb/printcmd.c:314
#16 0x00000000004a6792 in print_command_1 (exp=0x99d1c2 "ss", inspect=0, voidprint=1) at ../../gdb/printcmd.c:909
#17 0x00000000004a6805 in print_command (exp=0x99d1c2 "ss", from_tty=0) at ../../gdb/printcmd.c:929
#18 0x0000000000449720 in do_cfunc (c=0x9cb470, args=0x99d1c2 "ss", from_tty=0) at ../../gdb/cli/cli-decode.c:60
#19 0x000000000044c17b in cmd_func (cmd=0x9cb470, args=0x99d1c2 "ss", from_tty=0) at ../../gdb/cli/cli-decode.c:1669
#20 0x00000000004080d8 in execute_command (p=0x99d1c3 "s", from_tty=1) at ../../gdb/top.c:457
#21 0x00000000004dc08a in command_handler (command=0x99d1c0 "p ss") at ../../gdb/event-top.c:514
#22 0x00000000004dc74a in command_line_handler (rl=0xab8290 "°\202«") at ../../gdb/event-top.c:739
#23 0x00000000005c10f1 in rl_callback_read_char () at ../../readline/callback.c:205
#24 0x00000000004db6a5 in rl_callback_read_char_wrapper (client_data=0x0) at ../../gdb/event-top.c:178
#25 0x00000000004dbf50 in stdin_event_handler (error=0, client_data=0x0) at ../../gdb/event-top.c:433
#26 0x00000000004da994 in handle_file_event (event_file_desc=0) at ../../gdb/event-loop.c:732
#27 0x00000000004da02f in process_event () at ../../gdb/event-loop.c:341
#28 0x00000000004da07e in gdb_do_one_event (data=0x0) at ../../gdb/event-loop.c:378
#29 0x00000000004d60fd in catch_errors (func=0x4da044 <gdb_do_one_event>, func_args=0x0, errstring=0x74d62b "", mask=6) at ../../gdb/exceptions.c:516
#30 0x0000000000466ec0 in tui_command_loop (data=0x0) at ../../gdb/tui/tui-interp.c:153
#31 0x00000000004d6704 in current_interp_command_loop () at ../../gdb/interps.c:290
#32 0x0000000000400369 in captured_command_loop (data=0x0) at ../../gdb/main.c:101
#33 0x00000000004d60fd in catch_errors (func=0x400358 <captured_command_loop>, func_args=0x0, errstring=0x732242 "", mask=6) at ../../gdb/exceptions.c:516
#34 0x0000000000401597 in captured_main (data=0x7fffffffe620) at ../../gdb/main.c:878
#35 0x00000000004d60fd in catch_errors (func=0x40039b <captured_main>, func_args=0x7fffffffe620, errstring=0x732242 "", mask=6) at ../../gdb/exceptions.c:516
#36 0x00000000004015ca in gdb_main (args=0x7fffffffe620) at ../../gdb/main.c:888
#37 0x0000000000400354 in main (argc=4, argv=0x7fffffffe718) at ../../gdb/gdb.c:33
In frame #0:
(top) print/x *value
$1 = {
lval = 0x1,
modifiable = 0x1,
location = {
address = 0x7fffffffe610,
internalvar = 0x7fffffffe610
},
offset = 0x0,
bitsize = 0x0,
bitpos = 0x0,
frame_id = {
stack_addr = 0x0,
code_addr = 0x0,
special_addr = 0x0,
stack_addr_p = 0x0,
code_addr_p = 0x0,
special_addr_p = 0x0
},
type = 0xab02c8,
enclosing_type = 0xab02c8,
embedded_offset = 0x0,
pointed_to_offset = 0x0,
next = 0xdb6930,
regnum = 0xffff,
lazy = 0x0,
optimized_out = 0x0,
initialized = 0x1,
aligner = {
contents = {0x2},
force_doublest_align = 0x8000000000000000,
force_longest_align = 0x2,
force_core_addr_align = 0x2,
force_pointer_align = 0x2
}
}
(top) p value.type.main_type.tag_name
$2 = 0xaa8966 "s"
In frame #2:
(top) print/x *val
$3 = {
lval = 0x1,
modifiable = 0x1,
location = {
address = 0x7fffffffe610,
internalvar = 0x7fffffffe610
},
offset = 0x10,
bitsize = 0x0,
bitpos = 0x0,
frame_id = {
stack_addr = 0x0,
code_addr = 0x0,
special_addr = 0x0,
stack_addr_p = 0x0,
code_addr_p = 0x0,
special_addr_p = 0x0
},
type = 0xab02c8,
enclosing_type = 0xab02c8,
embedded_offset = 0x0,
pointed_to_offset = 0x0,
next = 0xddebf0,
regnum = 0xffff,
lazy = 0x0,
optimized_out = 0x0,
initialized = 0x1,
aligner = {
contents = {0x2},
force_doublest_align = 0x8000000000000000,
force_longest_align = 0x2,
force_core_addr_align = 0x2,
force_pointer_align = 0x2
}
}