Opened 10 years ago

Closed 10 years ago

#8001 closed Bugs (invalid)

stl_input_iterator generators garbage collection problems

Reported by: Wichert Akkerman <wichert@…> Owned by: Ralf W. Grosse-Kunstleve
Milestone: To Be Determined Component: python USE GITHUB
Version: Boost 1.52.0 Severity: Problem
Keywords: Cc:

Description

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. To test this I rewrote my code to use a standard !PyObject_GetIter / !PyIter_Next loop and that indeed made all problems go away.

Change History (1)

comment:1 by Ralf W. Grosse-Kunstleve, 10 years ago

Resolution: invalid
Status: newclosed

It is highly unlikely that the problem is in Boost.Python. Please use valgrind or some similar tool to debug the problem, which is most likely in your code.

Note: See TracTickets for help on using tickets.