Yes, we do link our internal code with a different Boost version; we build and 
(conda) package it ourselves.

Why should this matter if Parquet links it statically?  If static linking won't 
allow us to use our own version, why bother linking statically at all?

Thanks,
Alex



On 02/17/2018 10:52 AM, Uwe L. Korn wrote:
Hi,

The issue is here no that Boost is linked statically in one and dynamically in 
another but that you link against two different boost versions. The stacktrace 
shows links to Boost 1.55 whereas Arrow should be linked against 1.65 or 1.66 
(the one coming from conda-forge). Arrow requires at least a Boost version of 
1.60+ to work. The most likely guess from my side would be that your internal 
modules are linked against the system boost, not the conda-provided boost.

Uwe

Am 17.02.2018 um 16:47 schrieb Alex Samuel <a...@alexsamuel.net>:

Hi there,

Sure, I'll append top of the stack.  You can see our internal function 
"asd::infra::util::start_of_date"; everything else is Boost, Python, or 
libstdc++.

My understanding (though I haven't demonstrated this conclusively) is that, because 
Python loads extension modules RTLD_GLOBAL, an extension module can pick up symbols from 
another or its dependencies, even if the former "usually" satisfy relocations 
from their own shared lib dependencies.  So, one module linking Boost statically may 
interfere with another that links it dynamically, by injecting its symbols.

If necessary I can try to put together a minimal test case, but no guarantee it 
will actually trigger the bug.  But it might be worth testing my theory above 
first, with gdb or by some other means.

Thanks!
Alex



#0  0x00007f6ddeba4c8b in std::basic_string<char, std::char_traits<char>, std::allocator<char> 
>::basic_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) 
()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/numexpr/../../../libstdc++.so.6

#1  0x00007f6dd4f978d6 in 
boost::re_detail::cpp_regex_traits_char_layer<char>::init() ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../.././libboost_regex.so.1.55.0

#2  0x00007f6dd4fdbd88 in boost::object_cache<boost::re_detail::cpp_regex_traits_base<char>, 
boost::re_detail::cpp_regex_traits_implementation<char> 
>::do_get(boost::re_detail::cpp_regex_traits_base<char> const&, unsigned long) ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../.././libboost_regex.so.1.55.0

#3  0x00007f6dd4fe5bb5 in boost::basic_regex<char, boost::regex_traits<char, 
boost::cpp_regex_traits<char> > >::do_assign(char const*, char const*, unsigned int) 
()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../.././libboost_regex.so.1.55.0

#4  0x00007f6dd575a90e in asd::infra::util::start_of_date(std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > const&, char const*) ()

    at 
/prod/sys/sysasd/opt/tudor-devtools/v1.3/Linux.el6.x86_64-corei7-avx-gcc4.83-anaconda2.0.1/include/boost/regex/v4/basic_regex.hpp:382

#5  0x00007f6dd2c36734 in boost::python::objects::caller_py_function_impl<boost::python::detail::caller<unsigned long 
(*)(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*), 
boost::python::default_call_policies, boost::mpl::vector3<unsigned long, std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const&, char const*> > >::operator()(_object*, _object*) ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/util.so

#6  0x00007f6dd52ac71a in boost::python::objects::function::call(_object*, 
_object*) const ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../../libboost_python.so.1.55.0

#7  0x00007f6dd52aca68 in 
boost::detail::function::void_function_ref_invoker0<boost::python::objects::(anonymous 
namespace)::bind_return, void>::invoke(boost::detail::function::function_buffer&) 
()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../../libboost_python.so.1.55.0

#8  0x00007f6dd52b4cd3 in 
boost::python::detail::exception_handler::operator()(boost::function0<void> 
const&) const ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../../libboost_python.so.1.55.0

#9  0x00007f6dd2c32c03 in boost::detail::function::function_obj_invoker2<boost::_bi::bind_t<bool, 
boost::python::detail::translate_exception<asd::infra::Exception, void (*)(asd::infra::Exception const&)>, boost::_bi::list3<boost::arg<1>, 
boost::arg<2>, boost::_bi::value<void (*)(asd::infra::Exception const&)> > >, bool, boost::python::detail::exception_handler const&, 
boost::function0<void> const&>::invoke(boost::detail::function::function_buffer&, boost::python::detail::exception_handler const&, 
boost::function0<void> const&) ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/util.so

#10 0x00007f6dd52b4a9d in 
boost::python::handle_exception_impl(boost::function0<void>) ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../../libboost_python.so.1.55.0

#11 0x00007f6dd52ab2b3 in function_call ()

   from 
/space/asd/conda/envs/rd-20180212-0/lib/python2.7/site-packages/asd/infra/../../../../libboost_python.so.1.55.0

#12 0x00007f6df2bc8e93 in PyObject_Call (func=0x2799850, arg=<value optimized 
out>,

    kw=<value optimized out>) at Objects/abstract.c:2547

#13 0x00007f6df2c7b80d in do_call (f=<value optimized out>, throwflag=<value 
optimized out>)

    at Python/ceval.c:4569

#14 call_function (f=<value optimized out>, throwflag=<value optimized out>) at 
Python/ceval.c:4374

#15 PyEval_EvalFrameEx (f=<value optimized out>, throwflag=<value optimized 
out>) at Python/ceval.c:2989



On 02/17/2018 10:31 AM, Uwe L. Korn wrote:
Hello,
I am not sure why we are linking statically in the conda-forge packages, as a 
gut feeling we should link dynamically there. Wes, can you remember why?
Alex, would it be possible for you to send us the part of the segmentation 
fault that is not private to your modules. That would be a good indicator for 
us what is going wrong.
Typically it is best when you enable coredumps with `ulimit -c unlimited` and 
then run your program as usual. There should be no performance penalty. When 
ist segfaults, run `gdb python core` (note that the core file might also be 
postfixed with the PID but that depends on your system). In gdb type 'thread 
apply all bt full'. Post thd output pf that command and strip away the parts we 
should not see. Most relevant will be the stacktrace of the thread that 
segfaulted.
Uwe
Am 16.02.2018 um 23:17 schrieb Alex Samuel <a...@alexsamuel.net>:

Hello,

I am having some troubles using the Continuum PyArrow conda package 
dependencies in conjunction with internal C++ extension modules.

Apparently, Arrow and Parquet link Boost statically.  We have some internal 
packages containing C++ code that linking Boost libs dynamicaly.  If we import 
Feather as well as our own extension modules into the same Python process, we 
get random segfaults in Boost.  I think what's happening is that our extension 
modules are picking up Boost's symbols from Arrow and Parquet already loaded 
into the process, rather than from our own Boost shared libs.

Could anyone explain the policy for linking Boost in binary distributions, 
particularly conda packages?  What is your expectation for how other C++ 
extension modules should be built?

Thanks in advance,
Alex


Reply via email to