From: Simon Marchi <simark@simark.ca>
To: Tom Tromey <tom@tromey.com>, gdb-patches@sourceware.org
Subject: Re: [RFC 0/4] Better Python safety
Date: Mon, 23 Feb 2026 16:00:35 -0500 [thread overview]
Message-ID: <b65f9274-fab2-47fa-826b-c8f0f3d90a6a@simark.ca> (raw)
In-Reply-To: <20260222200759.1587070-1-tom@tromey.com>
On 2026-02-22 14:49, Tom Tromey wrote:
> This series is a rough draft showing how I think Python safety could
> be improved.
>
> The basic idea is to use C++ features: more fully use gdbpy_ref<> to
> avoid reference-counting bugs, introduce a new gdbpy_borrowed_ref to
> manage borrowed references; throw exceptions on failure rather than
> explicit error checks; and finally wrap Python C APIs to enforce these
> rules.
>
> This approach also lets us implement Python methods in a more natural
> style. Explicit try/catch when calling gdb APIs is no longer needed,
> and methods can simply return the appropriate type.
>
> This series is nowhere near complete, but I did mostly convert
> py-arch.c and py-frame.c. (Discussion of some holes below.)
>
> A nice example of the simplification is shown by
> gdbpy_all_architecture_names, which is now just:
>
> gdbpy_ref<>
> gdbpy_all_architecture_names (gdbpy_borrowed_ref self)
> {
> gdbpy_ref<> list = gdbpy_new_list (0);
>
> std::vector<const char *> name_list = gdbarch_printable_names ();
> for (const char *name : name_list)
> gdbpy_list_append (list, gdbpy_unicode_from_string (name));
>
> return list;
> }
Just some comments before I get into the code itself:
We have something really similar in the other project I work on,
Babeltrace. The base API is in C, and it is very refcount heavy. We
wrote C++ bindings around that, that I think are really nice and make it
almost impossible to make a mistake in refcount.
We have BorrowedObject:
https://git.efficios.com/?p=babeltrace.git;a=blob;f=src/cpp-common/bt2/borrowed-object.hpp;h=3ea62072df3f0dbfbf2ad3434980c4f7f597dd39;hb=HEAD
which holds a weak reference on an object. It can't hold nullptr,
meaning that if you receive a BorrowedObject of some kind, you know
there is an object in it.
We then have OptionalBorrowedObject, which is like BorrowedObject but
can be nullptr / empty:
https://git.efficios.com/?p=babeltrace.git;a=blob;f=src/cpp-common/bt2/shared-object.hpp;h=8d6666e2ed4c658150ff449245764287c5c72f94;hb=HEAD
This is similar to gdbpy_borrowed_ref.
The distinction between BorrowedObject and OptionalBorrowedObject is
nice, as it allows declaring parameters or return values that can't be
nullptr / empty, a bit like C++ references vs pointers. It might be
good to have that too. The wrapper around PyList_Append, for instance,
would take non-optional parameters.
And finally, SharedObject, which holds a strong reference:
https://git.efficios.com/?p=babeltrace.git;a=blob;f=src/cpp-common/bt2/optional-borrowed-object.hpp;h=cfabdf203542924742d8eaf24bb7ff33ebfbf14e;hb=HEAD
This is similar to gdbpy_ref.
Finally (1), is there something specific to GDB here? I'm wondering if we
could make it a separate project (and import it in GDB), because it's
something I would be tempted to use outside of GDB.
And finally (2), I was kind of surprised that something like this didn't
exist already, we're certainly not the first ones to want to use the
CPython in a modern C++ program. I searched around and found nanobind:
https://nanobind.readthedocs.io/en/latest/
It seems to do more than what we want (like automatic C++ <-> Python
data structure conversion), but the wrappers shown here seem to be like
what we want:
https://nanobind.readthedocs.io/en/latest/exchanging.html#option-3-wrappers
I'm not convinced that going with this library would be easier in the
long run, but I think we should at least take a moment to check what is
out there before writing something new.
Simon
next prev parent reply other threads:[~2026-02-23 21:01 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-22 19:49 Tom Tromey
2026-02-22 19:49 ` [RFC 1/4] Add gdbpy_borrowed_ref Tom Tromey
2026-02-24 4:57 ` Simon Marchi
2026-02-25 3:55 ` Tom Tromey
2026-02-25 15:24 ` Simon Marchi
2026-02-26 1:38 ` Tom Tromey
2026-02-22 19:49 ` [RFC 2/4] Add wrappers for some Python APIs Tom Tromey
2026-02-22 19:49 ` [RFC 3/4] Add constexpr functions to create PyMethodDef entries Tom Tromey
2026-02-22 19:49 ` [RFC 4/4] Convert some Python code to new-style Tom Tromey
2026-02-23 20:28 ` [RFC 0/4] Better Python safety Simon Marchi
2026-02-23 21:00 ` Simon Marchi [this message]
2026-02-23 23:23 ` Tom Tromey
2026-02-23 23:56 ` Tom Tromey
2026-02-24 1:05 ` Simon Marchi
2026-02-24 16:29 ` Tom Tromey
2026-02-23 21:22 ` Tom Tromey
2026-03-04 17:39 ` Matthieu Longo
2026-03-04 21:02 ` Tom Tromey
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=b65f9274-fab2-47fa-826b-c8f0f3d90a6a@simark.ca \
--to=simark@simark.ca \
--cc=gdb-patches@sourceware.org \
--cc=tom@tromey.com \
/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