mod_wsgi + ctypes导致分段错误

时间:2020-05-10 07:44:48

标签: python c apache ctypes mod-wsgi

我有一个使用ctypes调用某些C代码的python函数

python代码如下:

import numpy as np
from ctypes import *
dll=cdll.LoadLibrary("./test.so")

def callTestFunction():
    out=np.zeros(shape=(10),dtype=np.float32)
    dll.testFunction(out.ctypes.data,10)
    return out

C代码看起来像

void testFunction(float values[], int l){
    for(int i=0;i<l;i++){
      values[i]=1;
    }
}

如果我运行python并调用该函数,则此代码正常工作

但是,当我导入相同的代码并在mod_wsgi内部调用该函数时,会出现分段错误。

我已经设置了WSGIApplicationGroup %{GLOBAL},如果我使用gdb在httpd中捕获了段错误,它会显示

#0  0x00007fffc9fa9bad in testFunction (values=0x563e93b0, l=10) at test.c:63
63                  values[i]=1;
(gdb) print *values@10
Cannot access memory at address 0x563e93b0

我的猜测是Apache正在在我的python代码和c库之间强制某种内存边界吗?有没有人对此有解决方案,或者知道在mod_wsgi中将数组从c返回到python的更好方法?


更新:

我在python和c中添加了打印语句以打印出来 sizeof(c_void_p),out.ctypes.data和值。

在ipython中

out.ctypes.data 0x23dde40
sizeof(c_void_p) 8
values (in c): 23dde40

在Apache中

[Sun May 10 17:37:01.647440 2020] [wsgi:error] [pid 7101] [client 127.0.0.1:60346] out.ctypes.data 0x55555645f7c0
[Sun May 10 17:37:01.647592 2020] [wsgi:error] [pid 7101] [client 127.0.0.1:60346] sizeof(c_void_p) 8
...
(gdb) p values
$1 = (float *) 0x5645f7c0

因此Apache有所不同! 0x55555645f7c0和0x5645f7c0

如果我查看GDB中正确的内存位置,那看起来很有希望!

(gdb) p *0x55555645f7c0@40
$2 = {0 <repeats 40 times>}

结果是我需要将ctypes.data转换为c_void_p!

更正的python代码:

import numpy as np
from ctypes import *
dll=cdll.LoadLibrary("./test.so")

def callTestFunction():
    out=np.zeros(shape=(10),dtype=np.float32)
    dll.testFunction(c_void_p(out.ctypes.data),c_int(10))
    return out

我仍然不知道,为什么这在ipython中有效,但在Apache中无效。

0 个答案:

没有答案
相关问题