public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Paul Smith <psmith@gnu.org>
To: gdb@sourceware.org
Subject: GDB python: why do xmethod workers always get sent pointers?
Date: Sun, 08 May 2022 20:01:42 -0400	[thread overview]
Message-ID: <8ac1c99b3b058b3193d76f1c75976576f94c02cc.camel@gnu.org> (raw)

When examining xmethods I've discovered that the __call__() method for
the worker always is sent a pointer even if the value we want to work
with is not a pointer.

I've tested this in both GDB 10.2 and GDB 12.1.

Suppose I have a class Bar and I implement a worker for a getval()
method:

  class BarWorker_getval(gdb.xmethod.XMethodWorker):
      def get_arg_types(self):
          return None

      def get_result_type(self, obj):
          return gdb.lookup_type('int')

      def __call__(self, obj):
          gdb.write("TYPE: %s\n" % (str(obj.type)))
          return obj['val']

Now I declare a variable in my program:

  Bar bar;

Now in GDB I use the xmethod to call the getval() method:

  (gdb) ptype bar
  type = class Bar {
    public:
      int getval(void);
      int val;
  }

  (gdb) p bar.getval()
  TYPE: Bar *
  $1 = 0

Why is the type "Bar*" when I used a variable of type "Bar"?

This matters because it seems to prevent me from using xmethods with
convenience variables:

  (gdb) set $x = bar

  (gdb) ptype $x
  type = class Bar {
    public:
      int getval(void);
      int val;
  }

  (gdb) p $x.getval()
  Attempt to take address of value not located in memory.

If the xmethod infrastructure didn't "attempt to take address of value"
which of course we can't for convenience variables, then this would
work (I assume).


In this particular case I could work around it by setting the
convenience variable to the address of the value:

  (gdb) set $xp = &bar

  (gdb) p $xp->getval()
  type: Bar *
  $1 = 0

(weirdly the type here is still "Bar*")

But this doesn't work so well with other situations: the one I've run
into in particular is std::unique_ptr<>, which provides an xmethod for
operator-> so that you can retrieve values from it.  I can't find any
way to put a std::unique_ptr into a convenience variable then use it:

  (gdb) p uptr->val
  $1 = 0

  (gdb) set $xx = uptr
  (gdb) p $xx->val
  Attempt to take address of value not located in memory.

  (gdb) set $xp = &uptr
  (gdb) p $xp->val
  There is no member or method named val.

                 reply	other threads:[~2022-05-09  0:02 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8ac1c99b3b058b3193d76f1c75976576f94c02cc.camel@gnu.org \
    --to=psmith@gnu.org \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).