public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Fwd: Addresses in pretty-printing
       [not found] <CAHgb+0=pttEZ2uOcO6xfqJ4yvnzCCTJs0DTAZgLKKKwgZiocQQ@mail.gmail.com>
@ 2012-11-19  7:11 ` Jim Blandy
  2012-11-19 21:56   ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Jim Blandy @ 2012-11-19  7:11 UTC (permalink / raw)
  To: gdb ml

Quick summary: the patch discussed and approved in this long-ago
thread: http://sourceware.org/ml/gdb/2009-11/msg00105.html
causes silly output like this:

(gdb) print a
$1 = {ptr = }
(gdb) print s
$1 =

One particular patch is responsible. I suggest an extension to GDB's
Python interface that allows a cleaner solution.

In detail:

The original problem was that GDB showed string addresses where they
weren't wanted, according to gdb.python/py-prettyprint.exp. The test
wants the pretty-printer for this structure:

typedef struct string_repr
{
  struct whybother
  {
    const char *contents;
  } whybother;
} string;

to produce output like this:

$2 = "fnord"

instead of like this:

$1 = 0x403680 "fnord"

Here's the patch from that thread:

--- gdb/python/py-prettyprint.c#1    2009-11-09 17:58:39.000000000 -0800
+++ gdb/python/py-prettyprint.c     2009-11-09 16:51:16.862840000 -0800
@@ -209,7 +209,12 @@ print_string_repr (PyObject *printer, co
       Py_DECREF (py_str);
     }
   else if (replacement)
-    common_val_print (replacement, stream, recurse, options, language);
+    {
+      struct value_print_options opts = *options;
+
+      opts.addressprint = 0;
+      common_val_print (replacement, stream, recurse, &opts, language);
+    }
   else
     gdbpy_print_stack ();
 }

It seems to me this change is over-broad: all addresses appearing
anywhere in the non-pretty printing of a replacement value get
omitted, even if they're, say, a 'void *' or a pointer to some
structure. For example, this is unhelpful:

$ cat pretty-printers.c
struct B { void *ptr; };
struct A { struct B b; };
int main() {
  struct A a;
  a.b.ptr = 0;
  return 0;
};
$ cat pretty-printers-gdb.py
class ppA(object):
    def __init__(self, value): self.value = value
    def to_string(self): return self.value['b']
def lookup(value):
    if value.type.tag == 'A': return ppA(value)
gdb.pretty_printers[:] = [lookup]
$ gcc -g3 -O0 pretty-printers.c -o pretty-printers
$ gdb pretty-printers
(gdb) break 6
Breakpoint 1 at 0x400538: file pretty-printers.c, line 6.
(gdb) run
Breakpoint 1, main () at pretty-printers.c:6
6      return 0;
(gdb) print a
$1 = {ptr = }
(gdb)

The pretty-printer returns a B as the replacement value, and since B
contains pointers, they don't print.

It's trouble for NULL 'char *' pointers too: we always omit the string
contents of a 'char *' when it's NULL, which makes sense; but if we
omit the address as well, then there's nothing left:

$ cat pp2.c
struct S { char *s; };
int main() {
  struct S s;
  s.s = 0;
  return 0;
};
$ cat pp2-gdb.py
class ppS(object):
    def __init__(self, value): self.value = value
    def to_string(self): return self.value['s']
def lookup(value):
    if value.type.tag == 'S': return ppS(value)
gdb.pretty_printers[:] = [lookup]
$ gcc -g3 -O0 pp2.c -o pp2
$ gdb pp2
(gdb) b 5
Breakpoint 1 at 0x400538: file pp2.c, line 5.
(gdb) run
Breakpoint 1, main () at pp2.c:5
5      return 0;
(gdb) p s
$1 =
(gdb)

That's not good.

Just on first principles, I think it's odd to answer the question "How
can I get GDB to print a string without the address?" with something
like "return it as a replacement value". But that's what the
aforementioned patch does. Whether a pretty-printer hands GDB a value
as a replacement value, or calls Python's 'str', or returns it as a
child, shouldn't affect whether addresses get printed.

I'd like to suggest an alternative: gdb.Value should have a 'format'
method that behaves almost like applying Python's 'str' built-in
function to the value, except that it allows you to specify print
options for that value and its sub-values. Thus, the pretty-printer in
py-prettyprint.exp would become, simply:

class string_print:
   def __init__(self, val):
       self.val = val

   def to_string(self):
       return self.val['whybother']['contents'].format({'address': False})

Here is proposed documentation for gdb.Value.format, and two
accompanying functions, gdb.value_print_options and
gdb.set_value_print_options. I'd be willing to implement something
like this.

@defun Value.format (print_options = None)
Return a string holding the text @value{GDBN} would produce if
printing this @code{gdb.Value}. If this value has a pretty-printer,
call that to produce the string; otherwise, use @value{GDBN}'s
built-in printing rules.

@var{print_options}, if given, is a dictionary of the sort returned by
@code{gdb.value_print_options}, binding names of print options to
values to use while formatting this value. These settings affect only
the formatting of this value and its children: when a call to this
function returns, all print settings remain as they were before the
call occurred.

The result of calling method is very similar to that of applying
Python's @code{str} built-in function to the @code{gdb.Value}
instance, except that one may pass a @var{print_options}
argument to affect the value's formatting.
@end defun


@findex gdb.value_print_options
@defun gdb.value_print_options ()
Return a dictionary providing the current values of @value{GDBN}'s
value printing settings, as controlled by the @code{set print} command
(and a few other @code{set} commands). The dictionary's keys are the
names of the print options; the value stored under each key is that
option's current value. The keys and their corresponding @code{set}
subcommands are as follows:

@table @code
@item 'output-radix'
@code{set output-radix}
@item 'elements'
@code{set print elements}
@item 'null-stop'
@code{set print null-stop}
@item 'repeats'
@code{set print repeats}
@item 'pretty'
@code{set print pretty}
@item 'union'
@code{set print union}
@item 'array'
@code{set print array}
@item 'address'
@code{set print address}
@item 'symbol'
@code{set print symbol}
@item 'array-indexes'
@code{set print array-indexes}
@item 'static-members'
@code{set print static-members}
@item 'vtbl'
@code{set print vtbl}
@item 'object'
@code{set print object}
@item 'pascal_static-members'
@code{set print pascal_static-members}
@item 'demangle'
@code{set print demangle}
@item 'asm-demangle'
@code{set print asm-demangle}
@item 'max-symbolic-offset'
@code{set print max-symbolic-offset}
@item 'symbol-filename'
@code{set print symbol-filename}
@item 'sevenbit-strings'
@code{set print sevenbit-strings}
@end table

The dictionary values are booleans or numbers, as appropriate for each
print setting.
@end defun

@findex gdb.set_value_print_options
@defun gdb.set_value_print_options (options)
Set the value printing options as given in @var{options}, a dictionary
whose items' keys name value printing options, and whose values are
the values to which those options should be set. Permitted keys are as
for @code{gdb.value_print_options}, described above.

Only those options named in the dictionary are affected, so you can
use this method to set individual options:

@smallexample
gdb.set_value_print_options({'demangle': False})
@end smallexample
@end defun

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Fwd: Addresses in pretty-printing
  2012-11-19  7:11 ` Fwd: Addresses in pretty-printing Jim Blandy
