debug.py 2.68 KB
Newer Older
1
"""Example of script starting a debugger on RTMIN+3 signal
2 3 4 5 6 7 8 9 10 11

The pdb is launched in a separate thread in order not to trigger timeouts.
The prompt is accessible through network in case that the process is daemonized:
  $ socat READLINE TCP:127.0.0.1:54930
  > neo/debug.py(63)pdb()
  -> app # this is Application instance
  (Pdb) app
  <neo.master.app.Application object at 0x1fc9750>
"""

12 13
IF = 'pdb'
if IF == 'pdb':
14
    import socket, sys, threading
15 16
    from neo.lib.debug import getPdb
    #from pdb import Pdb as getPdb
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

    class Socket(object):

        def __init__(self, socket):
            self._socket = socket
            self._buf = ''

        def write(self, data):
            self._socket.send(data)

        def readline(self):
            recv = self._socket.recv
            data = self._buf
            while True:
                i = 1 + data.find('\n')
                if i:
                    self._buf = data[i:]
                    return data[:i]
                d = recv(4096)
                data += d
                if not d:
                    self._buf = ''
                    return data

        def flush(self):
            pass

        def closed(self):
            self._socket.setblocking(0)
            try:
                self._socket.recv(0)
                return True
            except socket.error, (err, _):
                if err != errno.EAGAIN:
                    raise
                self._socket.setblocking(1)
            return False

55
    def pdb(app_set):
56 57 58 59 60 61 62 63
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            s.bind(('127.0.0.1', 0))
            s.listen(0)
            print 'Listening to %u' % s.getsockname()[1]
            _socket = Socket(s.accept()[0])
        finally:
            s.close()
64 65 66 67
        try:
            app, = app_set
        except ValueError:
            app = None
68
        getPdb(stdin=_socket, stdout=_socket).set_trace()
69
        app # this is Application instance (see 'app_set' if there are several)
70 71

    try:
72 73 74 75 76 77 78 79 80 81 82 83 84
        app_set = sys.modules['neo.client.app'].app_set
    except KeyError:
        f = sys._getframe(3)
        try:
            while f.f_code.co_name != 'run' or \
                  f.f_locals.get('self').__class__.__name__ != 'Application':
                f = f.f_back
            app_set = f.f_locals['self'],
        except AttributeError:
            app_set = ()
        finally:
            del f
    threading.Thread(target=pdb, args=(app_set,)).start()
85 86 87 88 89 90 91 92

elif IF == 'frames':
    import sys, traceback
    write = sys.stderr.write
    for thread_id, frame in sys._current_frames().iteritems():
        write("Thread %s:\n" % thread_id)
        traceback.print_stack(frame)
    write("End of dump\n")