From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from eggs.gnu.org (eggs.gnu.org [IPv6:2001:470:142:3::10]) by sourceware.org (Postfix) with ESMTPS id 85D693858C54 for ; Mon, 9 May 2022 00:02:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 85D693858C54 Received: from fencepost.gnu.org ([2001:470:142:3::e]:41842) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nnqqg-0007ma-WA for gdb@sourceware.org; Sun, 08 May 2022 20:02:03 -0400 Received: from static-11-191-147-69.axsne.net ([69.147.191.11]:10400 helo=[10.200.55.35]) by fencepost.gnu.org with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nnqqN-0008Bf-GZ for gdb@sourceware.org; Sun, 08 May 2022 20:02:01 -0400 Message-ID: <8ac1c99b3b058b3193d76f1c75976576f94c02cc.camel@gnu.org> Subject: GDB python: why do xmethod workers always get sent pointers? From: Paul Smith Reply-To: psmith@gnu.org To: gdb@sourceware.org Date: Sun, 08 May 2022 20:01:42 -0400 Organization: GNU's Not UNIX! Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.44.1 (by Flathub.org)) MIME-Version: 1.0 X-Spam-Status: No, score=-3.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 May 2022 00:02:06 -0000 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 =3D class Bar { public: int getval(void); int val; } (gdb) p bar.getval() TYPE: Bar * $1 =3D 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 =3D bar (gdb) ptype $x type =3D 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 =3D &bar (gdb) p $xp->getval() type: Bar * $1 =3D 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 =3D 0 (gdb) set $xx =3D uptr (gdb) p $xx->val Attempt to take address of value not located in memory. (gdb) set $xp =3D &uptr (gdb) p $xp->val There is no member or method named val.