Cython回调中的Segfault

时间:2015-09-03 23:26:09

标签: python c sqlite cython

我目前有点陷入困境,希望得到一些指导。我有一个包装sqlite的小模块,我想允许使用sqlite提供的钩子来执行用户定义的Python函数。

以下是SQLite头文件中的定义:

SELECT TOP (sites.Credits) pages.Id, sites.Id
FROM sites s CROSS APPLY
     (SELECT p.*, row_number() over (order by (select null)) as seqnum
      FROM pages p
      WHERE p.Id = p.WebSites_Id
     ) p
where seqnum <= s.credits;

这是相应的Cython:

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

使用gdb,这里是回溯:

# 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)

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 函数print调用似乎失败了:

commit_hook_wrapper

我完全难过!什么想法可能会出错?

我动态链接到libsqlite3,我想知道这可能是问题。我之前已经在这些方面实施了回调,并且从未遇到过问题,但是这次无论我尝试什么,它似乎都会失败。

2 个答案:

答案 0 :(得分:4)

在cython-users列表中,有人建议我使用gil&#34;将我的回调声明为&#34;。修正了它:

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

答案 1 :(得分:0)

有关您的问题的一些信息可以在这里找到: (对不起,我还不能发表评论) http://docs.cython.org/en/latest/src/userguide/external_C_code.html#acquiring-and-releasing-the-gil

  

要在没有GIL的情况下执行的C代码回调的C函数需要先获取GIL才能操作P​​ython对象。