Skip to content

Conversation

@JDevlieghere
Copy link
Member

The bug [1] this is working around was fixed in SWIG 4.1. The workaround uses functions and constants that are not part of the limited API, which I'm trying to eliminate to make LLDB compatible with the Python Limited C API [2].

[1] swig/swig#1640
[2] #151617

@llvmbot
Copy link
Member

llvmbot commented Nov 13, 2025

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

The bug [1] this is working around was fixed in SWIG 4.1. The workaround uses functions and constants that are not part of the limited API, which I'm trying to eliminate to make LLDB compatible with the Python Limited C API [2].

[1] swig/swig#1640
[2] #151617


Full diff: https://github.com/llvm/llvm-project/pull/167808.diff

2 Files Affected:

  • (modified) lldb/bindings/python/python-typemaps.h (+2)
  • (modified) lldb/bindings/python/python-typemaps.swig (+3-3)
diff --git a/lldb/bindings/python/python-typemaps.h b/lldb/bindings/python/python-typemaps.h
index 8a533e822988e..366ae5e6a6676 100644
--- a/lldb/bindings/python/python-typemaps.h
+++ b/lldb/bindings/python/python-typemaps.h
@@ -3,6 +3,7 @@
 
 #include <Python.h>
 
+#if SWIG_VERSION < 0x040100
 // Defined here instead of a .swig file because SWIG 2 doesn't support
 // explicit deleted functions.
 struct Py_buffer_RAII {
@@ -15,5 +16,6 @@ struct Py_buffer_RAII {
       PyBuffer_Release(&buffer);
   }
 };
+#endif
 
 #endif // LLDB_BINDINGS_PYTHON_PYTHON_TYPEMAPS_H
diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig
index 4d3a95768f2f3..2064ac3c892f6 100644
--- a/lldb/bindings/python/python-typemaps.swig
+++ b/lldb/bindings/python/python-typemaps.swig
@@ -637,9 +637,7 @@ template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 // These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
 // and fixed so they will not crash if PyObject_GetBuffer fails.
 // https://github.com/swig/swig/issues/1640
-//
-// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper,
-// doing it right away is not legal according to the python buffer protocol.
+#if SWIG_VERSION < 0x040100
 
 %define %pybuffer_mutable_binary(TYPEMAP, SIZE)
 %typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
@@ -678,6 +676,8 @@ template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 %pybuffer_binary(const uint8_t *buf, size_t num_bytes);
 %pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes);
 
