Ошибка сегментации в приложении Python uWSGI

Я довольно новичок в использовании uwsgi со скриптами Python, так что, надеюсь, это наивная ошибка.

У меня есть два разных веб-приложения, которые взаимодействуют с отдельными, но связанными библиотеками 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 прекрасно работает, и у меня не было проблем с его настройкой. Он загружает десятки больших (100000+ строк, ~100 столбцов) массивов при инициализации MyObject и сохраняет их в памяти для функции приложения, чтобы рассчитать, когда он получает запросы от веб-сервера.

App2 еще не работает... lib2.py импортирует lib1.py, так как ему необходимо выполнять аналогичные вычисления для большого массива с массивами в рамках своей работы. Странно то, что это одна из функций lib1.py, которая выдает SEGFAULT. Сначала я подумал, что, может быть, это был какой-то странный случай двойного импорта, поэтому я разделил uwsgi на два отдельных сокета и приложения, как описано выше, когда впервые увидел это. Более странно то, что lib2 использует только 1 большой массив numpy, и он меньше, чем самый большой из массивов lib1. Размещая ряд print Заявления в мой код и просматривая журналы, я смог найти точную строку, где происходит segfault:

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

self.coordinates - это двумерный массив MxN, а vector.T - вектор-столбец Nx1. SEGFAULT исчезнет, ​​если я ограничу массив self.coordinates следующим образом: self.coordinates[:500,:]

Но SEGFAULT происходит всякий раз, когда ломтик становится намного больше, чем 500, что далеко не так, как мне нужно 150000. Опять же, этот расчет не вызывает проблем в lib1, когда self.coordinates может получить до 500000 x 200

Я чувствую, что выполнил как можно больше, чтобы убедиться, что ни один модуль / библиотека не был дважды импортирован. Другие функции numpy ведут себя нормально, и, опять же, lib2 прекрасно работает с большими массивами при использовании из командной строки.

Единственный другой странный признак, который стоит упомянуть, это то, что раньше, когда у меня был один файл app.py, который обрабатывал весь мой код Python uwsgi и обрабатывал запросы для разных приложений, используя переменную среды 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 ***

И вот конфиг xml для uwsgi, который я использую для app2:

<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 ответов

Другие вопросы по тегам