1# Copyright (C) 2010-2023 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16import traceback 17import os 18import sys 19import _gdb 20from contextlib import contextmanager 21 22# Python 3 moved "reload" 23if sys.version_info >= (3, 4): 24 from importlib import reload 25else: 26 from imp import reload 27 28from _gdb import * 29 30# Historically, gdb.events was always available, so ensure it's 31# still available without an explicit import. 32import _gdbevents as events 33 34sys.modules["gdb.events"] = events 35 36 37class _GdbFile(object): 38 # These two are needed in Python 3 39 encoding = "UTF-8" 40 errors = "strict" 41 42 def __init__(self, stream): 43 self.stream = stream 44 45 def close(self): 46 # Do nothing. 47 return None 48 49 def isatty(self): 50 return False 51 52 def writelines(self, iterable): 53 for line in iterable: 54 self.write(line) 55 56 def flush(self): 57 flush(stream=self.stream) 58 59 def write(self, s): 60 write(s, stream=self.stream) 61 62 63sys.stdout = _GdbFile(STDOUT) 64 65sys.stderr = _GdbFile(STDERR) 66 67# Default prompt hook does nothing. 68prompt_hook = None 69 70# Ensure that sys.argv is set to something. 71# We do not use PySys_SetArgvEx because it did not appear until 2.6.6. 72sys.argv = [""] 73 74# Initial pretty printers. 75pretty_printers = [] 76 77# Initial type printers. 78type_printers = [] 79# Initial xmethod matchers. 80xmethods = [] 81# Initial frame filters. 82frame_filters = {} 83# Initial frame unwinders. 84frame_unwinders = [] 85 86 87def _execute_unwinders(pending_frame): 88 """Internal function called from GDB to execute all unwinders. 89 90 Runs each currently enabled unwinder until it finds the one that 91 can unwind given frame. 92 93 Arguments: 94 pending_frame: gdb.PendingFrame instance. 95 96 Returns: 97 Tuple with: 98 99 [0] gdb.UnwindInfo instance 100 [1] Name of unwinder that claimed the frame (type `str`) 101 102 or None, if no unwinder has claimed the frame. 103 """ 104 for objfile in objfiles(): 105 for unwinder in objfile.frame_unwinders: 106 if unwinder.enabled: 107 unwind_info = unwinder(pending_frame) 108 if unwind_info is not None: 109 return (unwind_info, unwinder.name) 110 111 for unwinder in current_progspace().frame_unwinders: 112 if unwinder.enabled: 113 unwind_info = unwinder(pending_frame) 114 if unwind_info is not None: 115 return (unwind_info, unwinder.name) 116 117 for unwinder in frame_unwinders: 118 if unwinder.enabled: 119 unwind_info = unwinder(pending_frame) 120 if unwind_info is not None: 121 return (unwind_info, unwinder.name) 122 123 return None 124 125 126def _execute_file(filepath): 127 """This function is used to replace Python 2's PyRun_SimpleFile. 128 129 Loads and executes the given file. 130 131 We could use the runpy module, but its documentation says: 132 "Furthermore, any functions and classes defined by the executed code are 133 not guaranteed to work correctly after a runpy function has returned." 134 """ 135 globals = sys.modules["__main__"].__dict__ 136 set_file = False 137 # Set file (if not set) so that the imported file can use it (e.g. to 138 # access file-relative paths). This matches what PyRun_SimpleFile does. 139 if not hasattr(globals, "__file__"): 140 globals["__file__"] = filepath 141 set_file = True 142 try: 143 with open(filepath, "rb") as file: 144 # We pass globals also as locals to match what Python does 145 # in PyRun_SimpleFile. 146 compiled = compile(file.read(), filepath, "exec") 147 exec(compiled, globals, globals) 148 finally: 149 if set_file: 150 del globals["__file__"] 151 152 153# Convenience variable to GDB's python directory 154PYTHONDIR = os.path.dirname(os.path.dirname(__file__)) 155 156# Auto-load all functions/commands. 157 158# Packages to auto-load. 159 160packages = ["function", "command", "printer"] 161 162# pkgutil.iter_modules is not available prior to Python 2.6. Instead, 163# manually iterate the list, collating the Python files in each module 164# path. Construct the module name, and import. 165 166 167def _auto_load_packages(): 168 for package in packages: 169 location = os.path.join(os.path.dirname(__file__), package) 170 if os.path.exists(location): 171 py_files = filter( 172 lambda x: x.endswith(".py") and x != "__init__.py", os.listdir(location) 173 ) 174 175 for py_file in py_files: 176 # Construct from foo.py, gdb.module.foo 177 modname = "%s.%s.%s" % (__name__, package, py_file[:-3]) 178 try: 179 if modname in sys.modules: 180 # reload modules with duplicate names 181 reload(__import__(modname)) 182 else: 183 __import__(modname) 184 except: 185 sys.stderr.write(traceback.format_exc() + "\n") 186 187 188_auto_load_packages() 189 190 191def GdbSetPythonDirectory(dir): 192 """Update sys.path, reload gdb and auto-load packages.""" 193 global PYTHONDIR 194 195 try: 196 sys.path.remove(PYTHONDIR) 197 except ValueError: 198 pass 199 sys.path.insert(0, dir) 200 201 PYTHONDIR = dir 202 203 # note that reload overwrites the gdb module without deleting existing 204 # attributes 205 reload(__import__(__name__)) 206 _auto_load_packages() 207 208 209def current_progspace(): 210 "Return the current Progspace." 211 return selected_inferior().progspace 212 213 214def objfiles(): 215 "Return a sequence of the current program space's objfiles." 216 return current_progspace().objfiles() 217 218 219def solib_name(addr): 220 """solib_name (Long) -> String.\n\ 221Return the name of the shared library holding a given address, or None.""" 222 return current_progspace().solib_name(addr) 223 224 225def block_for_pc(pc): 226 "Return the block containing the given pc value, or None." 227 return current_progspace().block_for_pc(pc) 228 229 230def find_pc_line(pc): 231 """find_pc_line (pc) -> Symtab_and_line. 232 Return the gdb.Symtab_and_line object corresponding to the pc value.""" 233 return current_progspace().find_pc_line(pc) 234 235 236def set_parameter(name, value): 237 """Set the GDB parameter NAME to VALUE.""" 238 # Handle the specific cases of None and booleans here, because 239 # gdb.parameter can return them, but they can't be passed to 'set' 240 # this way. 241 if value is None: 242 value = "unlimited" 243 elif isinstance(value, bool): 244 if value: 245 value = "on" 246 else: 247 value = "off" 248 execute("set " + name + " " + str(value), to_string=True) 249 250 251@contextmanager 252def with_parameter(name, value): 253 """Temporarily set the GDB parameter NAME to VALUE. 254 Note that this is a context manager.""" 255 old_value = parameter(name) 256 set_parameter(name, value) 257 try: 258 # Nothing that useful to return. 259 yield None 260 finally: 261 set_parameter(name, old_value) 262