调用 Python C 扩展模块时出现分段错误

Segmentation fault on calling Python C-extension module

我有一个 C 扩展模块,我正在使用 CentOS 构建和使用它 发行版。

python setup.py build_ext --inplace

然而,当我尝试在 64 位 Ubuntu 机器上使用相同的(当然是再次重新编译以生成 .so 文件)时,我在调用 c 模块时遇到了分段错误.

我正在使用 Python 2.7.

运行 它使用 gdb 我得到以下跟踪

[Switching to Thread 0x7ffff232f700 (LWP 4685)]
convertsimple (freelist=0x7ffff232c840, bufsize=256, msgbuf=0x7ffff232c8d0 "", flags=0, 
p_va=0x54a812, p_format=<synthetic pointer>, arg=0x808430) at Python/getargs.c:716
716 Python/getargs.c: No such file or directory.

请注意,当我编译扩展模块并在那里使用它时,相同的代码在 CentOS 64 位中运行良好。

GDB BKtrace

(gdb) bt
#0  convertsimple (freelist=0x7ffff232b820, bufsize=256, msgbuf=0x7ffff232b8b0 "0", 
    flags=-72515583, p_va=0x7ffff232b920, p_format=<synthetic pointer>, arg=0x808430)
    at Python/getargs.c:716
#1  convertitem (arg=0x808430, p_format=p_format@entry=0x7ffff232b818, 
    p_va=p_va@entry=0x7ffff232ba08, flags=flags@entry=0, 
    levels=levels@entry=0x7ffff232b830, msgbuf=msgbuf@entry=0x7ffff232b8b0 "0", 
    bufsize=bufsize@entry=256, freelist=freelist@entry=0x7ffff232b820)
    at Python/getargs.c:514
#2  0x00000000004c8cb2 in vgetargs1 (args=0x7fffe80475f0, format=0x7ffff2582b70 "is#i", 
    p_va=p_va@entry=0x7ffff232ba08, flags=flags@entry=0) at Python/getargs.c:345
#3  0x00000000004c8fc9 in PyArg_ParseTuple (args=args@entry=0x7fffe80475f0, 
    format=format@entry=0x7ffff2582b70 "is#i") at Python/getargs.c:85
#4  0x00007ffff2581dd3 in cbmsg_parse (self=<optimized out>, args=0x7fffe80475f0)
    at src/cbmsgmodule_v1.c:44
#5  0x00000000004b5816 in call_function (oparg=<optimized out>, pp_stack=0x7ffff232bc30)
    at Python/ceval.c:4021

所以,终于找到了错误;这是解析参数时的编码错误,对于具有空值的 python 缓冲区,我将格式说明符设为 "is#i" 并从 Python 代码中传入一个整数来表示长度的字符串;正确的说明符是 "is#" ;并且您不需要从 python 明确传递长度;但在 C 中,您需要为 PyArg_ParseTuple 提供一个整数的地址以将长度解码为。

所以基本上我的代码写入了一个我没有分配的内存,并且在一个 OS 上没有任何事情发生,因为纯粹的运气或者内存分配的方式是由一些以前的缓冲区和 RAM 可用性,但是它在 Ubuntu 上遇到问题并且正确。

课程 - 当您进行涉及 C 等的低级编程时,要格外小心内存分配和释放。错过总是头疼