]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/python: work around missing symbols not yet part of Python limited API
authorMatthieu Longo <matthieu.longo@arm.com>
Mon, 30 Mar 2026 16:08:03 +0000 (17:08 +0100)
committerMatthieu Longo <matthieu.longo@arm.com>
Fri, 15 May 2026 10:12:32 +0000 (11:12 +0100)
Most Python API usages in GDB can be migrated to the limited API, except
the following:

- PEP-741's configuration structures and functions, which use opaque
  types. They were originally intended to be part of the Python limited
  API, but some Python core maintainers opposed their inclusion at the
  time.
- PyOS_ReadlineFunctionPointer, a global variable storing a function
  used to override PyOS_StdioReadline(). The signature has remained
  unchanged for a long time.
- PyRun_InteractiveLoop, used to read and execute Python statements when
  embedding an interactive interpreter. Its signature has also remained
  stable for a long time.

Since no limited API alternatives exist for these, and given their long
history of ABI stability, one approach is to expose them in a GDB header
and rely on their continued stability. While this is not without risk,
it seems acceptable given the arguments above. This would remove the
remaining obstacles preventing GDB from being agnostic to the Python
version available at runtime.
That said, issues should be opened on CPython issue tracker to request
that these functions be included in the limited API in future versions.
Last but not least, GDB does not need to officially support the Python
limited API. The '--enable-py-limited-api' option can remain experimental,
with appropriate forewarnings about its limitations and guarantees.

This patch adds a new header, python-limited-api-missing.h, which
exposes symbols not yet part of the Python limited API.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=23830
Approved-By: Tom Tromey <tom@tromey.com>
gdb/Makefile.in
gdb/python/python-internal.h
gdb/python/python-limited-api-missing.h [new file with mode: 0644]

index a0c11f5eb57207b494298aac27a11c496d666460..b2b7ef3d6065a4c37b8496e247a7d45ef722ae59 100644 (file)
@@ -1616,6 +1616,7 @@ HFILES_NO_SRCDIR = \
        python/py-stopevent.h \
        python/python.h \
        python/python-internal.h \
+       python/python-limited-api-missing.h \
        python/py-uiout.h \
        quick-symbol.h \
        ravenscar-thread.h \
index 37bc37691fe41b351c560ebd3a6c46c8735e21b3..3147156d5beaed508d5b6c313d5e9120182de6a2 100644 (file)
@@ -57,6 +57,9 @@
    double quotes.  On case-insensitive filesystems, this prevents us
    from including our python/python.h header file.  */
 #include <Python.h>
+#ifdef Py_LIMITED_API
+#include "python-limited-api-missing.h"
+#endif
 #include <frameobject.h>
 #include "py-ref.h"
 #include "py-obj-type.h"
diff --git a/gdb/python/python-limited-api-missing.h b/gdb/python/python-limited-api-missing.h
new file mode 100644 (file)
index 0000000..07882ca
--- /dev/null
@@ -0,0 +1,62 @@
+/* Gdb/Python header exposing missing symbols in the Python limited API.
+   Note: this is a workaround solution until those existing symbols below,
+   or new symbols are exposed in the limited API.
+
+   Copyright (C) 2026 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_PYTHON_LIMITED_API_MISSING_H
+#define GDB_PYTHON_LIMITED_API_MISSING_H
+
+#ifdef Py_LIMITED_API
+extern "C"
+{
+
+/* Symbols belonging to the configuration API introduced in PEP-741, and
+   required in gdb_PyInitializer.  */
+
+typedef struct PyInitConfig PyInitConfig;
+
+PyAPI_FUNC(PyInitConfig*) PyInitConfig_Create (void);
+PyAPI_FUNC(void) PyInitConfig_Free (PyInitConfig *config);
+
+PyAPI_FUNC(int) PyInitConfig_SetInt (PyInitConfig *config,
+                                    const char *name,
+                                    int64_t value);
+PyAPI_FUNC(int) PyInitConfig_SetStr (PyInitConfig *config,
+                                    const char *name,
+                                    const char *value);
+
+PyAPI_FUNC(int) PyInitConfig_GetError (PyInitConfig* config,
+                                      const char **err_msg);
+PyAPI_FUNC(int) PyInitConfig_GetExitCode (PyInitConfig* config,
+                                         int *exitcode);
+
+PyAPI_FUNC(int) Py_InitializeFromInitConfig (PyInitConfig *config);
+
+/* Handler for GDB's readline support.  */
+
+PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *);
+
+/* Utils from Python's high level layer API.  */
+
+PyAPI_FUNC(int) PyRun_InteractiveLoop (FILE *f, const char *p);
+
+}
+#endif /* Py_LIMITED_API */
+
+#endif /* GDB_PYTHON_LIMITED_API_MISSING_H */