]>
Commit | Line | Data |
---|---|---|
1d506c26 | 1 | # Copyright (C) 2010-2024 Free Software Foundation, Inc. |
aa2e2d8d DE |
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/>. | |
7b51bc51 | 15 | |
560c121c TT |
16 | import signal |
17 | import threading | |
5e239b84 | 18 | import traceback |
b9516fa1 YPK |
19 | import os |
20 | import sys | |
21 | import _gdb | |
b583c328 | 22 | from contextlib import contextmanager |
b9516fa1 | 23 | |
bfb9f5dc BS |
24 | # Python 3 moved "reload" |
25 | if sys.version_info >= (3, 4): | |
26 | from importlib import reload | |
edae3fd6 | 27 | else: |
9a27f2c6 PK |
28 | from imp import reload |
29 | ||
b9516fa1 YPK |
30 | from _gdb import * |
31 | ||
3acd9a69 TT |
32 | # Historically, gdb.events was always available, so ensure it's |
33 | # still available without an explicit import. | |
34 | import _gdbevents as events | |
bf4d777d TT |
35 | |
36 | sys.modules["gdb.events"] = events | |
3acd9a69 | 37 | |
13123da8 SM |
38 | |
39 | class _GdbFile(object): | |
9a27f2c6 PK |
40 | # These two are needed in Python 3 |
41 | encoding = "UTF-8" | |
42 | errors = "strict" | |
d11916aa | 43 | |
2d83dd69 TT |
44 | def __init__(self, stream): |
45 | self.stream = stream | |
46 | ||
b9516fa1 YPK |
47 | def close(self): |
48 | # Do nothing. | |
49 | return None | |
50 | ||
51 | def isatty(self): | |
52 | return False | |
53 | ||
b9516fa1 YPK |
54 | def writelines(self, iterable): |
55 | for line in iterable: | |
56 | self.write(line) | |
57 | ||
58 | def flush(self): | |
2d83dd69 | 59 | flush(stream=self.stream) |
13123da8 | 60 | |
9a27f2c6 | 61 | def write(self, s): |
2d83dd69 | 62 | write(s, stream=self.stream) |
13123da8 | 63 | |
b9516fa1 | 64 | |
2d83dd69 | 65 | sys.stdout = _GdbFile(STDOUT) |
13123da8 | 66 | |
2d83dd69 | 67 | sys.stderr = _GdbFile(STDERR) |
b9516fa1 YPK |
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. | |
13123da8 | 74 | sys.argv = [""] |
b9516fa1 YPK |
75 | |
76 | # Initial pretty printers. | |
77 | pretty_printers = [] | |
78 | ||
18a9fc12 TT |
79 | # Initial type printers. |
80 | type_printers = [] | |
883964a7 SC |
81 | # Initial xmethod matchers. |
82 | xmethods = [] | |
1e611234 PM |
83 | # Initial frame filters. |
84 | frame_filters = {} | |
d11916aa SS |
85 | # Initial frame unwinders. |
86 | frame_unwinders = [] | |
8f6c452b AB |
87 | # Initial missing debug handlers. |
88 | missing_debug_handlers = [] | |
d11916aa | 89 | |
13123da8 | 90 | |
08235187 | 91 | def _execute_unwinders(pending_frame): |
d11916aa SS |
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. | |
4e317a76 | 99 | |
d11916aa | 100 | Returns: |
4e317a76 SM |
101 | Tuple with: |
102 | ||
224506e9 SM |
103 | [0] gdb.UnwindInfo instance |
104 | [1] Name of unwinder that claimed the frame (type `str`) | |
4e317a76 | 105 | |
224506e9 | 106 | or None, if no unwinder has claimed the frame. |
d11916aa | 107 | """ |
8743a9cd | 108 | for objfile in objfiles(): |
d11916aa SS |
109 | for unwinder in objfile.frame_unwinders: |
110 | if unwinder.enabled: | |
111 | unwind_info = unwinder(pending_frame) | |
112 | if unwind_info is not None: | |
4e317a76 | 113 | return (unwind_info, unwinder.name) |
d11916aa | 114 | |
8743a9cd | 115 | for unwinder in current_progspace().frame_unwinders: |
d11916aa SS |
116 | if unwinder.enabled: |
117 | unwind_info = unwinder(pending_frame) | |
118 | if unwind_info is not None: | |
4e317a76 | 119 | return (unwind_info, unwinder.name) |
d11916aa SS |
120 | |
121 | for unwinder in frame_unwinders: | |
122 | if unwinder.enabled: | |
123 | unwind_info = unwinder(pending_frame) | |
124 | if unwind_info is not None: | |
4e317a76 | 125 | return (unwind_info, unwinder.name) |
d11916aa SS |
126 | |
127 | return None | |
128 | ||
13123da8 | 129 | |
27204489 CB |
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 | """ | |
13123da8 | 139 | globals = sys.modules["__main__"].__dict__ |
27204489 CB |
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. | |
13123da8 SM |
143 | if not hasattr(globals, "__file__"): |
144 | globals["__file__"] = filepath | |
27204489 CB |
145 | set_file = True |
146 | try: | |
13123da8 | 147 | with open(filepath, "rb") as file: |
27204489 CB |
148 | # We pass globals also as locals to match what Python does |
149 | # in PyRun_SimpleFile. | |
13123da8 | 150 | compiled = compile(file.read(), filepath, "exec") |
27204489 CB |
151 | exec(compiled, globals, globals) |
152 | finally: | |
153 | if set_file: | |
13123da8 | 154 | del globals["__file__"] |
27204489 | 155 | |
18a9fc12 | 156 | |
b9516fa1 YPK |
157 | # Convenience variable to GDB's python directory |
158 | PYTHONDIR = os.path.dirname(os.path.dirname(__file__)) | |
7b51bc51 | 159 | |
5e239b84 PM |
160 | # Auto-load all functions/commands. |
161 | ||
b9516fa1 | 162 | # Packages to auto-load. |
5e239b84 | 163 | |
13123da8 | 164 | packages = ["function", "command", "printer"] |
5e239b84 | 165 | |
b9516fa1 YPK |
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 | |
5e239b84 PM |
168 | # path. Construct the module name, and import. |
169 | ||
13123da8 | 170 | |
08235187 | 171 | def _auto_load_packages(): |
b9516fa1 YPK |
172 | for package in packages: |
173 | location = os.path.join(os.path.dirname(__file__), package) | |
174 | if os.path.exists(location): | |
13123da8 SM |
175 | py_files = filter( |
176 | lambda x: x.endswith(".py") and x != "__init__.py", os.listdir(location) | |
177 | ) | |
b9516fa1 YPK |
178 | |
179 | for py_file in py_files: | |
180 | # Construct from foo.py, gdb.module.foo | |
13123da8 | 181 | modname = "%s.%s.%s" % (__name__, package, py_file[:-3]) |
b9516fa1 YPK |
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: | |
13123da8 SM |
189 | sys.stderr.write(traceback.format_exc() + "\n") |
190 | ||
b9516fa1 | 191 | |
08235187 | 192 | _auto_load_packages() |
b9516fa1 | 193 | |
13123da8 | 194 | |
b9516fa1 YPK |
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__)) | |
08235187 | 210 | _auto_load_packages() |
8743a9cd | 211 | |
13123da8 | 212 | |
8743a9cd TT |
213 | def current_progspace(): |
214 | "Return the current Progspace." | |
215 | return selected_inferior().progspace | |
216 | ||
13123da8 | 217 | |
8743a9cd TT |
218 | def objfiles(): |
219 | "Return a sequence of the current program space's objfiles." | |
220 | return current_progspace().objfiles() | |
221 | ||
13123da8 SM |
222 | |
223 | def solib_name(addr): | |
8743a9cd TT |
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 | ||
13123da8 | 228 | |
8743a9cd TT |
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 | ||
13123da8 | 233 | |
8743a9cd TT |
234 | def find_pc_line(pc): |
235 | """find_pc_line (pc) -> Symtab_and_line. | |
13123da8 | 236 | Return the gdb.Symtab_and_line object corresponding to the pc value.""" |
8743a9cd | 237 | return current_progspace().find_pc_line(pc) |
f6474de9 | 238 | |
13123da8 | 239 | |
b583c328 TT |
240 | def set_parameter(name, value): |
241 | """Set the GDB parameter NAME to VALUE.""" | |
c506be7d MR |
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): | |
fa17a681 | 248 | if value: |
bf4d777d | 249 | value = "on" |
fa17a681 | 250 | else: |
bf4d777d | 251 | value = "off" |
299953ca | 252 | execute("set " + name + " " + str(value), to_string=True) |
b583c328 TT |
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) | |
560c121c TT |
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} | |
30c01bb1 | 276 | old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, to_block) |
560c121c TT |
277 | try: |
278 | yield None | |
279 | finally: | |
30c01bb1 | 280 | signal.pthread_sigmask(signal.SIG_SETMASK, old_mask) |
560c121c TT |
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() | |
8f6c452b AB |
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 |