Python uWSGI应用程序中的分段错误

时间:2015-01-04 18:56:19

标签: python numpy segmentation-fault uwsgi blas

我对使用uwsgi和python脚本相当新,所以希望这是一个天真的错误。

我有两个不同的Web应用程序与单独但相关的python库交互,我们称之为lib1.py和lib2.py

如果我从命令行使用这些库,我没有错误。

我创建了两个python文件,app1.py和app2.py,每个文件都附加到不同的uwsgi套接字。这些文件的基本框架是:

import lib1.py

#load objects into memory
MyObject = lib1.MyClass(init_params)

application(environ, start_response):
    status = '200 OK'

    output = MyObject.processRequest()

    response_headers = [('Content-type', 'text/html'),
                        ('Content-Length', str(len(output)))]

    start_response(status, response_headers)

    return [output]

相同的app2.py导入lib2 ...

App1效果很好,我设置它没有问题。当MyObject初始化时,它会加载数十个大的(100000多行,~100列)numpy数组,并将它们保存在内存中,以便应用程序函数在接收来自Web服务器的请求时进行计算。

App2尚未运行... lib2.py导入lib1.py,因为它需要在大型numpy数组上进行类似的计算,作为其工作的一部分。奇怪的是它是一个抛出SEGFAULT的lib1.py函数。起初,我认为这可能是一些奇怪的双重导入的症状,这就是为什么我在第一次看到这种情况时将uwsgi分成两个独立的套接字和应用程序,如上所述。更奇怪的是,lib2只使用了1个大的numpy数组,并且它比lib1 numpy数组中的最大数组小。通过在我的代码中放置一些print语句并查看日志,我能够找到发生段错误的确切行:

inner_product_array = np.dot(self.coordinates, vector.T)

self.coordinates是2d MxN数组,vector.T是Nx1列向量。如果我限制self.coordinates数组,那么SEGFAULT就会消失:self.coordinates[:500,:]

但只要切片大于500,就会发生SEGFAULT,这远远超过我需要的150000。同样,当self.coordinate可以达到500000 x 200

时,这个计算在lib1中没有问题

我觉得我已经尽可能地确保没有模块/库被双重导入。其他numpy函数表现良好,并且,当从命令行使用时,lib2再次适用于大型数组。

唯一需要提及的另一个奇怪的症状是,之前,当我有一个app.py文件处理我所有的uwsgi python代码并使用PATH_INFO环境变量处理不同应用程序的请求时(包括除了这两个之外的其他应用程序),所有的应用程序一起工作得很好,直到我添加了lib2。一旦添加了lib2,lib1就会破坏并开始提供SEGFAULTS。其他应用程序(没有依赖于lib1或lib2)都很好。

以下是日志中的错误:

*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 33866, cores: 1)
!!! uWSGI process 33866 got Segmentation Fault !!!
*** backtrace of 33866 ***
0   uwsgi                               0x00000001062f9420 uwsgi_backtrace + 48
1   uwsgi                               0x00000001062f9963 uwsgi_segfault + 51
2   libsystem_platform.dylib            0x00007fff9190ef1a _sigtramp + 26
3   multiarray.so                       0x0000000106fd4efe array_dealloc + 158
4   libBLAS.dylib                       0x00007fff908911ff rowMajorNoTranspose + 689
5   libBLAS.dylib                       0x00007fff9088f2c9 cblas_dgemv + 783
6   _dotblas.so                         0x00000001072e0129 dotblas_matrixproduct + 5513
7   libpython2.7.dylib                  0x00000001067d27c9 PyEval_EvalFrameEx + 14387
8   libpython2.7.dylib                  0x00000001067ced62 PyEval_EvalCodeEx + 1413
9   libpython2.7.dylib                  0x00000001067d557d _PyEval_SliceIndex + 757
10  libpython2.7.dylib                  0x00000001067d23e3 PyEval_EvalFrameEx + 13389
11  libpython2.7.dylib                  0x00000001067ced62 PyEval_EvalCodeEx + 1413
12  libpython2.7.dylib                  0x00000001067d557d _PyEval_SliceIndex + 757
13  libpython2.7.dylib                  0x00000001067d23e3 PyEval_EvalFrameEx + 13389
14  libpython2.7.dylib                  0x00000001067ced62 PyEval_EvalCodeEx + 1413
15  libpython2.7.dylib                  0x00000001067d557d _PyEval_SliceIndex + 757
16  libpython2.7.dylib                  0x00000001067d23e3 PyEval_EvalFrameEx + 13389
17  libpython2.7.dylib                  0x00000001067ced62 PyEval_EvalCodeEx + 1413
18  libpython2.7.dylib                  0x00000001067d557d _PyEval_SliceIndex + 757
19  libpython2.7.dylib                  0x00000001067d23e3 PyEval_EvalFrameEx + 13389
20  libpython2.7.dylib                  0x00000001067ced62 PyEval_EvalCodeEx + 1413
21  libpython2.7.dylib                  0x000000010677330a PyFunction_SetClosure + 826
22  libpython2.7.dylib                  0x00000001067552ac PyObject_Call + 99
23  libpython2.7.dylib                  0x00000001067d4d6b PyEval_CallObjectWithKeywords + 93
24  uwsgi                               0x0000000106314097 python_call + 23
25  uwsgi                               0x000000010631620f uwsgi_request_wsgi + 879
26  uwsgi                               0x00000001062ab530 wsgi_req_recv + 288
27  uwsgi                               0x00000001062f7205 simple_loop_run + 229
28  uwsgi                               0x00000001062fe577 uwsgi_ignition + 439
29  uwsgi                               0x00000001062fe363 uwsgi_worker_run + 835
30  uwsgi                               0x00000001062fbe7a uwsgi_run + 442
31  uwsgi                               0x00000001062f9b0e main + 14
32  libdyld.dylib                       0x00007fff854425c9 start + 1
*** end of backtrace ***

这是我用于app2的uwsgi的xml配置:

<uwsgi>
    <socket>127.0.0.1:3033</socket>
    <chdir>/abs/path/to/site_folder/wsgi</chdir>
    <wsgi-file>/abs/path/to/site_folder/wsgi/app2.py</wsgi-file>
    <logto>/abs/path/to/logdir/app2.log</logto>
    <pidfile>app2.pid</pidfile>
    <enable-threads></enable-threads>
    <daemonize2></daemonize2>
</uwsgi>

更新

我在Amazon Linux EC-2服务器上创建了一个相同的设置,一切正常,但没有错误。我遇到问题的本地机器是OSX。我仍然感到困惑,为什么只有在uWSGI框架中才会发生这种情况,并希望能够在本地开发和测试,但它似乎更像是一个安装问题(OpenBLAS?)而不是其他任何问题。任何想法为什么uWSGI会在相同的数据和相同的函数调用中触发这种错误行为,作为无错误的命令行脚本和单独的无错误的uWSGI应用程序?

0 个答案:

没有答案