-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compiling two modules with different compilers leads to segfault in class.h #1262
Comments
In general you want everything to be built with the same compiler, and same version of that compiler, see: |
STL internal data structures are not guaranteed to be compatible across compiler major versions, and definitely not across entirely different compilers. Pybind11 uses STL data structures to organize its internal state, hence it is important that extension modules are also compiled with the same compiler (otherwise, all sorts of corruption can occur). |
How do you recommend shipping binary python extension modules that use pybind11 if you don't know what other extensions a user might have installed that may use pybind11 and were built with another compiler version? Is there a way to completely isolate the pybind11 state across these extensions? |
The compiler version isn't quite as critical as the STL (and its version). STL versions are usually, but not always, backwards-compatible with previous versions of the same STL. For instance, you're usually fine mixing modules built with gcc-5/gcc-6/gcc-7/gcc-8/clang-* on linux, since they all use gcc's stdlibc++. Mixing any of those with clang using libc++—which is the default when using clang under macOS, but not on Linux—is asking for trouble. Very rarely the stl breaks backwards compatibility—IIRC, the last time for stdlibc++ was when version 5 came out (and was related to C++11 compatibility), so crossing the pre-5 and post-5 gcc boundary is likely another no-no. What you're getting trying to load one The only way around it is really to isolate the software: keep all your g++/stdlibc++-compiled code separate from your clang++/libc++-compiled code. And while that is a nuissance, it's not something that pybind can realistically do anything about. |
Dear all, I've realized that this has become a bit of a painful problem, particularly when installing external packages where one may not have control over what compiler is being used. The following commit, currently on master, namespaces pybind11's internal data structures based on the value of the __GXX_ABI_VERSION flag, if present. My hope is that this should avoid this kind of breakage in the future. For those of you who are affected, could you let me know if this addresses the problem? My plan then would be to push this into a patch release of pybind11. Best, |
I'll try it today. Thanks for your help |
It solved my problem. Thanks! |
Hi @wjakob , do you have a schedule for the patch release? |
I've added another commit that provides an even stricter separation: c9f5a46 |
Released in v2.4.0 now :) |
(not a patch release after all, because there are also some minor new features) |
The open source package pyonmttok was recently updated to use pybind11. However, compiling 2 pybind11 packages with different toolchains caused a segmentation fault when used in the same project. See for example pybind/pybind11#1262 For now, we revert this internal package back to Boost.Python.
See scipy/scipy#11237 and pybind/pybind11#1262 for details. tl;dr pybind11 is the first version where its symbol names are prefixed with the GCC (or Clang) version it was compiled with.
See scipy/scipy#11237 and pybind/pybind11#1262 for details. tl;dr pybind11 is the first version where its symbol names are prefixed with the GCC (or Clang) version it was compiled with.
See scipy/scipy#11237 and pybind/pybind11#1262 for details. tl;dr pybind11 is the first version where its symbol names are prefixed with the GCC (or Clang) version it was compiled with.
See scipy/scipy#11237 and pybind/pybind11#1262 for details. tl;dr pybind11 is the first version where its symbol names are prefixed with the GCC (or Clang) version it was compiled with.
Thank you for fixing this @wjakob ! I can confirm that this patch worked for us as well. |
This seems resolved. If more stuff needs to be done in this regard, please open a new issue. |
We have a library that uses pybind11 to wrap its internal C++ code. We now also want to allow external extension modules to be usable with the library. However, we are noticing that when our library is built with one compiler and an extension module with another, there is a segfault within pybind11 upon import.
I am able to reproduce the bug with a small example:
a.cpp
(imagine our library)b.cpp
(imagine an extension)setup_a.py
setup_b.py
Then:
CXX=clang++ CC=clang python setup_a.py install
CXX=g++-7 CC=gcc-7 python setup_b.py install
Then:
It seems the
metaclass
variable isnullptr
in this case. This can be confirmed by putting an assertion into that location inclass.h
.This is on macOS Sierra, but we see the same on Linux. We also observe this for certain combinations of different GCC versions. In the example above I use Python 3.5, but the same is observable for Python 3.6 and Python 2.7.
The text was updated successfully, but these errors were encountered: