aboutsummaryrefslogtreecommitdiff
path: root/paludis/python_hooks.cc
diff options
context:
space:
mode:
authorAvatar Marvin Schmidt <marv@exherbo.org> 2021-06-09 20:22:47 +0200
committerAvatar Marvin Schmidt <marv@exherbo.org> 2021-09-17 10:37:45 +0200
commit4cccab5c978b0dc241edfa3a620f4497c6e9be70 (patch)
treed6c0bf823e33d7287b2616b978793c4d0c560c14 /paludis/python_hooks.cc
parent4a3c2b65d9162ba29d0300057d29c43896c6eec1 (diff)
downloadpaludis-4cccab5c978b0dc241edfa3a620f4497c6e9be70.tar.gz
paludis-4cccab5c978b0dc241edfa3a620f4497c6e9be70.tar.xz
python: Assure Py_Initialize is called before static members are initialized
The python hooker test segfaulted because the static member variable of type `boost::python::dict` caused a call to `PyDict_New` and subsequently `_PyObject_GC_Alloc` before `Py_Initialize` was called: > [==========] Running 6 tests from 1 test suite. > [----------] Global test environment set-up. > [----------] 6 tests from Hooker > [ RUN ] Hooker.Works > > Program received signal SIGSEGV, Segmentation fault. > 0x00007ffff67863ac in _PyObject_GC_Alloc () from /usr/x86_64-pc-linux-gnu/lib/libpython3.9.so.1.0 > #0 0x00007ffff67863ac in _PyObject_GC_Alloc () from /usr/x86_64-pc-linux-gnu/lib/libpython3.9.so.1.0 > #1 0x00007ffff6786ac3 in _PyObject_GC_New () from /usr/x86_64-pc-linux-gnu/lib/libpython3.9.so.1.0 > #2 0x00007ffff669156c in PyDict_New () from /usr/x86_64-pc-linux-gnu/lib/libpython3.9.so.1.0 > #3 0x00007ffff64abafe in boost::python::detail::dict_base::dict_base() () from /usr/x86_64-pc-linux-gnu/lib/libboost_python39.so.1.76.0 > #4 0x00007ffff6ea3100 in boost::python::dict::dict (this=0x7ffff6eba728 <(anonymous namespace)::PyHookFile::_output_wrapper_namespace>) at /usr/x86_64-pc-linux-gnu/include/boost/python/dict.hpp:89 > #5 0x00007ffff6ea25bb in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at ../paludis/python_hooks.cc:82 > #6 0x00007ffff6ea2ac3 in _GLOBAL__sub_I_python_hooks.cc(void) () at ../paludis/python_hooks.cc:445 > #7 0x00007ffff7fdb0be in call_init () from /usr/x86_64-pc-linux-gnu/lib/ld-linux-x86-64.so.2 > #8 0x00007ffff7fdb1ac in _dl_init () from /usr/x86_64-pc-linux-gnu/lib/ld-linux-x86-64.so.2 > #9 0x00007ffff69cff55 in _dl_catch_exception () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6 > #10 0x00007ffff7fdf474 in dl_open_worker () from /usr/x86_64-pc-linux-gnu/lib/ld-linux-x86-64.so.2 > #11 0x00007ffff69cfef8 in _dl_catch_exception () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6 > #12 0x00007ffff7fdec4b in _dl_open () from /usr/x86_64-pc-linux-gnu/lib/ld-linux-x86-64.so.2 > #13 0x00007ffff687f3cc in dlopen_doit () from /usr/x86_64-pc-linux-gnu/lib/libdl.so.2 > #14 0x00007ffff69cfef8 in _dl_catch_exception () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6 > #15 0x00007ffff69cffc3 in _dl_catch_error () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6 > #16 0x00007ffff687fbf9 in _dlerror_run () from /usr/x86_64-pc-linux-gnu/lib/libdl.so.2 > #17 0x00007ffff687f458 in dlopen () from /usr/x86_64-pc-linux-gnu/lib/libdl.so.2 > #18 0x00007ffff78f1041 in paludis::Hooker::_find_hooks (this=0x7fffffffde08, hook=...) at ../paludis/hooker.cc:634 > #19 0x00007ffff78f3145 in paludis::Hooker::perform_hook (this=0x7fffffffde08, hook=..., optional_output_manager=...) at ../paludis/hooker.cc:782 > #20 0x000055555555886b in Hooker_Works_Test::TestBody (this=0x55555558af80) at ../paludis/hooker_TEST.cc:44 > #21 0x00007ffff6e8368f in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) () from /usr/x86_64-pc-linux-gnu/lib/libgtest.so > #22 0x00007ffff6e7374e in testing::Test::Run() () from /usr/x86_64-pc-linux-gnu/lib/libgtest.so > #23 0x00007ffff6e738a5 in testing::TestInfo::Run() () from /usr/x86_64-pc-linux-gnu/lib/libgtest.so > #24 0x00007ffff6e7398d in testing::TestSuite::Run() () from /usr/x86_64-pc-linux-gnu/lib/libgtest.so > #25 0x00007ffff6e73e9b in testing::internal::UnitTestImpl::RunAllTests() () from /usr/x86_64-pc-linux-gnu/lib/libgtest.so > #26 0x00007ffff6e83b6f in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) () > from /usr/x86_64-pc-linux-gnu/lib/libgtest.so > #27 0x00007ffff6e740a6 in testing::UnitTest::Run() () from /usr/x86_64-pc-linux-gnu/lib/libgtest.so > #28 0x00007ffff6e919ab in main () from /usr/x86_64-pc-linux-gnu/lib/libgtest_main.so > #29 0x00007ffff68beb25 in __libc_start_main () from /usr/x86_64-pc-linux-gnu/lib/libc.so.6 > #30 0x000055555555859e in _start () > (gdb) Calling `Py_Initialize` from PyHookFile's ctor is too late since static members are initialized before the construction of the first PyHookFile instance. Fix this by introducing a RAII-style initializer class that calls `Py_Initialize` on construction and add a static member variable of that type to PyHookFile before its other static member variable.
Diffstat (limited to 'paludis/python_hooks.cc')
-rw-r--r--paludis/python_hooks.cc12
1 files changed, 10 insertions, 2 deletions
diff --git a/paludis/python_hooks.cc b/paludis/python_hooks.cc
index 248805e88..2a1fd095d 100644
--- a/paludis/python_hooks.cc
+++ b/paludis/python_hooks.cc
@@ -34,6 +34,15 @@ namespace
private:
static std::mutex _mutex;
+ struct Initializer
+ {
+ Initializer()
+ {
+ Py_Initialize();
+ }
+ };
+
+ static Initializer pyinit;
static bp::dict _local_namespace_base;
static bp::dict _output_wrapper_namespace;
static bp::object _format_exception;
@@ -79,6 +88,7 @@ namespace
};
std::mutex PyHookFile::_mutex;
+ PyHookFile::Initializer PyHookFile::pyinit;
bp::dict PyHookFile::_output_wrapper_namespace;
bp::dict PyHookFile::_local_namespace_base;
bp::object PyHookFile::_format_exception;
@@ -99,8 +109,6 @@ PyHookFile::PyHookFile(const FSPath & f, const bool r, const Environment * const
initialized = true;
try
{
- Py_Initialize();
-
bp::object main = bp::import("__main__");
bp::object global_namespace = main.attr("__dict__");