gpt4 book ai didi

Python C API - 使用比较函数导致 'Segmentation fault'

转载 作者:太空宇宙 更新时间:2023-11-04 01:11:51 27 4
gpt4 key购买 nike

我目前正在尝试学习用 C 编写 Python 扩展,一切似乎都很顺利。但是,当我尝试使用比较函数时,它们都会导致 Segmentaion 错误。例如:

#include "Python.h"

int test(void) {
int result;
printf("Before compare...\n");
result = PyObject_Compare(PyInt_FromLong(1), PyInt_FromLong(3));
printf("result= %d\n", result);
return 0;
}

从 Python(我使用 ctypes)执行 test() 给出以下输出:

Before compare...
Segmentation fault

这发生在我身上的其他比较功能,如:PyObject_cmp...等等

感谢任何帮助,谢谢。

更多信息:

我首先将文件 (test.c) 编译到一个共享库中:

$> python-config --cflags
-I/usr/include/python2.7 -I/usr/include/python2.7 -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
$> python-config --ldflags
-L/usr/lib/python2.7/config -lpthread -ldl -lutil -lm -lpython2.7 -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions

$> gcc -c $(python-config --cflags) ./test.c -o test.o
$> gcc -shared ./test.o $(python-config --ldflags) -o libtest.so

然后我像这样从 Python 启动函数:

import ctypes
testlib = ctypes.CDLL('./libtest.so')

testlib.test()

编辑:

使用 Viktor 给出的测试

$> gcc -o dlltest test.c -ldl
$> gdb dlltest
(gdb) run
Starting program: dlltest
[Thread debugging using libthread_db enabled]
Cannot find new threads: generic error
(gdb)

所以我这样做了:

$> LD_PRELOAD=libpthread-2.13.so gdb dlltest
(gdb) run
Starting program: dlltest
[Thread debugging using libthread_db enabled]
Before compare...
result= -1
[Inferior 1 (process 3274) exited normally]
(gdb)

编辑2:

>$ gdb --args python frompython.py
(gdb) run
Starting program: /usr/bin/python frompython.py
[Thread debugging using libthread_db enabled]
Before compare...

Program received signal SIGSEGV, Segmentation fault.
0x080a855b in PyObject_Compare ()
(gdb) backtrace
#0 0x080a855b in PyObject_Compare ()
#1 0x005225d8 in test () at ./testmod.c:29
#2 0x005181ca in ffi_call_SYSV ()
from /usr/lib/python2.7/lib-dynload/_ctypes.so
#3 0x00517eff in ffi_call () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#4 0x00510312 in _ctypes_callproc ()
from /usr/lib/python2.7/lib-dynload/_ctypes.so
#5 0x0050788d in ?? () from /usr/lib/python2.7/lib-dynload/_ctypes.so
#6 0x0805dc31 in PyObject_Call ()
#7 0x080f81c1 in PyEval_EvalFrameEx ()
#8 0x080fd804 in PyEval_EvalCodeEx ()
#9 0x080fe177 in PyEval_EvalCode ()
#10 0x0811acd0 in ?? ()
#11 0x0811b8e9 in PyRun_FileExFlags ()
#12 0x0811c4cc in PyRun_SimpleFileExFlags ()
#13 0x0812c7c6 in Py_Main ()
#14 0x0805da0b in main ()
(gdb)

最佳答案

“test()”函数中没有 Python 解释器的初始化(没有 Py_Initialize 调用)。

PyInt_FromLong() 返回指向内部数组的指针,在您的情况下该指针未初始化。所以你得到一些无效的指针并将它传递给 Py_Compare() 函数会使解释器崩溃。

有关初始化的详细信息,请参见此处: http://docs.python.org/c-api/init.html#initializing-and-finalizing-the-interpreter

至少尝试在 test() 函数的开头添加“Py_Initialize()”调用。

编辑:

有趣的是,如果您使用此程序从 C 运行 libtest.test,那么来自 GDB 的堆栈跟踪是什么:

#include <dlfcn.h>

typedef int (*fcn)();

int main()
{
void* dll = dlopen("libtest.so", RTLD_LAZY);

/* dlerror checks here */

fcn Test = (fcn)dlsym(dll, "test");

Test();

dclose(dll);

return 0;
}

编辑2:

  1. 编译测试(gcc -o dlltest test.c -ldl)

  2. 运行“gdb dlltest”

  3. 在 gdb 提示符下输入命令“run”

  4. 看是否崩溃

  5. 如果是,请在 gdb 的提示符中键入回溯。

编辑3:

目前尚不清楚崩溃的位置。尝试添加“fflush(stdout);”在每次 printf() 调用后确保打印错误。

如果“result= -1”出现在基于 python 的应用程序中,则错误出在 ctypes 中,而不是在 libtest.so 中。

关于Python C API - 使用比较函数导致 'Segmentation fault',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10875176/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com