1*061da546Spatrickimport sys 2*061da546Spatrickimport os.path 3*061da546Spatrickimport inspect 4*061da546Spatrick 5*061da546Spatrick 6*061da546Spatrickclass NopLogger: 7*061da546Spatrick 8*061da546Spatrick def __init__(self): 9*061da546Spatrick pass 10*061da546Spatrick 11*061da546Spatrick def write(self, data): 12*061da546Spatrick pass 13*061da546Spatrick 14*061da546Spatrick def flush(self): 15*061da546Spatrick pass 16*061da546Spatrick 17*061da546Spatrick def close(self): 18*061da546Spatrick pass 19*061da546Spatrick 20*061da546Spatrick 21*061da546Spatrickclass StdoutLogger: 22*061da546Spatrick 23*061da546Spatrick def __init__(self): 24*061da546Spatrick pass 25*061da546Spatrick 26*061da546Spatrick def write(self, data): 27*061da546Spatrick print(data) 28*061da546Spatrick 29*061da546Spatrick def flush(self): 30*061da546Spatrick pass 31*061da546Spatrick 32*061da546Spatrick def close(self): 33*061da546Spatrick pass 34*061da546Spatrick 35*061da546Spatrick 36*061da546Spatrickclass FileLogger: 37*061da546Spatrick 38*061da546Spatrick def __init__(self, name): 39*061da546Spatrick self.file = None 40*061da546Spatrick try: 41*061da546Spatrick name = os.path.abspath(name) 42*061da546Spatrick self.file = open(name, 'a') 43*061da546Spatrick except: 44*061da546Spatrick try: 45*061da546Spatrick self.file = open('formatters.log', 'a') 46*061da546Spatrick except: 47*061da546Spatrick pass 48*061da546Spatrick 49*061da546Spatrick def write(self, data): 50*061da546Spatrick if self.file is not None: 51*061da546Spatrick print(data, file=self.file) 52*061da546Spatrick else: 53*061da546Spatrick print(data) 54*061da546Spatrick 55*061da546Spatrick def flush(self): 56*061da546Spatrick if self.file is not None: 57*061da546Spatrick self.file.flush() 58*061da546Spatrick 59*061da546Spatrick def close(self): 60*061da546Spatrick if self.file is not None: 61*061da546Spatrick self.file.close() 62*061da546Spatrick self.file = None 63*061da546Spatrick 64*061da546Spatrick# to enable logging: 65*061da546Spatrick# define lldb.formatters.Logger._lldb_formatters_debug_level to any number greater than 0 66*061da546Spatrick# if you define it to any value greater than 1, the log will be automatically flushed after each write (slower but should make sure most of the stuff makes it to the log even if we crash) 67*061da546Spatrick# if you define it to any value greater than 2, the calling function's details will automatically be logged (even slower, but provides additional details) 68*061da546Spatrick# if you need the log to go to a file instead of on screen, define 69*061da546Spatrick# lldb.formatters.Logger._lldb_formatters_debug_filename to a valid 70*061da546Spatrick# filename 71*061da546Spatrick 72*061da546Spatrick 73*061da546Spatrickclass Logger: 74*061da546Spatrick 75*061da546Spatrick def __init__(self, autoflush=False, logcaller=False): 76*061da546Spatrick global _lldb_formatters_debug_level 77*061da546Spatrick global _lldb_formatters_debug_filename 78*061da546Spatrick self.autoflush = autoflush 79*061da546Spatrick want_log = False 80*061da546Spatrick try: 81*061da546Spatrick want_log = (_lldb_formatters_debug_level > 0) 82*061da546Spatrick except: 83*061da546Spatrick pass 84*061da546Spatrick if not (want_log): 85*061da546Spatrick self.impl = NopLogger() 86*061da546Spatrick return 87*061da546Spatrick want_file = False 88*061da546Spatrick try: 89*061da546Spatrick want_file = (_lldb_formatters_debug_filename is not None and _lldb_formatters_debug_filename != 90*061da546Spatrick '' and _lldb_formatters_debug_filename != 0) 91*061da546Spatrick except: 92*061da546Spatrick pass 93*061da546Spatrick if want_file: 94*061da546Spatrick self.impl = FileLogger(_lldb_formatters_debug_filename) 95*061da546Spatrick else: 96*061da546Spatrick self.impl = StdoutLogger() 97*061da546Spatrick try: 98*061da546Spatrick self.autoflush = (_lldb_formatters_debug_level > 1) 99*061da546Spatrick except: 100*061da546Spatrick self.autoflush = autoflush 101*061da546Spatrick want_caller_info = False 102*061da546Spatrick try: 103*061da546Spatrick want_caller_info = (_lldb_formatters_debug_level > 2) 104*061da546Spatrick except: 105*061da546Spatrick pass 106*061da546Spatrick if want_caller_info: 107*061da546Spatrick self._log_caller() 108*061da546Spatrick 109*061da546Spatrick def _log_caller(self): 110*061da546Spatrick caller = inspect.stack()[2] 111*061da546Spatrick try: 112*061da546Spatrick if caller is not None and len(caller) > 3: 113*061da546Spatrick self.write('Logging from function ' + str(caller)) 114*061da546Spatrick else: 115*061da546Spatrick self.write( 116*061da546Spatrick 'Caller info not available - Required caller logging not possible') 117*061da546Spatrick finally: 118*061da546Spatrick del caller # needed per Python docs to avoid keeping objects alive longer than we care 119*061da546Spatrick 120*061da546Spatrick def write(self, data): 121*061da546Spatrick self.impl.write(data) 122*061da546Spatrick if self.autoflush: 123*061da546Spatrick self.flush() 124*061da546Spatrick 125*061da546Spatrick def __rshift__(self, data): 126*061da546Spatrick self.write(data) 127*061da546Spatrick 128*061da546Spatrick def flush(self): 129*061da546Spatrick self.impl.flush() 130*061da546Spatrick 131*061da546Spatrick def close(self): 132*061da546Spatrick self.impl.close() 133