简体   繁体   English

用c和mod_wsgi用apache扩展python / django

[英]Extend python/django with c and mod_wsgi with apache

I have a question about extending python with c code and mod_wsgi. 我有一个关于使用c代码和mod_wsgi扩展python的问题。

I have a django app in an apache server that query a postgresql database to generate reports. 我在apache服务器中有一个django应用程序,它查询postgresql数据库以生成报告。 In some reports the system creates a csv file with the results. 在某些报告中,系统会创建包含结果的csv文件。 To create this csv file, some times the system must process more than two hundred thousands registers with python, that is obviously very slow. 要创建这个csv文件,有时系统必须使用python处理超过二十万个寄存器,这显然非常慢。 To accelerate this, we programed ac module that do this work, and that improves the speed many times. 为了加速这一点,我们编写了执行此工作的交流模块,并且多次提高了速度。 We have tried with ctypes and create a python module with c, both works fine in the runserver but crashes when executed with apache and mod_wsgi. 我们尝试使用ctypes并使用c创建一个python模块,两者在runserver中工作正常但在使用apache和mod_wsgi执行时崩溃。

The error in httpd-error.log is: httpd-error.log中的错误是:

[Wed Jul 27 02:33:52 2011] [notice] child pid 44657 exit signal Segmentation fault (11) [Wed Jul 27 02:33:52 2011] [通知]儿童pid 44657退出信号分段故障(11)

¿Any suggestion? ¿有什么建议吗?

The code is: 代码是:

# Creates the HttpResponse object with the appropriate CSV header.
response = HttpResponse(mimetype='application/x-zip-compressed')
response['Content-Disposition'] = \
    'attachment; filename=' + filename + '.zip'

p0 = 'descarga_' + str(datetime.today()) + '.csv'

p1 = settings.DATABASES['default']['NAME']
p2 = settings.DATABASES['default']['USER']

#lib.generar(string_at(p0),p1,p2,string_at(str(init)),string_at(str(end)),string_at(str(provider)))

import generador
generador.generar(p0,p1,p2,str(init),str(end),str(provider))

It crashes after we call generador.generar() that is an external module developed in C 在我们调用generador.generar()之后崩溃了,这是一个用C开发的外部模块

I have also tried with GDb as @GrahamDumpleton suggets and this is the output, not very useful :( 我也试过GDb作为@GrahamDumpleton suggets,这是输出,不是很有用:(

The debugger starts and when i clic the link that executes that calls the c module it falls agin in segmentation fault 调试器启动,当我确定执行调用c模块的链接时,它会在分段错误中失败

(gdb) run -X
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/local/sbin/httpd -X
[New LWP 101064]
[New Thread 28501140 (LWP 101064)]


Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 28501140 (LWP 101064)]
0x2847d423 in fwrite () from /lib/libc.so.7

Well after the Segmetation fault, I tried with the 'where' command in the debugger and this is what it give: 在Segmetation故障之后,我尝试使用调试器中的'where'命令,这就是它给出的内容:

(gdb) where
#0  0x2847d423 in fwrite () from /lib/libc.so.7
#1  0x293f8d09 in generar () from /ruta/al/codigo/generador.so
#2  0x28912caa in PyCFunction_Call () from /usr/local/lib/libpython2.7.so
#3  0x2896e49a in PyEval_EvalFrameEx () from /usr/local/lib/libpython2.7.so
#4  0x2897044b in PyEval_EvalCodeEx () from /usr/local/lib/libpython2.7.so
#5  0x288feafd in PyClassMethod_New () from /usr/local/lib/libpython2.7.so
#6  0x288d622c in PyObject_Call () from /usr/local/lib/libpython2.7.so
#7  0x2896c27a in PyEval_EvalFrameEx () from /usr/local/lib/libpython2.7.so
#8  0x2896fadc in PyEval_EvalFrameEx () from /usr/local/lib/libpython2.7.so
#9  0x2897044b in PyEval_EvalCodeEx () from /usr/local/lib/libpython2.7.so
#10 0x288fea0a in PyClassMethod_New () from /usr/local/lib/libpython2.7.so
#11 0x288d622c in PyObject_Call () from /usr/local/lib/libpython2.7.so
#12 0x288e4fd8 in PyClass_IsSubclass () from /usr/local/lib/libpython2.7.so
#13 0x288d622c in PyObject_Call () from /usr/local/lib/libpython2.7.so
#14 0x2893044c in _PyObject_LookupSpecial () from /usr/local/lib/libpython2.7.so
#15 0x288d622c in PyObject_Call () from /usr/local/lib/libpython2.7.so
#16 0x28968ec4 in PyEval_CallObjectWithKeywords () from /usr/local/lib/libpython2.7.so
#17 0x2889b229 in Adapter_run (self=0x28b4dd58, object=0x28c7d50c) at mod_wsgi.c:3841
#18 0x2889be50 in wsgi_execute_script (r=0x28cb4058) at mod_wsgi.c:6547
#19 0x2889de66 in wsgi_hook_handler (r=0x28cb4058) at mod_wsgi.c:9080
#20 0x08076b19 in ap_run_handler (r=0x28cb4058) at config.c:157
#21 0x08079dee in ap_invoke_handler (r=0x28cb4058) at config.c:376
#22 0x08084eb0 in ap_process_request (r=0x28cb4058) at http_request.c:282
#23 0x0808201b in ap_process_http_connection (c=0x28b201f0) at http_core.c:190
#24 0x0807de09 in ap_run_process_connection (c=0x28b201f0) at connection.c:43
#25 0x08089791 in child_main (child_num_arg=Variable "child_num_arg" is not available.
) at prefork.c:662
#26 0x080899e3 in make_child (s=0x28510f10, slot=0) at prefork.c:707
#27 0x0808a591 in ap_mpm_run (_pconf=0x2850f018, plog=0x2853d018, s=0x28510f10) at  prefork.c:983
#28 0x08064195 in main (argc=676384792, argv=0x28b1e018) at main.c:739

