[C++-sig] BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS with default args dumps core

Holger Joukl Holger.Joukl at LBBW.de
Fri Apr 1 18:01:15 CEST 2011


Hi all,

I'm having trouble wrapping a very simple member function with Boost.Python
using the
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS macro, getting a segmentation fault.

I run into the problem both with Boost 1.44.0 and 1.46.1, running on
Solaris 10/Sparc
using gcc 4.5.1 and Python 2.7.1.

What's a bit strange is that I can run the offending Python code snippet
successfully
iff there is a Boost.Python induced exception raised before this code gets
invoked,
i.e. there are reproducable situations where the same code does not suffer
the segfault;
see "##### test runs" below.


##### wrapped class
$ cat default_arguments_class.hpp

class DefaultArgs {
 public: // member functions
    int foo(int arg1=100, int arg2=10) { return arg1 - arg2; };
};


##### wrapper code
$ cat default_arguments_wrap.cpp

// file default_arguments_wrap.cpp

#include <boost/python.hpp>
#include "default_arguments_class.hpp"

namespace bp = boost::python;


BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(DefaultArgs_foo_overloads,
DefaultArgs::foo, 0, 2)

BOOST_PYTHON_MODULE(defaultargs)
{
    bp::class_<DefaultArgs>("DefaultArgs", "DefaultArgs class docstring")
        .def("foo", &DefaultArgs::foo, (bp::arg("arg1")=100,
bp::arg("arg2")=10))
        .def("foo_macro", &DefaultArgs::foo, DefaultArgs_foo_overloads())
        .def("foo_macro_a1_a2_with_defaults", &DefaultArgs::foo,
DefaultArgs_foo_overloads((bp::arg("arg1")=100, bp::arg("arg2")=10)))
        .def("foo_macro_a2", &DefaultArgs::foo,
DefaultArgs_foo_overloads((bp::arg("arg2"))))
    ;
};


##### the Jamroot file
$ cat Jamroot

# get the environment variable "USER"
import os ;
local _USER = [ os.environ USER ] ;
#ECHO $(_USER) ;

local _BOOST_ROOT = /var/tmp/$(_USER)/boost_apps/boost ;
local _BOOST_VERSION = boost_1_46_1 ;
#local _BOOST_VERSION = boost_1_44_0 ;
#ECHO $(_BOOST_ROOT) ;


use-project boost : $(_BOOST_ROOT)/$(_BOOST_VERSION) ;


# Set up the project-wide requirements that everything uses the
# boost_python library from the project whose global ID is
# /boost/python.


project minimal
        : requirements <library>/boost/python//boost_python

<dll-path><variant>debug:$(_BOOST_ROOT)/build/$(_BOOST_VERSION)/py2.7/stage/debug/lib

<dll-path><variant>release:$(_BOOST_ROOT)/build/$(_BOOST_VERSION)/py2.7/stage/release/lib
        ;

python-extension defaultargs
        : # sources + // Add all files here otherwise we get undefined
symbol errors like
        default_arguments_wrap.cpp

        : # requirements *
        : # default-build *
        : # usage-requirements *
        ;


##### simple test script
$ cat test_defaultargs2.py

#!/apps/local/gcc/4.5.1/bin/python2.7

import os
import sys
import argparse

_USER=os.getenv("USER")
parser = argparse.ArgumentParser()
parser.add_argument(
    '--path', type=str,
    help='lib installation base path (default: %(default)s)',
    default='/var/tmp/%s/boost_apps/boost/build/boost_1_44_0/py2.7/'
    'minimal/gcc-4.5.1' % (_USER),)
parser.add_argument(
    '--variant', type=str, default='debug',
    help='lib installation path variant (default: %(default)s)')
parser.add_argument(
    '--with-exception', action='store_true',
    help='prepend a test with successful Boost exception')
args = parser.parse_args()


EXPATH = os.path.join(args.path, args.variant)

sys.path.insert(1, EXPATH)

try:
    import defaultargs
except:
    print "sys.path set correctly?", sys.path
    raise


d = defaultargs.DefaultArgs()

if args.with_exception:
    try:
        print "d.foo_macro_a2(1, 2, 3):", d.foo_macro_a2(1, 2, 3)
    except Exception, e:
        print e

print "d.foo_macro_a2(arg2=60):", d.foo_macro_a2(arg2=60)

##### Test run

$ ./test_defaultargs2.py
--path=/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1
 --with-exception
d.foo_macro_a2(1, 2, 3): Python argument types in
    DefaultArgs.foo_macro_a2(DefaultArgs, int, int, int)
