Python встроенный в C ++ ошибка try_rich_compare для типов

0

У меня есть ошибка в моей программе, которая, похоже, связана с сопоставлением двух типов объектов в python. Вот ошибка из gdb

    Program received signal SIGSEGV, Segmentation fault.
0x00007fffc3acd35c in try_rich_compare (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:621
621 ../Objects/object.c: No such file or directory.
(gdb) bt
#0  0x00007fffc3acd35c in try_rich_compare (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:621
#1  0x00007fffc3acded7 in do_richcmp (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:930
#2  0x00007fffc3ace164 in PyObject_RichCompare (v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>, op=3) at ../Objects/object.c:982
#3  0x00007fffc3b74a24 in cmp_outcome (op=3, v=0x7fffcc433ec0 <UTOPIA::PyNodeType>, w=0x7fffc3a06ec0 <UTOPIA::PyNodeType>) at ../Python/ceval.c:4525
#4  0x00007fffc3b6bbbe in PyEval_EvalFrameEx (f=0x157e990, throwflag=0) at ../Python/ceval.c:2287
#5  0x00007fffc3b6ff3e in PyEval_EvalCodeEx (co=0x7fffc2553510, globals=0x7fffc254b1a8, locals=0x0, args=0x7fffc257c6a0, argcount=2, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0)
at ../Python/ceval.c:3252
#6  0x00007fffc3aa643b in function_call (func=0x7fffc2552300, arg=0x7fffc257c678, kw=0x0) at ../Objects/funcobject.c:526
#7  0x00007fffc3a64c79 in PyObject_Call (func=0x7fffc2552300, arg=0x7fffc257c678, kw=0x0) at ../Objects/abstract.c:2529
#8  0x00007fffc3a810a1 in instancemethod_call (func=0x7fffc2552300, arg=0x7fffc257c678, kw=0x0) at ../Objects/classobject.c:2602
#9  0x00007fffc3a64c79 in PyObject_Call (func=0x7fffd80df5e0, arg=0x7fffc2550370, kw=0x0) at ../Objects/abstract.c:2529
#10 0x00007fffc3a64de1 in call_function_tail (callable=0x7fffd80df5e0, args=0x7fffc2550370) at ../Objects/abstract.c:2561
#11 0x00007fffc3a651f3 in PyObject_CallMethod (o=0x7fffc255ced0, name=0x7fffcc4659a4 "invoke", format=0x7fffcc4659a2 "O") at ../Objects/abstract.c:2638
#12 0x00007fffcc45d556 in UTOPIA::Python_service_interface::invoke (this=0x14ed610, invocation_=0x16aa6f0, input_=...)
at /home/oni/Projects/utopia/components/libutopia/plugins/python/service_interface.cpp:134

Моя программа содержит библиотеку объектов. Некоторые из этих объектов обернуты внутри оболочки объекта python. Моя основная C++ программа загружает эту библиотеку python, чтобы получить определения этих типов. В этом случае тип нарушения выглядит следующим образом:

 // Node class
    static PyTypeObject PyNodeType =
    {
        PyObject_HEAD_INIT(0)
        0,                                 /* ob_size */
        "utopia.Node",                     /* tp_name */
        sizeof(PyNode),                    /* tp_basicsize */
        0,                                 /* tp_itemsize */
        (destructor) PyNode_dealloc,       /* tp_dealloc */
        0,                                 /* tp_print */
        0,                                 /* tp_getattr */
        0,                                 /* tp_setattr */
        0,                                 /* tp_compare */
        (reprfunc) PyNode_repr,            /* tp_repr */
        0,                                 /* tp_as_number */
        0,                                 /* tp_as_sequence */
        &PyNode_as_mapping,                /* tp_as_mapping */
        0,                                 /* tp_hash  */
        0,                                 /* tp_call */
        0,                                 /* tp_str */
        0,                                 /* tp_getattro */
        0,                                 /* tp_setattro */
        0,                                 /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT,                /* tp_flags */
        "UTOPIA::GenericNode class",       /* tp_doc */
        0,                                 /* tp_traverse */
        0,                                 /* tp_clear */
        0,                                 /* tp_richcompare */
        0,                                 /* tp_weaklistoffset */
        0,                                 /* tp_iter */
        0,                                 /* tp_iternext */
        PyNode_methods,                    /* tp_methods */
        0,                                 /* tp_members */
        0,                                 /* tp_getset */
        0,                                 /* tp_base */
        0,                                 /* tp_dict */
        0,                                 /* tp_descr_get */
        0,                                 /* tp_descr_set */
        0,                                 /* tp_dictoffset */
        (initproc) PyNode_init,            /* tp_init */
        0,                                 /* tp_alloc */
        PyNode_new,                        /* tp_new */
        0,                                 /* tp_free */
        0,                                 /* tp_is_gc */
        0,                                 /* tp_bases */
        0,                                 /* tp_mro */
        0,                                 /* tp_cache */
        0,                                 /* tp_subclasses */
        0,                                 /* tp_weaklist */
        0,                                 /* tp_del */
    };

Теперь, позже, программа C++ загружает библиотеку python2.7 и запускает python внутри себя. Затем он импортирует эту библиотеку python-оболочки.

Это означает, что этот PyNodeType появляется в программе C++, а также внутри экземпляра python, запущенного внутри программы C++. В какой-то момент эти две вещи сравниваются, и программа взрывается! : S

Не совсем уверен, как обойти это, поскольку определение необходимо в обоих местах.

Дальнейшая проверка показывает, что, хотя тип каким-то образом выведен, один из этих параметров заполнен нулевыми указателями

(gdb) print v
$4 = (PyObject *) 0x7fffcc433ec0 <UTOPIA::PyNodeType>
(gdb) print *v
$5 = {_ob_next = 0x0, _ob_prev = 0x0, ob_refcnt = 2, ob_type = 0x0}
(gdb) print *w
$6 = {_ob_next = 0x7fffd80b3310, _ob_prev = 0x7fffe00aca70, ob_refcnt = 43, ob_type = 0x7fffc3efc0c0 <PyType_Type>}

***ОБНОВИТЬ***

Поэтому, когда я создаю объект, я смотрю на ячейки памяти

PyNode* newPyNode = PyObject_New(PyNode, &PyNodeType);
(gdb) print &PyNodeType
$4 = (PyTypeObject *) 0x7fffe353cea0 <UTOPIA::PyNodeType>

Но тогда, если я посмотрю на поле ob_type в моем объекте newPyNode

(gdb) print *newPyNode
$7 = {_ob_next = 0x7fffe12fd1c8, _ob_prev = 0x7fffe32024e0 <refchain>, ob_refcnt = 1, ob_type = 0x7fffe2a10ec0 <UTOPIA::PyNodeType>, node = 0xef2cc0}

ob_type не соответствует. Что дает? Глядя на функции сравнения, такие как

PyObject_TypeCheck

... эти ячейки памяти должны быть одинаковыми.

Теги:

1 ответ

0

Похоже, он исправлен. Ive объединил CPP. Часть проекта с библиотекой python.so, которая, похоже, устранила проблему. Первый.so был таким образом, что основной проект мог загружать скрипты python, а второй - разрешить программе python доступ ко всем функциям утопии (наоборот). Объединение двух библиотек вместе, похоже, исправило это.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню