GC error due to stl_input_iterator
I am running into some unexpected errors when using stl_input_iterator. I have a fairly simple converter registered to convert an iterable list of values (custom enum) to a unordered_set. The code looks like this: struct advicetype_set_from_python { advicetype_set_from_python() { converter::registry::push_back(&convertible, &construct, type_id<std::unordered_set<AdviceType>>()); } static void* convertible(PyObject *obj) { if (obj==Py_None) return obj; PyObject* iter = PyObject_GetIter(obj); if (iter==NULL) { throw_error_already_set(); return 0; } Py_DECREF(iter); return obj; } static void construct(PyObject* obj, converter::rvalue_from_python_stage1_data *data) { std::unordered_set<AdviceType> result; if (obj!=Py_None) { object o = object(handle<>(obj)); stl_input_iterator<AdviceType> begin(o), end; result.insert(begin, end); } void *storage = ((converter::rvalue_from_python_storage<std::unordered_set<AdviceType>>*)data)->storage.bytes; new (storage) std::unordered_set<AdviceType>(result); data->convertible = storage; } }; When using this code we were seeing segfaults due to what appears to be invalid reference counters. Since I suspected a problem in this convertor I wrote a simple test which triggers the converter a number of times: for i in range(5000): my_func({AdviceType.one, AdviceType.two}) Which had an interesting result: the tests immediately aborted with a "Fatal Python error: GC object already tracked" error. Commenting out the contents of the if-statement in construct() made the problem go away, which makes we think the bug is in the stl_input_iterator used there. Am I doing something wrong here, or is this a boost bug? FWIW I am seeing this under both Boost 1.48 on an Ubuntu 12.04 machine and Boost 1.52 on OSX 10.8. I am not sure if this is related, but clang outputs an interesting warning for the in-place new that is required here: warning: cast from 'converter::rvalue_from_python_stage1_data *' to 'converter::rvalue_from_python_storage<std::unordered_set<AdviceType> > *' increases required alignment from 8 to 16 [-Wcast-align] void *storage = ((converter::rvalue_from_python_storage<std::unordered_set<AdviceType>>*)data)->storage.bytes; Wichert.
On Feb 6, 2013, at 14:30 , Wichert Akkerman <wichert@wiggy.net> wrote:
Which had an interesting result: the tests immediately aborted with a "Fatal Python error: GC object already tracked" error. Commenting out the contents of the if-statement in construct() made the problem go away, which makes we think the bug is in the stl_input_iterator used there. Am I doing something wrong here, or is this a boost bug? FWIW I am seeing this under both Boost 1.48 on an Ubuntu 12.04 machine and Boost 1.52 on OSX 10.8.
I rewrote my code to use a standard PyObject_GetIter / PyIter_Next loop and that made all problems go away, which suggests that stl_input_iterator was indeed the problem. Wichert.
participants (1)
-
Wichert Akkerman