@ 2012-11-19 21:56   ` Tom Tromey
  2012-11-19 23:03     ` Jim Blandy
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2012-11-19 21:56 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb ml

>>>>> "Jim" == Jim Blandy <jimb@red-bean.com> writes:

Jim> Here is proposed documentation for gdb.Value.format, and two
Jim> accompanying functions, gdb.value_print_options and
Jim> gdb.set_value_print_options. I'd be willing to implement something
Jim> like this.

It seems like a worthwhile facility to me.

I think one possible objection is that this kind of thing will let
pretty-printer authors effectively override user settings.  However,
we've see that they already do this, and it isn't really possible (or
perhaps arguably desirable) to stop them.  Your proposal makes the
resulting code cleaner and is also, I think, useful for writing
new commands.

Jim> @findex gdb.set_value_print_options
Jim> @defun gdb.set_value_print_options (options)
Jim> Set the value printing options as given in @var{options}, a dictionary
Jim> whose items' keys name value printing options, and whose values are
Jim> the values to which those options should be set. Permitted keys are as
Jim> for @code{gdb.value_print_options}, described above.

This is just shorthand for a bunch of calls to gdb.execute, to set the
various parameters?

Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Fwd: Addresses in pretty-printing
  2012-11-19 21:56   ` Tom Tromey
@ 2012-11-19 23:03     ` Jim Blandy
  2012-11-20 20:58       ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Jim Blandy @ 2012-11-19 23:03 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb ml

On Mon, Nov 19, 2012 at 1:56 PM, Tom Tromey <tromey@redhat.com> wrote:
>>>>>> "Jim" == Jim Blandy <jimb@red-bean.com> writes:
>
> Jim> Here is proposed documentation for gdb.Value.format, and two
> Jim> accompanying functions, gdb.value_print_options and
> Jim> gdb.set_value_print_options. I'd be willing to implement something
> Jim> like this.
>
> It seems like a worthwhile facility to me.
>
> I think one possible objection is that this kind of thing will let
> pretty-printer authors effectively override user settings.  However,
> we've see that they already do this, and it isn't really possible (or
> perhaps arguably desirable) to stop them.  Your proposal makes the
> resulting code cleaner and is also, I think, useful for writing
> new commands.

Yeah; badly-written pretty-printers can do anything they like. The
proposal might make it easier for pretty-printers to respect user
settings (like 'print elements', say).

> Jim> @findex gdb.set_value_print_options
> Jim> @defun gdb.set_value_print_options (options)
> Jim> Set the value printing options as given in @var{options}, a dictionary
> Jim> whose items' keys name value printing options, and whose values are
> Jim> the values to which those options should be set. Permitted keys are as
> Jim> for @code{gdb.value_print_options}, described above.
>
> This is just shorthand for a bunch of calls to gdb.execute, to set the
> various parameters?

Yes, and it could avoid the silly stringify/pass to gdb/destringify
process and just write to user_print_options directly.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Fwd: Addresses in pretty-printing
  2012-11-19 23:03     ` Jim Blandy
@ 2012-11-20 20:58       ` Tom Tromey
  0 siblings, 0 replies; 4+ messages in thread
From: Tom Tromey @ 2012-11-20 20:58 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb ml

>>>>> "Jim" == Jim Blandy <jimb@red-bean.com> writes:

Tom> This is just shorthand for a bunch of calls to gdb.execute, to set the
Tom> various parameters?

Jim> Yes, and it could avoid the silly stringify/pass to gdb/destringify
Jim> process and just write to user_print_options directly.

I guess I don't have any objection to that, either, as long as it
properly notifies the observers.

I'm looking forward to your patch.  Thanks.

Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-11-20 20:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAHgb+0=pttEZ2uOcO6xfqJ4yvnzCCTJs0DTAZgLKKKwgZiocQQ@mail.gmail.com>
2012-11-19  7:11 ` Fwd: Addresses in pretty-printing Jim Blandy
2012-11-19 21:56   ` Tom Tromey
2012-11-19 23:03     ` Jim Blandy
2012-11-20 20:58       ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).