177 lines
5.0 KiB
Python
177 lines
5.0 KiB
Python
import asyncio
|
|
import inspect
|
|
import os
|
|
import re
|
|
import time
|
|
|
|
instance = object()
|
|
|
|
def init():
|
|
global instance
|
|
instance = Debugger()
|
|
|
|
|
|
class Debugger(object):
|
|
"""A socket based debugger """
|
|
|
|
""" a list of tags to debug """
|
|
tags = {}
|
|
knownTags = []
|
|
selectedTags = []
|
|
|
|
# subscribed = {}
|
|
|
|
def __init__(self):
|
|
self.socket_file = '/tmp/._my_debug_socket'
|
|
print('\nStarting the debugger on socket file \'{}\'.\nRequest help with \n echo help | nc -U {}\'\n '.format(
|
|
self.socket_file,
|
|
self.socket_file
|
|
))
|
|
|
|
def cleanup(self):
|
|
if os.path.exists(self.socket_file):
|
|
os.remove(self.socket_file)
|
|
|
|
|
|
def add_known_tags(self, tags):
|
|
if isinstance(tags, str):
|
|
tags = [tags]
|
|
self.tags = set(list(self.tags) + tags)
|
|
|
|
def add_selected_tags(self, tags):
|
|
if isinstance(tags, str):
|
|
tags = [tags]
|
|
self.selectedTags = set(list(self.selectedTags)).union(set(tags))
|
|
|
|
def debug(self, tags, message):
|
|
if isinstance(tags, str):
|
|
tags = [tags]
|
|
self.add_known_tags(tags)
|
|
if len(set(tags) & set(self.selectedTags)):
|
|
print(message)
|
|
# else :
|
|
# print( "skipping message %s vs. %s" % (self.selectedTags, tags ))
|
|
|
|
async def server(self):
|
|
|
|
async def handler(reader, writer):
|
|
data = await reader.read(100)
|
|
if data:
|
|
msg = ""
|
|
req = data.split()
|
|
if not len(req):
|
|
msg = "Error: empty request"
|
|
else:
|
|
cmd = "cmd_" + str(req.pop(0), "utf-8")
|
|
print("Debugger server command: %s" % (cmd))
|
|
if not hasattr(self, cmd):
|
|
msg = "Error: Invalid command '%s'" % (cmd)
|
|
else:
|
|
method = getattr(self, cmd)
|
|
if not callable(method):
|
|
msg = "Error: Called a property"
|
|
else:
|
|
try:
|
|
req = [str(i, 'utf-8') for i in req]
|
|
msg = method(req)
|
|
except Exception as e:
|
|
msg = "Error : %s " % (e)
|
|
print("Response:\n%s" % (msg))
|
|
writer.write(bytes(msg, "utf-8"))
|
|
await writer.drain()
|
|
writer.close()
|
|
|
|
self.cleanup()
|
|
return await asyncio.start_unix_server(handler, path=self.socket_file)
|
|
|
|
def cmd_help(self, params):
|
|
"""
|
|
request general help
|
|
"""
|
|
members = inspect.getmembers(self)
|
|
out = []
|
|
for name, obj in members:
|
|
if not re.match("^cmd_", name):
|
|
continue
|
|
out.append(
|
|
"- " + re.sub("^cmd_(.*)", lambda m: m.group(1), name) + (str(obj.__doc__) if obj.__doc__ else ""))
|
|
|
|
return "\n".join(out) + "\n"
|
|
|
|
def cmd_list_tags(self, params):
|
|
"""
|
|
List available debug tags
|
|
"""
|
|
msg = ""
|
|
if not len(self.tags):
|
|
msg += "No tags yet\n"
|
|
else:
|
|
msg += "Tags:"
|
|
for flag in sorted(self.tags):
|
|
msg += "\n - %s" % (flag)
|
|
msg += "\n"
|
|
return msg
|
|
|
|
def cmd_add_tags(self, params):
|
|
"""
|
|
Add a debug tag
|
|
"""
|
|
msg = ""
|
|
if not len(params):
|
|
msg = "No flag provided"
|
|
else:
|
|
for flag in params:
|
|
if flag in self.selectedTags:
|
|
msg += "Noop: flag '%s' already added" % (flag)
|
|
else:
|
|
self.add_selected_tags([flag])
|
|
msg += "Added flag '%s'" % (flag)
|
|
return msg
|
|
|
|
def cmd_del_tags(self, params):
|
|
"""
|
|
Removes a tag
|
|
"""
|
|
msg = ""
|
|
if not len(params):
|
|
msg = "No flag provided"
|
|
else:
|
|
for flag in params:
|
|
if flag not in self.selectedTags:
|
|
msg += "Noop: flag '%s' not added" % (flag)
|
|
else:
|
|
self.selectedTags.remove(flag)
|
|
msg += "Removed flag '%s'" % (flag)
|
|
return msg
|
|
|
|
# def cmd_list_objs(self, params):
|
|
# """
|
|
# List available objects
|
|
# """
|
|
# if not len(self.subscribed ):
|
|
# msg += "No subscribed object yet\n"
|
|
# else:
|
|
# msg += "Subscribed objects:"
|
|
# for i, (oid, obj) in enumerate(self.subscribed.items()) :
|
|
# msg+="\n - %s\t%s" % (oid,obj)
|
|
#
|
|
# return "\n".msg
|
|
#
|
|
#
|
|
# def cmd_add_objs(self, params):
|
|
# """
|
|
# Debug a precise object
|
|
# """
|
|
# oid = params[0]
|
|
# msg = "Unknown error"
|
|
# if not self.subscribed[oid]:
|
|
#
|
|
# msg = "No such object"
|
|
# else :
|
|
# obj = self.subscribed[oid]
|
|
# msg = obj.debugSelf()
|
|
# return msg
|
|
|
|
# def subscribe( self, oid, obj ):
|
|
# self.subscribed[ oid ] = obj
|