From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by sourceware.org (Postfix) with ESMTPS id 547273858C55 for ; Sat, 7 May 2022 19:51:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 547273858C55 Received: by mail-wr1-x435.google.com with SMTP id q23so14256110wra.1 for ; Sat, 07 May 2022 12:51:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4COTuXL/7pfPmcKOLT5LTeXalkwYqxXfoH3DAAX/h7w=; b=E5wZl3E/zYk3TcwwjglFas2hlWX2/M7chpQXoaV1a/NYIRApohFuVvlqJZke445p/q z+JJbDTtzgqZqLQLI+g+V+gqFt+HdyQ5mGj8+2Lp48RvJDlsX5/0WiLKFMlykZve2TEM AY3/N1ZZaickPGNkZUXx9MvByCFkPw0eagV7pUQ3nJFT6qROvNaVDdFs3VEjySYzilwm nLOC702nFJ/nk59ah6TXPLVSTJ3Lh2juQO/HuBo93LEYRJVRNeqQtH/haZ8czIAzSsLu AJCk3JM3iY8+QuRx0T9uElqLXKEhcb89dGecTjSlPKq/3KuwVsNvuXW7hpfSblEekN/i J0HQ== X-Gm-Message-State: AOAM532HGZ8Rl6lVP8u0mqhXugEoSNZXR6jtblicbgPuMPVKeAB6E0hz pM6N0dd9BU9ucih+m6TonpRqLBuPtD17tebeEKQ= X-Google-Smtp-Source: ABdhPJwClPjtmV00frNJfLsW92rb5pvNvtOSuG6TyUZUJatqWlzYGHH1STbReE+3V436F63pYxBQPa+VJXURLpRwVMU= X-Received: by 2002:a05:6000:1687:b0:20c:7de9:feca with SMTP id y7-20020a056000168700b0020c7de9fecamr7767197wrd.221.1651953083896; Sat, 07 May 2022 12:51:23 -0700 (PDT) MIME-Version: 1.0 References: <5568db74d0acb198a3e8121ee75e3cfa02ea0c6f.camel@mad-scientist.net> <453082091.802975.1651922375216@mail.yahoo.com> <222e7c9b9ac74aa886c1501792e677a0dfa1f268.camel@mad-scientist.net> In-Reply-To: <222e7c9b9ac74aa886c1501792e677a0dfa1f268.camel@mad-scientist.net> From: Jonathan Wakely Date: Sat, 7 May 2022 20:51:12 +0100 Message-ID: Subject: Re: Help using the GDB C++ STL pretty-printers / xmethods To: Paul Smith Cc: "gcc-help@gcc.gnu.org" Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-1.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, 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: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 May 2022 19:51:27 -0000 On Sat, 7 May 2022 at 20:07, Paul Smith wrote: > > On Sat, 2022-05-07 at 16:35 +0100, Jonathan Wakely wrote: > > On Sat, 7 May 2022 at 16:08, Paul Smith > > wrote: > > > Thanks for the reply. I should have mentioned this; what I do is: > > > > > > python > > > from libstdcxx.v6 import register_libstdcxx_printers > > > register_libstdcxx_printers(None) > > > end > > > > Why are you doing this by hand? That should not be necessary. > > Well I have this in my init file so I don't really enter it by hand. > But are you implying that it should somehow happen without having to do > anything at all... how does that work? Do you mean, that my > distribution should have set things up so that it happens > automatically? Yes. > Or that somehow GDB should "find" these macros on its > own? > > Note I am building/installing my own GCC and GDB so maybe I just > haven't put everything in the right places. GCC's 'make install' should do everything needed. That installs $prefix/lib64/libstdc++.so.6.0.30-gdb.py alongside the .so file, and gdb auto-loads that when debugging a process linked to the libstdc++.so.6.0.30 library. That python script imports the register_libstdcxx_printers function and runs it. Maybe you're only linking statically to libstdc++.a? > > > > Just to clarify are you saying that one or both of the methods I've > > > tried (using * or -> operators) _should_ work, and that they do > > > work for you when you try them? > > > > Yes. > > OK, I've discovered what's going on. Apparently for some reason the > ability to show the values doesn't happen immediately. When I attach > to a process and it's sitting in a sleep somewhere in the C runtime > like this: > > (gdb) bt > #0 0x00007f804634e26f in clock_nanosleep () from /lib/x86_64-linux- > gnu/libc.so.6 > #1 0x00007f8046353ef7 in nanosleep () from /lib/x86_64-linux- > gnu/libc.so.6 > #2 0x000000000097a3c9 in SignalHandler::sleepUntilSignal > (this=, response=..., timeoutMs=) at > SignalHandler.cpp:205 > #3 0x0000000000960e64 in Engine::main (this=0x7f8045f0f000) at > Engine.cpp:1374 > #4 0x000000000098fbdf in Engine::runMain (this=0x7f8045f0f000) at > Engine.cpp:793 > #5 0x000000000095f907 in main (argc=, argv= out>) at main.cpp:59 > > so my current frame is #0, then I run a python function I wrote that > shows a bunch of info about this process and sets a convenience > variable for the main pointer $mp, then I try to use it I get the > errors I showed earlier: > > (gdb) p $mp->mgr->initialized > One of the arguments you tried to pass to operator-> could not be > converted to what the function wants. > > but, now if I change my frame (to one of my frames... it doesn't help > to go to frame #1 above) it works fine: > > (gdb) fr 2 > #2 0x000000000097a3c9 in SignalHandler::sleepUntilSignal > (this=, response=..., timeoutMs=) at > SignalHandler.cpp:205 > 205 ::nanosleep(&interval, NULL); > > (gdb) p $mp->mgr->initialized > $1 = true > > Now I can go back down to frame 0 and it still works: > > (gdb) fr 0 > #0 0x00007f804634e26f in clock_nanosleep () from /lib/x86_64-linux- > gnu/libc.so.6 > > (gdb) p $mp->mgr->initialized > $2 = true > > I can't find anything in the GDB docs about this but I guess it's a > question for them, as to what's happening here. Hmm, that's reminiscent of https://sourceware.org/bugzilla/show_bug.cgi?id=25234 > > > I'm not talking about printing things per se, I'm talking about > > > writing my own python macros that help me examine my own data > > > structures, which are built with STL types. > > > > > > For example I have a complex structure that uses std::vector, > > > std::list, std:unordered_map, unique_ptr, etc. and I want to write > > > my own methods that examine these structures, either to print them > > > in a different way (not just the standard pretty-printer output) or > > > whatever. > > > > That sounds useful, but it's unlikely anybody else is going to > > provide it. If you want it, you get to build it :-) > > (sorry please replace "macro" with "Python function" everywhere in my > email... I will try to do better) > > I'm pretty sure that's the same answer I got last time I asked :). > > I just don't have the time or, probably, the knowledge of the STL > implementation I would need to do this well. But I would be happy to > work with someone, including writing some code, designing some > features, etc., if anyone else were interested. > > What I would really like to have are two things: > > (a) iterator classes that I could instantiate from my python functions > when I need to iterate through an STL type. So if in my class I have > "std::list fooList" and in my python functions I have a python > variable "fooList" which refers to this object, I would like a way to > write something like: > > for elt in StdForwardIterator(fooList): > > > Map iterators could return a tuple, etc. > > I don't know if it makes more sense to create individual iterator > classes like above, or to implement Python classes that wrap types and > provides Pythonic access by implementing Python special methods (so > that an std::unordered_map object could be treated like a dict or > whatever). All the logic to do that in Python is already present in the printers, it's just that the iterators are GDB pretty-print iterators so have a different API from general purpose Python iterables. They do exactly what the printers want, which means the iterator returns ('[n]', value) for each n in [0,cont.size()). And the StdMapPrinter._iter type iterators over key,value,key,value,key,value because that's what a printer with display_hint() = 'map' expects. For your purposes you probably want (key,value),(key,value),(key,value). But starting from the existing code and making it do that would take about five minutes per container, I reckon. I don't think you need any knowledge of the C++ implementation, because that's already been captured in Python code. > (b) Ways to access the contents of containers like unique_ptr, > shared_ptr, etc. from python functions. So if in my class I have > "std::unique_ptr fooPtr" and in my python functions I have a > variable "fooPtr" which refers to this object, I would like a way to > retrieve a gdb.Value containing its pointer. The UniquePtrGetWorker Xmethod already does that. You should be able to just do: py ptr = gdb.parse_and_eval('uniqptr.get()') Xmethods seems like the right way to do much of this, because they can be used at the normal GDB prompt as well as within Python scripts working in GDB. We could certainly add more Xmethods, but nobody is asking for them or telling us which ones are missing. Adding things nobody wants is a waste of time, there are dozens of other things we can work on instead that people are actually asking for. If we had a Python type to access a std::unique_ptr maybe it would make sense to reuse that in both the printer and xmethods for unique_ptr, and similarly for each other std type that was exposed via some Python lookalike type. But somebody would have to do the work.