did not match C++ signature:
    foo_macro_a2(DefaultArgs {lvalue})
    foo_macro_a2(DefaultArgs {lvalue}, int)
    foo_macro_a2(DefaultArgs {lvalue}, int, int arg2)
d.foo_macro_a2(arg2=60):
Traceback (most recent call last):
  File "./test_defaultargs2.py", line 42, in <module>
    print "d.foo_macro_a2(arg2=60):", d.foo_macro_a2(arg2=60)
Boost.Python.ArgumentError: Python argument types in
    DefaultArgs.foo_macro_a2(DefaultArgs)
did not match C++ signature:
    foo_macro_a2(DefaultArgs {lvalue})
    foo_macro_a2(DefaultArgs {lvalue}, int)
    foo_macro_a2(DefaultArgs {lvalue}, int, int arg2)

1 $ ./test_defaultargs2.py
--path=/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1

Segmentation Fault (core dumped)

139  $ /apps/local/gcc/4.5.1/bin/gdb /apps/local/gcc/4.5.1/bin/python2.7 -c
core
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.10".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /apps/local/gcc/4.5.1/bin/python2.7...done.

warning: core file may not match specified executable file.
[New LWP 1]
Reading symbols from /lib/libsocket.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib/libsocket.so.1
Reading symbols from /lib/libnsl.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/librt.so.1
Reading symbols from /lib/libdl.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libdl.so.1
Reading symbols from /lib/libm.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib/libm.so.2
Reading symbols from /lib/libc.so.1...(no debugging symbols found)...done.
[Thread debugging using libthread_db enabled]
[New Thread 1 (LWP 1)]
Loaded symbols for /lib/libc.so.1
Reading symbols from /lib/libaio.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib/libaio.so.1
Reading symbols from /lib/libmd.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/libmd.so.1
Reading symbols from /platform/SUNW,Sun-Fire-V490/lib/libc_psr.so.1...(no
debugging symbols found)...done.
Loaded symbols for /platform/SUNW,Sun-Fire-V490/lib/libc_psr.so.1
Reading symbols from
/usr/lib/locale/en_US.ISO8859-1/en_US.ISO8859-1.so.3...(no debugging
symbols found)...done.
Loaded symbols for /usr/lib/locale/en_US.ISO8859-1/en_US.ISO8859-1.so.3
Reading symbols from /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/strop.so...done.
Loaded symbols for /apps/local/gcc/4.5.1/lib/python2.7/lib-dynload/strop.so
Reading symbols from /apps/prod/gcc/4.5.1/lib/libgcc_s.so.1...done.
Loaded symbols for /apps/prod/gcc/4.5.1/lib/libgcc_s.so.1
Reading symbols from /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/operator.so...done.
Loaded symbols for /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/operator.so
Reading symbols from /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/_functools.so...done.
Loaded symbols for /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/_functools.so
Reading symbols from /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/_locale.so...done.
Loaded symbols for /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/_locale.so
Reading symbols from /apps/prod/gcc/4.5.1/lib/libintl.so.8...done.
Loaded symbols for /apps/prod/gcc/4.5.1/lib/libintl.so.8
Reading symbols from /apps/prod/gcc/4.5.1/lib/libiconv.so.2...done.
Loaded symbols for /apps/prod/gcc/4.5.1/lib/libiconv.so.2
Reading symbols from /lib/libsec.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib/libsec.so.1
Reading symbols from /lib/libavl.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib/libavl.so.1
Reading symbols from /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/_struct.so...done.
Loaded symbols for /apps/local/gcc/4.5.1
/lib/python2.7/lib-dynload/_struct.so
Reading symbols from
/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1
/debug/defaultargs.so...done.
Loaded symbols for
/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/minimal/gcc-4.5.1
/debug/defaultargs.so
Reading symbols from
/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/stage/debug/lib/libboost_python.so.1.44.0...done.

Loaded symbols for
/var/tmp/lb54320/boost_apps/boost/build/boost_1_44_0/py2.7/stage/debug/lib/libboost_python.so.1.44.0

