import sys
import threading
import time
-import traceback
import werkzeug.serving
import openerp
import openerp.tools.config as config
from openerp.release import nt_service_name
-from openerp.tools.misc import stripped_sys_argv
+from openerp.tools.misc import stripped_sys_argv, dumpstacks
import wsgi_server
# runtime
self.pid = os.getpid()
- def dumpstacks(self):
- """ Signal handler: dump a stack trace for each existing thread."""
- # code from http://stackoverflow.com/questions/132058/getting-stack-trace-from-a-running-python-application#answer-2569696
- # modified for python 2.5 compatibility
- threads_info = dict([(th.ident, {'name': th.name,
- 'uid': getattr(th,'uid','n/a')})
- for th in threading.enumerate()])
- code = []
- for threadId, stack in sys._current_frames().items():
- thread_info = threads_info.get(threadId)
- code.append("\n# Thread: %s (id:%s) (uid:%s)" % \
- (thread_info and thread_info['name'] or 'n/a',
- threadId,
- thread_info and thread_info['uid'] or 'n/a'))
- for filename, lineno, name, line in traceback.extract_stack(stack):
- code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
- if line:
- code.append(" %s" % (line.strip()))
- _logger.info("\n".join(code))
def close_socket(self, sock):
""" Closes a socket instance cleanly
# restart on kill -HUP
openerp.phoenix = True
self.quit_signals_received += 1
- elif sig == signal.SIGQUIT:
- # dump stacks on kill -3
- self.dumpstacks()
def cron_thread(self, number):
while True:
signal.signal(signal.SIGTERM, self.signal_handler)
signal.signal(signal.SIGCHLD, self.signal_handler)
signal.signal(signal.SIGHUP, self.signal_handler)
- signal.signal(signal.SIGQUIT, self.signal_handler)
+ signal.signal(signal.SIGQUIT, dumpstacks)
elif os.name == 'nt':
import win32api
win32api.SetConsoleCtrlHandler(lambda sig: signal_handler(sig, None), 1)
def start(self):
import gevent
from gevent.wsgi import WSGIServer
+
+ if os.name == 'posix':
+ signal.signal(signal.SIGQUIT, dumpstacks)
+
gevent.spawn(self.watch_parent)
self.httpd = WSGIServer((self.interface, self.port), self.app)
_logger.info('Evented Service (longpolling) running on %s:%s', self.interface, self.port)
signal.signal(signal.SIGTERM, self.signal_handler)
signal.signal(signal.SIGHUP, self.signal_handler)
signal.signal(signal.SIGCHLD, self.signal_handler)
- signal.signal(signal.SIGQUIT, self.signal_handler)
signal.signal(signal.SIGTTIN, self.signal_handler)
signal.signal(signal.SIGTTOU, self.signal_handler)
+ signal.signal(signal.SIGQUIT, dumpstacks)
+
# listen to socket
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
from lxml import etree
from which import which
from threading import local
+import traceback
try:
from html2text import html2text
from config import config
from cache import *
+import openerp
# get_encodings, ustr and exception_to_unicode were originally from tools.misc.
# There are moved to loglevels until we refactor tools.
-from openerp.loglevels import get_encodings, ustr, exception_to_unicode
+from openerp.loglevels import get_encodings, ustr, exception_to_unicode # noqa
_logger = logging.getLogger(__name__)
return [x for i, x in enumerate(args) if not strip(args, i)]
+
+def dumpstacks(sig, frame):
+ """ Signal handler: dump a stack trace for each existing thread."""
+ code = []
+
+ def extract_stack(stack):
+ for filename, lineno, name, line in traceback.extract_stack(stack):
+ yield 'File: "%s", line %d, in %s' % (filename, lineno, name)
+ if line:
+ yield " %s" % (line.strip(),)
+
+ # code from http://stackoverflow.com/questions/132058/getting-stack-trace-from-a-running-python-application#answer-2569696
+ # modified for python 2.5 compatibility
+ threads_info = dict([(th.ident, {'name': th.name, 'uid': getattr(th, 'uid', 'n/a')})
+ for th in threading.enumerate()])
+ for threadId, stack in sys._current_frames().items():
+ thread_info = threads_info.get(threadId)
+ code.append("\n# Thread: %s (id:%s) (uid:%s)" %
+ (thread_info and thread_info['name'] or 'n/a',
+ threadId,
+ thread_info and thread_info['uid'] or 'n/a'))
+ for line in extract_stack(stack):
+ code.append(line)
+
+ if openerp.evented:
+ # code from http://stackoverflow.com/questions/12510648/in-gevent-how-can-i-dump-stack-traces-of-all-running-greenlets
+ import gc
+ from greenlet import greenlet
+ for ob in gc.get_objects():
+ if not isinstance(ob, greenlet) or not ob:
+ continue
+ code.append("\n# Greenlet: %r" % (ob,))
+ for line in extract_stack(ob.gr_frame):
+ code.append(line)
+
+ _logger.info("\n".join(code))
+
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: