Спорадический segfault в расширении C ++ Python - PullRequest
0 голосов
/ 06 января 2012

У меня есть объект python, который получает доступ и загружает текст через HTTP. Я запускаю этот объект Python и обрабатываю этот текст, используя код C ++. * 1001 Т.е. *

/* CPPCode.cxx */
int main(...) {
    for(int i = 0; i < numURLs; i++) {
        // Python method returns a string
        PyObject *pyValue = PyObject_CallMethod(pyObjectInstance, pyFunctionName, par1, par2....);
        string valString = PyString_AsString(pHistValue);   
        // ... process string ... 
    }
} 

/* PyObject.py */
class PyClass:
    def PyFunction(...):
        try: urlSock = urllib.urlopen(urlName)
        except ...

        while(...) :
             dataStr = urlSock.readline()
             # do some basic string processing....

        return dataStr

Большинство URL работают нормально - код на С ++ получает правильную строку, я могу ее обработать, все хорошо и хорошо. Несколько конкретных URL, которые выглядят (в основном) так же, как и другие в браузере, приводят к segfault в методе PyString_AsString ():

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00000000000000b2
0x000000010007716d in PyString_AsString ()

Если я распечатаю строку, которая должна быть возвращена методом python ('dataStr' в псевдокоде выше), она выглядит хорошо! Я понятия не имею, что может быть причиной этой проблемы - любые советы о том, как действовать, будет принята с благодарностью! Спасибо

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~

РЕШЕНИЕ:

Код шаблона, который я использовал, вызывал

Py_DECREF(pyValue)

прежде чем я позвонил

PyString_AsString(pyValue)

Почему он был освобожден для определенных вызовов функций, я понятия не имею. Как говорит «Gecco» в комментариях ниже,

'Документация PyString_AsString гласит: «Указатель ссылается на внутренний буфер строки, а не на копию. Данные не должны быть изменены каким-либо образом, если только строка не была создана с использованием PyString_FromStringAndSize (NULL, size). Она не должна быть освобожденным. " «

Ответы [ 3 ]

1 голос
/ 06 января 2012

PyString_AsString документация гласит: «Указатель ссылается на внутренний буфер строки, а не на копию. Данные не должны быть изменены каким-либо образом, если только строка не была создана с использованием PyString_FromStringAndSize (NULL, size). Он не должен быть освобожден . "

Пожалуйста, убедитесь, что вы не освобождаете этот буфер

0 голосов
/ 06 января 2012

Полагаю, Py_DECREF каким-то образом получает значение NULL.

0 голосов
/ 06 января 2012

Если вы компилируете свой код C с флагом отладки -g (по крайней мере, в GCC), то вы можете запустить свой код на python с помощью отладчика gnu gdb:

$ gdb /path/to/python/compiled/against 
... blah ...
(gdb) run PyObject.py

и вы должны поймать свой segfault.

...