]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/__init__.py
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / python / lib / gdb / __init__.py
1 # Copyright (C) 2010-2024 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
16 import signal
17 import threading
18 import traceback
19 import os
20 import sys
21 import _gdb
22 from contextlib import contextmanager
23
24 # Python 3 moved "reload"
25 if sys.version_info >= (3, 4):
26 from importlib import reload
27 else:
28 from imp import reload
29
30 from _gdb import *
31
32 # Historically, gdb.events was always available, so ensure it's
33 # still available without an explicit import.
34 import _gdbevents as events
35
36 sys.modules["gdb.events"] = events
37
38
39 class _GdbFile(object):
40 # These two are needed in Python 3
41 encoding = "UTF-8"
42 errors = "strict"
43
44 def __init__(self, stream):
45 self.stream = stream
46
47 def close(self):
48 # Do nothing.
49 return None
50
51 def isatty(self):
52 return False
53
54 def writelines(self, iterable):
55 for line in iterable:
56 self.write(line)
57
58 def flush(self):
59 flush(stream=self.stream)
60
61 def write(self, s):
62 write(s, stream=self.stream)
63
64
65 sys.stdout = _GdbFile(STDOUT)
66
67 sys.stderr = _GdbFile(STDERR)
68
69 # Default prompt hook does nothing.
70 prompt_hook = None
71
72 # Ensure that sys.argv is set to something.
73 # We do not use PySys_SetArgvEx because it did not appear until 2.6.6.
74 sys.argv = [""]
75
76 # Initial pretty printers.
77 pretty_printers = []
78
79 # Initial type printers.
80 type_printers = []
81 # Initial xmethod matchers.
82 xmethods = []
83 # Initial frame filters.
84 frame_filters = {}
85 # Initial frame unwinders.
86 frame_unwinders = []
87 # Initial missing debug handlers.
88 missing_debug_handlers = []
89
90
91 def _execute_unwinders(pending_frame):
92 """Internal function called from GDB to execute all unwinders.
93
94 Runs each currently enabled unwinder until it finds the one that
95 can unwind given frame.
96
97 Arguments:
98 pending_frame: gdb.PendingFrame instance.
99
100 Returns:
101 Tuple with:
102
103 [0] gdb.UnwindInfo instance
104 [1] Name of unwinder that claimed the frame (type `str`)
105
106 or None, if no unwinder has claimed the frame.
107 """
108 for objfile in objfiles():
109 for unwinder in objfile.frame_unwinders:
110 if unwinder.enabled:
111 unwind_info = unwinder(pending_frame)
112 if unwind_info is not None:
113 return (unwind_info, unwinder.name)
114
115 for unwinder in current_progspace().frame_unwinders:
116 if unwinder.enabled:
117 unwind_info = unwinder(pending_frame)
118 if unwind_info is not None:
119 return (unwind_info, unwinder.name)
120
121 for unwinder in frame_unwinders:
122 if unwinder.enabled:
123 unwind_info = unwinder(pending_frame)
124 if unwind_info is not None:
125 return (unwind_info, unwinder.name)
126
127 return None
128
129
130 def _execute_file(filepath):
131 """This function is used to replace Python 2's PyRun_SimpleFile.
132
133 Loads and executes the given file.
134
135 We could use the runpy module, but its documentation says:
136 "Furthermore, any functions and classes defined by the executed code are
137 not guaranteed to work correctly after a runpy function has returned."
138 """
139 globals = sys.modules["__main__"].__dict__
140 set_file = False
141 # Set file (if not set) so that the imported file can use it (e.g. to
142 # access file-relative paths). This matches what PyRun_SimpleFile does.
143 if not hasattr(globals, "__file__"):
144 globals["__file__"] = filepath
145 set_file = True
146 try:
147 with open(filepath, "rb") as file:
148 # We pass globals also as locals to match what Python does
149 # in PyRun_SimpleFile.
150 compiled = compile(file.read(), filepath, "exec")
151 exec(compiled, globals, globals)
152 finally:
153 if set_file:
154 del globals["__file__"]
155
156
157 # Convenience variable to GDB's python directory
158 PYTHONDIR = os.path.dirname(os.path.dirname(__file__))
159
160 # Auto-load all functions/commands.
161
162 # Packages to auto-load.
163
164 packages = ["function", "command", "printer"]
165
166 # pkgutil.iter_modules is not available prior to Python 2.6. Instead,
167 # manually iterate the list, collating the Python files in each module
168 # path. Construct the module name, and import.
169
170
171 def _auto_load_packages():
172 for package in packages:
173 location = os.path.join(os.path.dirname(__file__), package)
174 if os.path.exists(location):
175 py_files = filter(
176 lambda x: x.endswith(".py") and x != "__init__.py", os.listdir(location)
177 )
178
179 for py_file in py_files:
180 # Construct from foo.py, gdb.module.foo
181 modname = "%s.%s.%s" % (__name__, package, py_file[:-3])
182 try:
183 if modname in sys.modules:
184 # reload modules with duplicate names
185 reload(__import__(modname))
186 else:
187 __import__(modname)
188 except:
189 sys.stderr.write(traceback.format_exc() + "\n")
190
191
192 _auto_load_packages()
193
194
195 def GdbSetPythonDirectory(dir):
196 """Update sys.path, reload gdb and auto-load packages."""
197 global PYTHONDIR
198
199 try:
200 sys.path.remove(PYTHONDIR)
201 except ValueError:
202 pass
203 sys.path.insert(0, dir)
204
205 PYTHONDIR = dir
206
207 # note that reload overwrites the gdb module without deleting existing
208 # attributes
209 reload(__import__(__name__))
210 _auto_load_packages()
211
212
213 def current_progspace():
214 "Return the current Progspace."
215 return selected_inferior().progspace
216
217
218 def objfiles():
219 "Return a sequence of the current program space's objfiles."
220 return current_progspace().objfiles()
221
222
223 def solib_name(addr):
224 """solib_name (Long) -> String.\n\
225 Return the name of the shared library holding a given address, or None."""
226 return current_progspace().solib_name(addr)
227
228
229 def block_for_pc(pc):
230 "Return the block containing the given pc value, or None."
231 return current_progspace().block_for_pc(pc)
232
233
234 def find_pc_line(pc):
235 """find_pc_line (pc) -> Symtab_and_line.
236 Return the gdb.Symtab_and_line object corresponding to the pc value."""
237 return current_progspace().find_pc_line(pc)
238
239
240 def set_parameter(name, value):
241 """Set the GDB parameter NAME to VALUE."""
242 # Handle the specific cases of None and booleans here, because
243 # gdb.parameter can return them, but they can't be passed to 'set'
244 # this way.
245 if value is None:
246 value = "unlimited"
247 elif isinstance(value, bool):
248 if value:
249 value = "on"
250 else:
251 value = "off"
252 execute("set " + name + " " + str(value), to_string=True)
253
254
255 @contextmanager
256 def with_parameter(name, value):
257 """Temporarily set the GDB parameter NAME to VALUE.
258 Note that this is a context manager."""
259 old_value = parameter(name)
260 set_parameter(name, value)
261 try:
262 # Nothing that useful to return.
263 yield None
264 finally:
265 set_parameter(name, old_value)
266
267
268 @contextmanager
269 def blocked_signals():
270 """A helper function that blocks and unblocks signals."""
271 if not hasattr(signal, "pthread_sigmask"):
272 yield
273 return
274
275 to_block = {signal.SIGCHLD, signal.SIGINT, signal.SIGALRM, signal.SIGWINCH}
276 old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, to_block)
277 try:
278 yield None
279 finally:
280 signal.pthread_sigmask(signal.SIG_SETMASK, old_mask)
281
282
283 class Thread(threading.Thread):
284 """A GDB-specific wrapper around threading.Thread
285
286 This wrapper ensures that the new thread blocks any signals that
287 must be delivered on GDB's main thread."""
288
289 def start(self):
290 # GDB requires that these be delivered to the main thread. We
291 # do this here to avoid any possible race with the creation of
292 # the new thread. The thread mask is inherited by new
293 # threads.
294 with blocked_signals():
295 super().start()
296
297
298 def _handle_missing_debuginfo(objfile):
299 """Internal function called from GDB to execute missing debug
300 handlers.
301
302 Run each of the currently registered, and enabled missing debug
303 handler objects for the current program space and then from the
304 global list. Stop after the first handler that returns a result
305 other than None.
306
307 Arguments:
308 objfile: A gdb.Objfile for which GDB could not find any debug
309 information.
310
311 Returns:
312 None: No debug information could be found for objfile.
313 False: A handler has done all it can with objfile, but no
314 debug information could be found.
315 True: Debug information might have been installed by a
316 handler, GDB should check again.
317 A string: This is the filename of a file containing the
318 required debug information.
319 """
320 pspace = objfile.progspace
321
322 for handler in pspace.missing_debug_handlers:
323 if handler.enabled:
324 result = handler(objfile)
325 if result is not None:
326 return result
327
328 for handler in missing_debug_handlers:
329 if handler.enabled:
330 result = handler(objfile)
331 if result is not None:
332 return result
333
334 return None