Reading symbols from /apps/local/gcc/4.5.1/lib//libstdc++.so.6...done.
Loaded symbols for /apps/local/gcc/4.5.1/lib//libstdc++.so.6
Reading symbols from /apps/local/gcc/4.5.1/lib//libgcc_s.so.1...done.
Loaded symbols for /apps/local/gcc/4.5.1/lib//libgcc_s.so.1
Reading symbols from /platform/SUNW,Sun-Fire-V490/lib/libmd_psr.so.1...(no
debugging symbols found)...done.
Loaded symbols for /platform/SUNW,Sun-Fire-V490/lib/libmd_psr.so.1
Reading symbols from /lib/ld.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/ld.so.1
Core was generated by `/apps/local/gcc/4.5.1/bin/python2.7
./test_defaultargs2.py --path=/var/tmp/lb54'.
Program terminated with signal 11, Segmentation fault.
#0  0xfed05ee0 in boost::python::objects::find_instance_impl
(inst=0x33e3a0,
    type=..., null_shared_ptr_only=false) at
libs/python/src/object/class.cpp:485
485           if (Py_TYPE(Py_TYPE(inst)) != &class_metatype_object)
(gdb) where
#0  0xfed05ee0 in boost::python::objects::find_instance_impl
(inst=0x33e3a0,
    type=..., null_shared_ptr_only=false) at
libs/python/src/object/class.cpp:485
#1  0xfecf9fd8 in boost::python::converter::rvalue_from_python_stage1 (
    source=0x33e3a0, converters=...) at
libs/python/src/converter/from_python.cpp:46
#2  0xfedc0dc0 in
boost::python::converter::arg_rvalue_from_python<int>::arg_rvalue_from_python
 (this=0xffbfed80, obj=0x33e3a0)
    at
/var/tmp/lb54320/boost_apps/boost/boost_1_44_0/boost/python/converter/arg_from_python.hpp:299
#3  0xfedc02fc in boost::python::arg_from_python<int>::arg_from_python (
    this=0xffbfed80, source=0x33e3a0)
    at
/var/tmp/lb54320/boost_apps/boost/boost_1_44_0/boost/python/arg_from_python.hpp:70
#4  0xfedbf288 in impl<int (*)(DefaultArgs&, int),
boost::python::default_call_policies, boost::mpl::vector3<int,
DefaultArgs&, int> >::operator() (this=0x1efdfc,
    args_=0x33e370)
    at
/var/tmp/lb54320/boost_apps/boost/boost_1_44_0/boost/preprocessor/iteration/detail/local.hpp:37
#5  0xfedbe9cc in
boost::python::objects::caller_py_function_impl<boost::python::detail::caller<int
 (*)(DefaultArgs&, int), boost::python::default_call_policies,
boost::mpl::vector3<int, DefaultArgs&, int> > >::operator() (this=0x1efdf8,
args=0x33e370,
    kw=0x341270)
    at
/var/tmp/lb54320/boost_apps/boost/boost_1_44_0/boost/python/object/py_function.hpp:38
#6  0xfed0ca48 in boost::python::objects::py_function::operator()
(this=0x2053b0,
    args=0x33e370, kw=0x341270) at
./boost/python/object/py_function.hpp:143
#7  0xfed0996c in boost::python::objects::function::call (this=0x2640c0,
    args=0x33e370, keywords=0x341270) at
libs/python/src/object/function.cpp:226
#8  0xfed0b748 in boost::python::objects::(anonymous
namespace)::bind_return::operator() (this=0xffbff198) at
libs/python/src/object/function.cpp:585
#9  0xfed0c564 in
boost::detail::function::void_function_ref_invoker0<boost::python::objects::<unnamed>::bind_return,
 void>::invoke(boost::detail::function::function_buffer &)
(function_obj_ptr=...) at ./boost/function/function_template.hpp:188
#10 0xfed294e4 in boost::function0<void>::operator() (this=0xffbff124)
    at ./boost/function/function_template.hpp:1013
#11 0xfed288d0 in boost::python::handle_exception_impl (f=...)
    at libs/python/src/errors.cpp:25
#12 0xfed0c070 in
boost::python::handle_exception<boost::python::objects::<unnamed>::bind_return>(boost::python::objects::(anonymous
 namespace)::bind_return) (f=Cannot access memory at address 0x0
)
    at ./boost/python/errors.hpp:29
#13 0xfed0b850 in boost::python::objects::function_call (func=0x2640c0,
    args=0x33e370, kw=0x341270) at libs/python/src/object/function.cpp:626
#14 0x0002aa14 in PyObject_Call (func=0x2640c0, arg=0x33e370, kw=0x341270)
    at Objects/abstract.c:2529
#15 0x000b26a0 in do_call (f=0x2da2f8, throwflag=<value optimized out>)
    at Python/ceval.c:4230
#16 call_function (f=0x2da2f8, throwflag=<value optimized out>) at
Python/ceval.c:4035
---Type <return> to continue, or q <return> to quit---


Any hints appreciated. Should I report this as a Boost.Python bug?

Best regards,
Holger

Landesbank Baden-Wuerttemberg
Anstalt des oeffentlichen Rechts
Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz
HRA 12704
Amtsgericht Stuttgart



More information about the Cplusplus-sig mailing list