91 lines
2.8 KiB
Python
91 lines
2.8 KiB
Python
|
#!/usr/bin/env python
|
||
|
import os, re, sys
|
||
|
from subprocess import Popen, PIPE, STDOUT
|
||
|
|
||
|
_can_debug = os.system('which gdb > /dev/null 2>&1') == 0
|
||
|
|
||
|
def can_debug():
|
||
|
global _can_debug
|
||
|
return _can_debug
|
||
|
|
||
|
class Debugger(object):
|
||
|
frame_begin_re = re.compile('^\032\032frame-begin ([^ ]+) ([^ ]+)$')
|
||
|
source_re = re.compile('^\032\032source (.+)$')
|
||
|
def __init__(self, cmd='gdb', args=[]):
|
||
|
self.pipe = None
|
||
|
self.cmd = cmd
|
||
|
self.args = [cmd, '--annotate=3']
|
||
|
self.args.extend(args)
|
||
|
self.start()
|
||
|
|
||
|
#gdb state
|
||
|
self.prompt = None
|
||
|
self.path = None
|
||
|
self.line = None
|
||
|
self.char = None
|
||
|
self.middle = None
|
||
|
self.addr = None
|
||
|
self.breaks = []
|
||
|
|
||
|
def start(self):
|
||
|
assert self.pipe is None
|
||
|
cmd = ' '.join(self.args)
|
||
|
self.pipe = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
|
||
|
def stop(self):
|
||
|
self.pipe.stdin.close()
|
||
|
self.pipe.stdout.close()
|
||
|
self.pipe = None
|
||
|
def restart(self):
|
||
|
self.stop()
|
||
|
self.start()
|
||
|
|
||
|
def _readline(self):
|
||
|
line = self.pipe.stdout.readline()
|
||
|
if line:
|
||
|
return line[:-1]
|
||
|
else:
|
||
|
return None
|
||
|
def _assertline(self, s):
|
||
|
l = self._readline()
|
||
|
assert l == s, repr(l)
|
||
|
|
||
|
def run(self):
|
||
|
while True:
|
||
|
line = self._readline()
|
||
|
if line is None:
|
||
|
break
|
||
|
if line.startswith('\032\032'):
|
||
|
if line == '\032\032starting':
|
||
|
pass
|
||
|
elif line == '\032\032stopped':
|
||
|
pass
|
||
|
elif line.startswith('\032\032frame-begin'):
|
||
|
m = self.frame_begin_re.match(line)
|
||
|
assert m
|
||
|
elif line.startswith('\032\032source'):
|
||
|
m = self.source_re.match(line)
|
||
|
assert m
|
||
|
fields = m.group(1).split(':')
|
||
|
self.path = fields[0]
|
||
|
self.line = int(fields[1])
|
||
|
self.char = int(fields[2])
|
||
|
self.middle = fields[3]
|
||
|
self.addr = fields[4]
|
||
|
print "SOURCE %r, line %d (%s)" % (self.path, self.line, self.addr)
|
||
|
elif line == '\032\032pre-prompt':
|
||
|
self.prompt = self._readline()
|
||
|
print 'PROMPT: %r' % self.prompt
|
||
|
self._assertline('\032\032prompt')
|
||
|
self.pipe.stdin.write(sys.stdin.readline())
|
||
|
self._assertline('')
|
||
|
self._assertline('\032\032post-prompt')
|
||
|
else:
|
||
|
print 'CMD %r' % line
|
||
|
elif line:
|
||
|
print line
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
args = sys.argv[1:]
|
||
|
d = Debugger(args=args)
|
||
|
d.run()
|