+#endif
+
 %typemap(in) (const char **symbol_name, uint32_t num_names) {
   using namespace lldb_private;
   /* Check if is a list  */

The bug [1] this is working around was fixed in SWIG 4.1. The workaround
uses functions and constants that are not part of the limited API, which
I'm trying to eliminate to make LLDB compatible with the Python Limited
C API [2].

[1] swig/swig#1640
[2] llvm#151617
@JDevlieghere JDevlieghere force-pushed the Py_buffer_RAII-workaround branch from 5baef17 to 169d7d8 Compare November 13, 2025 18:33
@JDevlieghere JDevlieghere merged commit ac2d3d1 into llvm:main Nov 13, 2025
10 checks passed
@JDevlieghere JDevlieghere deleted the Py_buffer_RAII-workaround branch November 13, 2025 19:07
@llvm-ci
Copy link
Collaborator

llvm-ci commented Nov 13, 2025

LLVM Buildbot has detected a new failure on builder lldb-x86_64-debian running on lldb-x86_64-debian while building lldb at step 4 "build".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/35160

Here is the relevant piece of the build log for the reference
Step 4 (build) failure: build (failure)
...
4.873 [51/12/79] Linking CXX executable bin/llvm-extract
4.882 [51/11/80] Linking CXX executable bin/llvm-jitlink
5.157 [51/10/81] Linking CXX executable bin/diagtool
5.209 [51/9/82] Linking CXX shared module lib/CheckerDependencyHandlingAnalyzerPlugin.so
5.220 [51/8/83] Linking CXX shared module lib/CheckerOptionHandlingAnalyzerPlugin.so
5.222 [51/7/84] Linking CXX shared module lib/SampleAnalyzerPlugin.so
5.512 [51/6/85] Linking CXX executable bin/clang-diff
5.568 [51/5/86] Linking CXX executable bin/clang-installapi
5.573 [51/4/87] Linking CXX executable bin/clang-refactor
8.768 [51/3/88] Building CXX object tools/lldb/source/API/CMakeFiles/liblldb.dir/__/__/bindings/python/LLDBWrapPython.cpp.o
FAILED: tools/lldb/source/API/CMakeFiles/liblldb.dir/__/__/bindings/python/LLDBWrapPython.cpp.o 
/usr/bin/clang++ -DGTEST_HAS_RTTI=0 -DHAVE_ROUND -DLLDB_IN_LIBLLDB -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/source/API -I/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/source/API -I/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/include -I/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/include -I/home/worker/2.0.1/lldb-x86_64-debian/build/include -I/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/include -I/usr/include/python3.13 -I/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/llvm/../clang/include -I/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/../clang/include -I/home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/source -I/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/source -isystem /usr/include/libxml2 -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wno-pass-failed -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -ffunction-sections -fdata-sections -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-vla-extension -O3 -DNDEBUG -std=c++17 -fPIC  -fno-exceptions -funwind-tables -fno-rtti -UNDEBUG  -w -Wno-sequence-point -Wno-cast-qual -MD -MT tools/lldb/source/API/CMakeFiles/liblldb.dir/__/__/bindings/python/LLDBWrapPython.cpp.o -MF tools/lldb/source/API/CMakeFiles/liblldb.dir/__/__/bindings/python/LLDBWrapPython.cpp.o.d -o tools/lldb/source/API/CMakeFiles/liblldb.dir/__/__/bindings/python/LLDBWrapPython.cpp.o -c /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/bindings/python/LLDBWrapPython.cpp
/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/bindings/python/LLDBWrapPython.cpp:35063:11: error: use of undeclared identifier 'PyObject_AsWriteBuffer'; did you mean 'PyObject_GetBuffer'?
 35063 |     res = PyObject_AsWriteBuffer(swig_obj[1], &buf, &size);
       |           ^~~~~~~~~~~~~~~~~~~~~~
       |           PyObject_GetBuffer
/usr/include/python3.13/pybuffer.h:46:17: note: 'PyObject_GetBuffer' declared here
   46 | PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
      |                 ^
/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/bindings/python/LLDBWrapPython.cpp:35063:47: error: cannot initialize a parameter of type 'Py_buffer *' with an rvalue of type 'void **'
 35063 |     res = PyObject_AsWriteBuffer(swig_obj[1], &buf, &size);
       |                                               ^~~~
/usr/include/python3.13/pybuffer.h:46:62: note: passing argument to parameter 'view' here
   46 | PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
      |                                                              ^
/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/bindings/python/LLDBWrapPython.cpp:35135:11: error: use of undeclared identifier 'PyObject_AsReadBuffer'; did you mean 'PyObject_GetBuffer'?
 35135 |     res = PyObject_AsReadBuffer(swig_obj[1], &buf, &size);
       |           ^~~~~~~~~~~~~~~~~~~~~
       |           PyObject_GetBuffer
/usr/include/python3.13/pybuffer.h:46:17: note: 'PyObject_GetBuffer' declared here
   46 | PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
      |                 ^
/home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb/bindings/python/LLDBWrapPython.cpp:35135:46: error: cannot initialize a parameter of type 'Py_buffer *' with an rvalue of type 'const void **'
 35135 |     res = PyObject_AsReadBuffer(swig_obj[1], &buf, &size);
       |                                              ^~~~
/usr/include/python3.13/pybuffer.h:46:62: note: passing argument to parameter 'view' here
   46 | PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view,
      |                                                              ^
4 errors generated.
13.123 [51/2/89] Building CXX object lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
14.462 [51/1/90] Building CXX object lib/LTO/CMakeFiles/LLVMLTO.dir/LTO.cpp.o
ninja: build stopped: subcommand failed.

@JDevlieghere
Copy link
Member Author

JDevlieghere commented Nov 13, 2025

The Debian builder is using SWIG 4.0 so it's exercising that code path. Looking into it.

According to the build bot page, the Debian bot is using swig 4.3.0-1. The issue is Python 3.13. I'm able to repro with that version locally.

@JDevlieghere
Copy link
Member Author

Ugh, okay, this is going to be a problem... SWIG is using the "Old Buffer Protocol" when targeting the limited API: https://github.com/swig/swig/blob/master/Lib/python/pybuffer.i. However these were removed in Python 3.13...

@JDevlieghere
Copy link
Member Author

Seems like SWIG is aware of the problem: swig/swig@05c439d

llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Nov 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants