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