mod_wsgi+c类型导致分段错误

2024-06-17 13:24:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python函数,它使用ctypes调用一些c代码

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中的segfault,它会说

#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


更新:

我将print语句添加到python和c中以进行打印 sizeof(c_void_p)、out.ctypes.data和值

在伊皮顿

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

在阿帕奇

[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\u void\u 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中无效


Tags: 代码testimportwsgidataapachenpout