Хорошо известно, что pysha3 несовместим с pypy, и, поскольку он не поддерживается в течение 3 лет, я должен изменить его сам.
Конечно, правильным способом было бы выполнить полное переписывание в чистом видеPython-код (который также приведет к более быстрой реализации по сравнению с текущим), но мне не хватает необходимых знаний как в криптографии, так и в фоновой математике, чтобы сделать это, и программа, использующая его, очень интенсивно использует список (для которого требуется python3 безgil для многопоточности или python3 с jit).
Единственная точка отказа сводится к этой функции , которая должна вызываться кодом C:
static PyObject*
_Py_strhex(const char* argbuf, const Py_ssize_t arglen)
{
static const char *hexdigits = "0123456789abcdef";
PyObject *retval;
#if PY_MAJOR_VERSION >= 3
Py_UCS1 *retbuf;
#else
char *retbuf;
#endif
Py_ssize_t i, j;
assert(arglen >= 0);
if (arglen > PY_SSIZE_T_MAX / 2)
return PyErr_NoMemory();
#if PY_MAJOR_VERSION >= 3
retval = PyUnicode_New(arglen * 2, 127);
if (!retval)
return NULL;
retbuf = PyUnicode_1BYTE_DATA(retval);
#else
retval = PyString_FromStringAndSize(NULL, arglen * 2);
if (!retval)
return NULL;
retbuf = PyString_AsString(retval);
if (!retbuf) {
Py_DECREF(retval);
return NULL;
}
#endif
/* make hex version of string, taken from shamodule.c */
for (i=j=0; i < arglen; i++) {
unsigned char c;
c = (argbuf[i] >> 4) & 0xf;
retbuf[j++] = hexdigits[c];
c = argbuf[i] & 0xf;
retbuf[j++] = hexdigits[c];
}
return retval;
}
Уровень совместимости для Cython составляет 3,2 для Pypy, и PyUnicode_New
был введен в Python3.3.
Я попытался исправить это путем замены всего файла следующим кодом Cython:
cdef Py_strhex(const char* argbuf, const Py_ssize_t arglen):
return (argbuf[:arglen]).hex()
но, похоже, это вызывает ошибку сегментации, включая компиляцию и использование официальной реализации Python. И используя официальный двоичный файл PyPy, у меня нет символов отладки для gdb, поэтому я не знаю почему.
(gdb) bt
#0 0x00007ffff564cd00 in pypy_g_text_w__pypy_interpreter_baseobjspace_W_Root () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#1 0x00007ffff5d721a8 in pypy_g_getattr () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#2 0x00007ffff543a8bd in pypy_g_dispatcher_15 () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#3 0x00007ffff5ab909b in pypy_g_wrapper_second_level.star_2_14 () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#4 0x00007fffd7212372 in _Py_strhex.2738 () from /usr/lib64/pypy3.6-v7.2.0-linux64/site-packages/pysha3-1.0.3.dev1-py3.6-linux-x86_64.egg/_pysha3.pypy3-72-x86_64-linux-gnu.so
#5 0x00007fffd7217990 in _sha3_sha3_224_hexdigest_impl.2958 () from /usr/lib64/pypy3.6-v7.2.0-linux64/site-packages/pysha3-1.0.3.dev1-py3.6-linux-x86_64.egg/_pysha3.pypy3-72-x86_64-linux-gnu.so
#6 0x00007ffff5be2170 in pypy_g_generic_cpy_call__StdObjSpaceConst_funcPtr_SomeI_5 () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#7 0x00007ffff54b25cd in pypy_g.call_1 () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#8 0x00007ffff56715b9 in pypy_g_BuiltinCodePassThroughArguments1_funcrun_obj () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#9 0x00007ffff56ffc06 in pypy_g_call_valuestack__AccessDirect_None () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
#10 0x00007ffff5edb29b in pypy_g_CALL_METHOD__AccessDirect_star_1 () from /usr/lib64/pypy3.6-v7.2.0-linux64/bin/libpypy3-c.so
Увеличение глубины стека Linux по умолчанию до 65 МБ не меняет глубину рекурсиигде происходит ошибка по умолчанию, даже если глубина стека превышает 200, похоже, это не связано с переполнением стека.