From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12667 invoked by alias); 17 Aug 2011 12:49:36 -0000 Received: (qmail 12658 invoked by uid 22791); 17 Aug 2011 12:49:35 -0000 X-SWARE-Spam-Status: No, hits=-2.5 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 17 Aug 2011 12:49:14 +0000 Received: (qmail 5513 invoked from network); 17 Aug 2011 12:49:13 -0000 Received: from unknown (HELO scottsdale.localnet) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 17 Aug 2011 12:49:13 -0000 From: Pedro Alves To: Andrew Oakley Subject: Re: Python API - nested pretty printers MI implications Date: Wed, 17 Aug 2011 12:49:00 -0000 User-Agent: KMail/1.13.6 (Linux/2.6.38-10-generic; KDE/4.7.0; x86_64; ; ) Cc: gdb@sourceware.org References: <20110814171023.19db4f49@ado-gentoo> <201108151530.08237.pedro@codesourcery.com> <20110816231151.6cd06011@ado-gentoo> In-Reply-To: <20110816231151.6cd06011@ado-gentoo> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <201108171349.10546.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2011-08/txt/msg00070.txt.bz2 On Tuesday 16 August 2011 23:11:51, Andrew Oakley wrote: > > On Mon, 15 Aug 2011 15:30:08 +0100 > Pedro Alves wrote: > > On Monday 15 August 2011 15:06:10, Andrew Oakley wrote: > > > I assume the idea is to create a gdb.Value (with some data it > > > doesn't really matter what) and then detect that it is that > > > particular gdb.Value when the pretty printers list is searched? > > > Perhaps you could do something like this: > > > > > > def fake_value_printer(val): > > > if hasattr(val, "prettyprinter"): > > > return val.prettyprinter > > > else: > > > return None > > > > > > gdb.pretty_printers.insert(0, fake_value_printer) > > > > > > Then you could just return any old gdb.Value and as long as it had a > > > prettyprinter attribute then that would be called instead of the > > > "normal" version. > > > > > > Is this what you were thinking of? > > > > I was actually thinking more like: > > > > gdb.pretty_printers.insert(0, fake_value_printer) > > > > def fake_value_printer(val): > > isinstance(o, MyFakeValue) > > return FakeValuePrinter(val, or whatever args needed) > > else: > > return None > > > > instead of duck typing, but yes, that sounds similar. > > > > > That's quite a nice trick but I'm not sure its a good long-term > > > solution. It relies on the same python gdb.Value being passed back > > > to the pretty printer selection function > > > > I don't understand. > > Imagine for a minute that a "struct value" didn't have a reference to a > gdb.Value. Instead a gdb.Value is created every time we want to pass > a value to python. The result of this is that the pretty-printer could > return one gdb.Value and the pretty printer selection function would > get a completely different gdb.Value that represented the same thing > (breaking any code that worked like the examples above). I understand now, thanks. Actually, it looks like that is already happening, as when gdb always takes a copy of the struct value under the gdb.Value internally, and then wraps it in a _new_ gdb.Value before passing it to the python pretty printer lookup functions (in the pretty_printers array). :-( IMO this is a bug, and the internal conversions should be short-circuited to garantee the same gdb.Value is passed ... (I remembered , which ended up in gdb.Value being extendable, but I see that Tom had identified the internal copy problem at the time too.) > Given that GDB is quite happy giving you different gdb.Value objects > for exactly the same thing it doesn't seem unreasonable to expect it to > happen with pretty printers too (and the documentation doesn't say that > it can't happen). > > As a random example of GDB returning different gdb.Values for the same > thing: > > > $ gdb --quiet `which cat` > > Reading symbols from /bin/cat...Reading symbols from /usr/lib64/debug/bin/cat.debug...done. > > done. > > (gdb) start > > Temporary breakpoint 1 at 0x401d7b: file cat.c, line 502. > > Starting program: /bin/cat > > > > Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe068) at cat.c:5 > > 502 cat.c: No such file or directory. > > in cat.c > > (gdb) python print gdb.selected_frame().read_var('argc') is gdb.selected_frame().read_var('argc') > > False > > (gdb) That's really an unrelated example, IMO. > Given some changes to the MI I can envisage this actually happening in > reality, Daniel Jacobowitz was talking about allowing non-root object > updates which might lead to this kind of behaviour. Yes, we should keep those working. > I hope this makes more sense now because I don't think I can explain it > any better :(. Yes, thanks. > > > and probably causes exactly the same problems for the MI. > > > > There'd be no NULL values this way. Wasn't that the problem? > > Kind of. Unfortunately this could well confuse front ends. They see > something that looks like a real value, it even has a type they can > "helpfully" display. That's not good because this isn't a real value so > we shouldn't make the FE (and by extension varobj) think that it is. Not sure that's a real problem. We could maybe just make it type void. -- Pedro Alves