You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What version (or hash if on master) of pybind11 are you using?
2.9, 2.10 (code seems similar on current master)
Problem description
pybind11 enforces hidden visibility for all symbols, apart from exceptions (including error_already_set), where the PYBIND11_EXPORT_EXCEPTION macro is used to grant them default visibility . This is presumably to allow pybind11-specific exceptions to be caught across DSO boundaries, which is useful.
However, if the DSOs use different versions of pybind11 internally, then e.g. catching error_already_set, even as a std::exception, and calling .what() on it can give garbled text (at best).
We experienced this exact scenario with a library built against pybind11 2.10 and an application built against 2.9. Between these versions, the ABI of error_already_set changed dramatically.
I would suggest an inline namespace (using the PYBIND11_VERSION_MAJOR and PYBIND11_VERSION_MINOR macros to construct a suitable name). This namespace would wrap all exported types (i.e. exceptions), or perhaps just all of pybind11 (which has the advantage that there is then technically no need to enforce hidden visibility for other symbols). E.g. the full symbolic namespace could be pybind11::v2_13 but code could still refer to it as pybind11 (because of the inline).
Reproducible example code
Tricky to put together a code example. I will explain in words what happens in our product.
You need a full example project with two DSOs. In the order they are loaded, the first uses pybind11 2.9 and the second uses 2.10.
The first DSO calls through to the second, which calls out to a Python function.
The Python function then `raise`s.
The first DSO catches the resulting C++ exception as a `std::exception` and calls `.what()` on it to verify the expected exception message. It will be garbled.
You can see on stepping through a GCC 11 build using GDB, the 2.10 class is used to construct the exception, but it gets the 2.9 vtable pointer.
Is this a regression? Put the last known working version here if it is.
Not a regression
The text was updated successfully, but these errors were encountered:
Required prerequisites
What version (or hash if on master) of pybind11 are you using?
2.9, 2.10 (code seems similar on current master)
Problem description
pybind11 enforces
hidden
visibility for all symbols, apart from exceptions (includingerror_already_set
), where thePYBIND11_EXPORT_EXCEPTION
macro is used to grant themdefault
visibility . This is presumably to allow pybind11-specific exceptions to be caught across DSO boundaries, which is useful.However, if the DSOs use different versions of pybind11 internally, then e.g. catching
error_already_set
, even as astd::exception
, and calling.what()
on it can give garbled text (at best).We experienced this exact scenario with a library built against pybind11 2.10 and an application built against 2.9. Between these versions, the ABI of
error_already_set
changed dramatically.I would suggest an inline namespace (using the
PYBIND11_VERSION_MAJOR
andPYBIND11_VERSION_MINOR
macros to construct a suitable name). This namespace would wrap all exported types (i.e. exceptions), or perhaps just all of pybind11 (which has the advantage that there is then technically no need to enforcehidden
visibility for other symbols). E.g. the full symbolic namespace could bepybind11::v2_13
but code could still refer to it aspybind11
(because of theinline
).Reproducible example code
Is this a regression? Put the last known working version here if it is.
Not a regression
The text was updated successfully, but these errors were encountered: