Недоступная память при разборе двух байт из кортежа - PullRequest
0 голосов
/ 13 марта 2019

Я создал маленькую функцию-оболочку C, которая требует двух байтовых переменных:

static PyObject * wrapperfunction(PyObject * self, PyObject * args) {
    const unsigned char * data;
    Py_ssize_t datalen;
    const unsigned char * otherdata;
    Py_ssize_t otherlen;

    if (!PyArg_ParseTuple(args, "y#y#", &data, &datalen, &otherdata, &otherlen))
        return NULL;

    some_function(data, datalen, otherdata, otherlen);
}

Но я заметил, что в 64-битной Linux-системе эта функция в некоторых случаях выходила из строя (я не мог сузить их до особого случая), и внутри some_function произошел сбой, так как data был нечитаемым адресом. обычно этот адрес будет 0x7fff00000001

Я бы не понял, почему это происходит, но изменил код, чтобы использовать вместо него Py_buffer - который отлично работает:

static PyObject * wrapperfunction(PyObject * self, PyObject * args) {
    Py_buffer data;
    Py_buffer otherdata;

    if (!PyArg_ParseTuple(args, "y*y*", &data, &otherdata))
        return NULL;

    some_function((unsigned char *)data.buf, data.len, (unsigned char *)otherdata, otherdata.len);
}

Насколько я могу судить, в документации на python сказано, что y* является предпочтительным методом, но не то, что y# будет работать только один раз. Есть ли причина, по которой метод, использующий y#, не работает?

Я использую Python 3.5.3 на debian stretch amd64. На компьютере с Windows (python 3.6.4 / x64) один и тот же код никогда не вызывал ошибку segfault.

...