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