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