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