Try setting: 尝试设置:

WSGIApplicationGroup %{GLOBAL}

and forcing the application to run in main Python interpreter. 并强制应用程序在主Python解释器中运行。

Possible your C extension isn't written properly to work with Python sub interpreters. 可能没有正确编写C扩展来使用Python子解释器。

See: 看到:

http://code.google.com/p/modwsgi/wiki/ApplicationIssues#Python_Simplified_GIL_State_API http://code.google.com/p/modwsgi/wiki/ApplicationIssues#Python_Simplified_GIL_State_API

Your code could also just be buggy and using it under mod_wsgi shows out the problem where command line Python does. 您的代码也可能只是错误并且在mod_wsgi下使用它会显示命令行Python的问题。

See: 看到:

http://code.google.com/p/modwsgi/wiki/DebuggingTechniques#Debugging_Crashes_With_GDB http://code.google.com/p/modwsgi/wiki/DebuggingTechniques#Debugging_Crashes_With_GDB

on how to debug where the crash is occurring. 关于如何调试崩溃发生的位置。


UPDATE 1 更新1

When building your extension module, to aid debugging in gdb, ensure that optimisation isn't turned on when compiling extension module and that debug options are. 在构建扩展模块时,为了帮助在gdb中进行调试,请确保在编译扩展模块时没有打开优化,并且调试选项是。

For setup.py driven extension module build, I find it necessary to add: 对于setup.py驱动的扩展模块构建,我发现有必要添加:

from distutils import sysconfig
dummy = sysconfig.get_config_vars('CFLAGS', 'OPT')
config_vars = sysconfig._config_vars
config_vars['CFLAGS'] = config_vars['CFLAGS'].replace(' -Os ', ' ')
config_vars['OPT'] = config_vars['OPT'].replace(' -Os ', ' ')

That way can get rid of -Os options. 这种方式可以摆脱-Os选项。 Whether it is -Os or -O will depend on your Python installation. 无论是-Os还是-O都取决于您的Python安装。

Check then for -g in compiler options when extension module built and add it if need be. 在构建扩展模块时检查编译器选项中的-g,并在需要时添加它。

Once that is done you can then use gdb to actually dump out values of variables, get actual line numbers etc. 完成后,您可以使用gdb实际转储变量值,获取实际行号等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM