我有一个python2.7守护进程,它使用http://www.jejik.com/files/examples/daemon.py的一个模块
这个过程很重,内存使用量约为40 GB,子线程为9个。服务器使用RHEL6.3和192 GB RAM和足够的CPU功率。
在开始这个过程后,它会持续大约3-7个小时,但是后来被某个人杀死了,可能是内核。但我在dmesg或内核日志(我已经手动激活)中找不到任何提示,什么也找不到。当不以守护进程启动时,我刚刚收到终端中的消息:“已被杀死”。
已采取以下预防措施:
这个问题在采取这些预防措施之前就已经存在了,所以他们不对杀人负责。
我还有一种机制来捕获所有异常,STDERR,STDOUT,并将所有事情记录到一个旋转的日志文件中。但就在这个过程结束之前,没有什么有趣的事情。
流程中使用的模块包括: oracle_cx、ibm_db、suds、wsgi_utils。但是当发生错误时,所有这些人都会写日志。
有人知道怎么追查谋杀案吗?谁和为什么?
提前谢谢你
发布于 2013-05-06 09:18:49
若要查看进程终止时登录的是谁,请使用命令last。
如果当时没有人登录,这个过程就会被一些信号所扼杀。
因为这是Python,所以找出杀死进程的最简单方法是为所有信号编写一个信号处理程序并记录它们。见这里如何编写信号处理程序。见这个问题是如何把他们全部抓起来的。
如果您得到一个核心转储,附加一个具有足够空间的外部硬盘。或者使用ulimit将内核的大小限制在1GB以内;这可能足以查看其崩溃的位置。
或者,使用像gdb这样的调试器启动进程;当“核心转储”信号被发送到进程时,它将确保得到一个提示。
发布于 2013-05-07 09:42:04
我想我找到了根本原因,这可能是Python2.7中的一个bug,在捕捉到所有可捕捉的信号并忽略它们之后,我可以跟踪更多的错误消息并得到socket.error的提示。问题是,这样的错误将首先触发SIGTERM (trus试图杀死进程),然后写入STDERR。我捕获所有STDOUT和STDERR的机制可以记录消息,因为主进程已经被杀死。无论如何,这是守护进程中的一个问题。这些是进程终止前日志中的最后一行。
2013-05-07 11:05:53,194 - STDERR - ERROR - Traceback (most recent call last):
2013-05-07 11:05:53,304 - STDERR - ERROR - File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 582, in process_request_thread
2013-05-07 11:05:53,415 - STDERR - ERROR - self.finish_request(request, client_address)
2013-05-07 11:05:53,489 - STDERR - ERROR - File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 323, in finish_request
2013-05-07 11:05:53,587 - STDERR - ERROR - self.RequestHandlerClass(request, client_address, self)
2013-05-07 11:05:53,684 - STDERR - ERROR - File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 640, in __init__
2013-05-07 11:05:53,835 - STDERR - ERROR - self.finish()
2013-05-07 11:05:53,887 - STDERR - ERROR - File "/var/lib/netcam_epd/lib/python2.7/SocketServer.py", line 693, in finish
2013-05-07 11:05:54,084 - STDERR - ERROR - self.wfile.flush()
2013-05-07 11:05:54,182 - STDERR - ERROR - File "/var/lib/netcam_epd/lib/python2.7/socket.py", line 303, in flush
2013-05-07 11:05:54,326 - STDERR - ERROR - self._sock.sendall(view[write_offset:write_offset+buffer_size])
2013-05-07 11:05:54,387 - STDERR - ERROR - error: [Errno 32] Broken pipe很明显,这是由于试图写入不可写的套接字造成的。我认为库应该使用接近的返回值来更好地处理这个问题,而不仅仅是抛出错误/异常,因为套接字可以在正常运行的任何时候关闭。
我会核实这是否真的是根洞。
https://stackoverflow.com/questions/16395082
复制相似问题