您的位置:首页 > 运维架构 > Apache

apache PyString_FromString: Assertion `str != ((void *)0)' failed. 错误处理

2014-10-08 17:16 573 查看
最近遇到个奇怪的问题,我将django项目迁到到另一台服务器时,报如下错误:

[Wed Oct 08 15:31:04 2014] [error] [client 10.19.81.48] Premature end of script headers: wsgi.py, referer:

: Objects/stringobject.c:115: PyString_FromString: Assertion `str != ((void *)0)' failed.

[Wed Oct 08 15:31:18 2014] [error] [client 10.19.81.48] Premature end of script headers: wsgi.py, referer:

google了一番,刚开始看到Premature end of script headers以为是脚本的Line Endings有问题,但是确认是unix的格式

所以果断转移方向,有可能是系统的问题,于是找到下面这篇文章,终于解决了我的问题:


mod_wsgi线程崩溃

$ tail -f error_log
httpd: Objects/stringobject.c:105: PyString_FromString: Assertion `str != ((void *)0)' failed.
[Sun Jul 26 00:48:53 2009] [notice] child pid 1145 exit signal Aborted (6)
httpd: Objects/stringobject.c:105: PyString_FromString: Assertion `str != ((void *)0)' failed.
[Sun Jul 26 00:48:54 2009] [notice] child pid 1146 exit signal Aborted (6)


检查error.log文件

httpd: Objects/stringobject.c:105: PyString_FromString: Assertion `str != ((void *)0)' failed.
[Fri Mar 20 20:39:03 2009] [notice] child pid 8734 exit signal Aborted (6)

由此可得知mod_wsgi线程崩溃掉了,Google一下,在这里得到一些资料,看来wsgi应用在Apache下崩溃的不止是Trac,Django也是有可能的。

这是由于Apache与Python的expat库版本不匹配导致。

Apache expat版本:

httpd-2.2.8/lib $ strings libexpat.so.0.1.0 | grep expat_
expat_1.95.2

Python expat版本:

/opt/httpd-2.2.8/lib $ python
Python 2.4.3 (#1, May 24 2008, 13:47:28)
[GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyexpat
>>> pyexpat.EXPAT_VERSION
'expat_2.0.1'

找到原因后就好办了,但是作者只提了一句下载expat 2.0.1安装,却没说如何安装到Apache,Apache的configure本身并没有with-expat参数,只有 apache_src/srclib/apr-util/configure有这个参数却不知如何关联,无奈之下另找方案。

检查httpd依赖的库:

/opt/httpd-2.2.8/bin $ ldd httpd
linux-gate.so.1 =>  (0x002e6000)
libm.so.6 => /lib/libm.so.6 (0x00cd8000)
libaprutil-1.so.0 => /opt/httpd-2.2.8/lib/libaprutil-1.so.0 (0x00c1e000)
libexpat.so.0 => /opt/httpd-2.2.8/lib/libexpat.so.0 (0x00925000)
libapr-1.so.0 => /opt/httpd-2.2.8/lib/libapr-1.so.0 (0x003df000)
libuuid.so.1 => /lib/libuuid.so.1 (0x00110000)
librt.so.1 => /lib/librt.so.1 (0x00d91000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x0023d000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00d01000)
libdl.so.2 => /lib/libdl.so.2 (0x00cd2000)
libc.so.6 => /lib/libc.so.6 (0x00402000)
/lib/ld-linux.so.2 (0x00b6f000)

由此可知Apache使用的是/opt/httpd-2.2.8/lib/libexpat.so.0,而这个文件是一个软链接,尝试将其删除,重新指到2.0.1:

/opt/httpd-2.2.8/lib $ ln -s /opt/expat-2.0.1/lib/libexpat.so.1.5.2 libexpat.so.0

重新启动Apache, 测试成功!


注意这里的重启是先stop后再start,而不是restart,restart貌似不起作用

expat-2.0.1.tar.gz

这个是源文件,需要编译一下,见下面的教程

关于expat库

1、expat库简介

refer to wiki:

To use the Expat library, programs first register handler functions with Expat. When Expat parses an XML document, it calls the registered handlers as it finds relevant tokens in the input stream. These tokens and their associated
handler calls are called events. Typically, programs register handler functions for XML element start or stop events and character events. Expat provides for more sophisticated event handling such as XML Namespace declarations, processing instructions and
DTD events.

Expat is parsing events resemble the events defined in the Simple API for XML (SAX), but Expat is not a SAX-compliant parser. Projects incorporating the Expat library often build SAX and possibly DOM parsers on top of Expat. While Expat is mainly a stream-based
(push) parser, it supports stopping and restarting parsing at arbitrary times, thus making the implementation of a pull parser relatively easy as well.

为了使用Expat库,程序首先在Expart中住一个处理器函数(handler functions) 。当Expat解析XML文档时,发现输入流中有相关的令牌会调用已经注册的处理器(handlers) ,这些令牌(tokens)和其先关的处理器(handler)被称作事件。通常情况下, 程序会为XML元素中的开始事件、停止事件、字符事件(character events)注册处理函数。Expat提供了 更多复杂事件处理,例如XML命名空间声明,处理指令和DTD事件。

Expat是定义在SAX中的解析事件或类似事件。但是它不是一个严格的服从SAX的解析器。Expat是主要基于流的解析器(推送) ,它支持在任意时间停止和重新启动的解析器,从而使相关的拉动型解析器(pull parser )实现很容易。

(第一次翻译,翻译的不好啊~~~)

说白了 ,Expat是一个面向流的xml解析器。

2、expat库的交叉编译

expat-2.0.1.tar.gz

./configure --host=arm-none-linux-gnueabi --prefix=/root/home

make && make install

参考:http://askyyy.blog.163.com/blog/static/123457599200971802737/ http://blog.csdn.net/flyeagle022/article/details/7789098
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