我有一个C扩展模块,我正在使用CentOS构建和使用 distutils。
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 "\250",
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 "\250",
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
答案 0 :(得分:0)
所以,终于找到了这个bug;解析参数时出现编码错误,对于具有空值的python缓冲区,我将格式说明符设置为&#34;#i&#34;并从Python代码传递一个整数来表示字符串的长度;无论正确的说明符是&#34;是#&#34; ;并且你不需要从python中明确传入长度;但是在C中你需要为PyArg_ParseTuple提供一个整数的地址来解码长度。
所以基本上我的代码我写入了一个我没有分配的内存,并且在一个操作系统上没有发生任何事情,因为纯粹的运气或内存由一些先前的缓冲区和RAM可用性分配的方式,但它在Ubuntu上有问题正确。
课程 - 当你接触C等进行低级编程时,要特别注意内存分配和释放。如果错过了总是很头疼