python - Cython 回调中的段错误

标签 python c sqlite cython

我目前有点卡住了,希望得到一些指导。我有一个包装 sqlite 的小模块,我想允许使用 sqlite 提供的 Hook 执行用户定义的 Python 函数。

这是来自 SQLite 头文件的定义:

cdef extern from "sqlite3.h":
    cdef void *sqlite3_commit_hook(sqlite3*, int(*xFunc)(void*), void*)

这是对应的Cython:

# Reference to user-provided function.
cdef object py_commit_hook = None

# Typedef for callback
ctypedef int(*commit_callback)(void *data)

# Wrapper function that will in turn call the user-provided python callback.
cdef int commit_hook_wrapper(void *data):
    print 'hello'  # Just for debugging.
    py_commit_hook()

# API used to set callback and make sqlite3 library call.
def set_commit_hook(DatabaseHelper db, callback):
    cdef commit_callback f
    global py_commit_hook

    py_commit_hook = callback
    f = commit_hook_wrapper

    sqlite3_commit_hook(db.db, f, <void *>0)

使用 gdb,这里是回溯:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b16e2d in PySys_GetObject () from /usr/lib/libpython2.7.so.1.0
(gdb) bt
#0  0x00007ffff7b16e2d in PySys_GetObject () from /usr/lib/libpython2.7.so.1.0
#1  0x00007ffff567d291 in __Pyx_GetStdout () at pysqlite_ext.c:6121
#2  __Pyx_PrintOne (f=0x0, o=0x7ffff7e39270) at pysqlite_ext.c:6227
#3  __pyx_f_12pysqlite_ext_commit_hook_wrapper (__pyx_v_data=<optimized out>)
    at pysqlite_ext.c:2526
#4  0x00007ffff58ffb36 in ?? () from /usr/lib/libsqlite3.so.0
#5  0x00007ffff590ac5e in ?? () from /usr/lib/libsqlite3.so.0
#6  0x00007ffff590bd4f in sqlite3_step () from /usr/lib/libsqlite3.so.0
#7  0x00007ffff5b6ffb0 in pysqlite_step ()
   from /usr/lib/python2.7/lib-dynload/_sqlite3.so

commit_hook_wrapper 函数中的 print 调用似乎失败了:

(gdb) f 1
#1  0x00007ffff567d291 in __Pyx_GetStdout () at pysqlite_ext.c:6121
6121        PyObject *f = PySys_GetObject((char *)"stdout");
(gdb) l
6116        }
6117    }
6118    
6119    #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION < 3
6120    static PyObject *__Pyx_GetStdout(void) {
6121        PyObject *f = PySys_GetObject((char *)"stdout");
6122        if (!f) {
6123            PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
6124        }
6125        return f;

我完全被难住了!有什么想法可能会出错吗?

我正在动态链接到 libsqlite3,我想知道这是否可能是问题所在。我之前已经按照这些思路实现了回调,但从未遇到过问题,但是这次无论我尝试什么,它似乎都失败了。

最佳答案

在 cython 用户列表中,有人建议我将回调声明为“with gil”。修复它:

cdef int commit_hook_wrapper(void *data) with gil:
    print 'hello'
    py_commit_hook()

关于python - Cython 回调中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32386938/

相关文章:

python - 如何在 Google Cloud Platform 中为 Node 应用程序安装 Python3

python - 定义类时引用 __init__(self) 函数中的 self 约定理解实例对象

sqlite - 是否可以在 sqlite 中定义位列?

c++ - 过滤器(标准)设计模式的正确实现

node.js - 使用 Webpack 捆绑 Sqlite3 导致编译错误

Python imaplib 登录失败

python - 使用 python (scapy?) 丢弃从网络收到的数据包

c - ndisasm手册中提到的二进制文件和可执行文件有什么区别?

c - 将数组传递给 C 中的多个函数

c++ - 位域成员的类型