??????????????????????????????? ??????????????????????????????? ??????????????????????????????? >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. ??????????????????????????????? ??????????????????????????????? ??????????????????????????????? ??????????????????????????????? ??????????????????????????????? ??????????????????????????????? >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< PK!&tɘ(˜(python/gdb/FrameDecorator.pynu„[µü¤# Copyright (C) 2013-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb # This small code snippet deals with problem of strings in Python 2.x # and Python 3.x. Python 2.x has str and unicode classes which are # sub-classes of basestring. In Python 3.x all strings are encoded # and basestring has been removed. try: basestring except NameError: basestring = str class FrameDecorator(object): """Basic implementation of a Frame Decorator""" """ This base frame decorator decorates a frame or another frame decorator, and provides convenience methods. If this object is wrapping a frame decorator, defer to that wrapped object's method if it has one. This allows for frame decorators that have sub-classed FrameDecorator object, but also wrap other frame decorators on the same frame to correctly execute. E.g If the result of frame filters running means we have one gdb.Frame wrapped by multiple frame decorators, all sub-classed from FrameDecorator, the resulting hierarchy will be: Decorator1 -- (wraps) Decorator2 -- (wraps) FrameDecorator -- (wraps) gdb.Frame In this case we have two frame decorators, both of which are sub-classed from FrameDecorator. If Decorator1 just overrides the 'function' method, then all of the other methods are carried out by the super-class FrameDecorator. But Decorator2 may have overriden other methods, so FrameDecorator will look at the 'base' parameter and defer to that class's methods. And so on, down the chain.""" # 'base' can refer to a gdb.Frame or another frame decorator. In # the latter case, the child class will have called the super # method and _base will be an object conforming to the Frame Filter # class. def __init__(self, base): self._base = base @staticmethod def _is_limited_frame(frame): """Internal utility to determine if the frame is special or limited.""" sal = frame.find_sal() if (not sal.symtab or not sal.symtab.filename or frame.type() == gdb.DUMMY_FRAME or frame.type() == gdb.SIGTRAMP_FRAME): return True return False def elided(self): """Return any elided frames that this class might be wrapping, or None.""" if hasattr(self._base, "elided"): return self._base.elided() return None def function(self): """ Return the name of the frame's function or an address of the function of the frame. First determine if this is a special frame. If not, try to determine filename from GDB's frame internal function API. Finally, if a name cannot be determined return the address. If this function returns an address, GDB will attempt to determine the function name from its internal minimal symbols store (for example, for inferiors without debug-info).""" # Both gdb.Frame, and FrameDecorator have a method called # "function", so determine which object this is. if not isinstance(self._base, gdb.Frame): if hasattr(self._base, "function"): # If it is not a gdb.Frame, and there is already a # "function" method, use that. return self._base.function() frame = self.inferior_frame() if frame.type() == gdb.DUMMY_FRAME: return "" elif frame.type() == gdb.SIGTRAMP_FRAME: return "" func = frame.function() # If we cannot determine the function name, return the # address. If GDB detects an integer value from this function # it will attempt to find the function name from minimal # symbols via its own internal functions. if func == None: pc = frame.pc() return pc return str(func) def address(self): """ Return the address of the frame's pc""" if hasattr(self._base, "address"): return self._base.address() frame = self.inferior_frame() return frame.pc() def filename(self): """ Return the filename associated with this frame, detecting and returning the appropriate library name is this is a shared library.""" if hasattr(self._base, "filename"): return self._base.filename() frame = self.inferior_frame() sal = frame.find_sal() if not sal.symtab or not sal.symtab.filename: pc = frame.pc() return gdb.solib_name(pc) else: return sal.symtab.filename def frame_args(self): """ Return an iterable of frame arguments for this frame, if any. The iterable object contains objects conforming with the Symbol/Value interface. If there are no frame arguments, or if this frame is deemed to be a special case, return None.""" if hasattr(self._base, "frame_args"): return self._base.frame_args() frame = self.inferior_frame() if self._is_limited_frame(frame): return None args = FrameVars(frame) return args.fetch_frame_args() def frame_locals(self): """ Return an iterable of local variables for this frame, if any. The iterable object contains objects conforming with the Symbol/Value interface. If there are no frame locals, or if this frame is deemed to be a special case, return None.""" if hasattr(self._base, "frame_locals"): return self._base.frame_locals() frame = self.inferior_frame() if self._is_limited_frame(frame): return None args = FrameVars(frame) return args.fetch_frame_locals() def line(self): """ Return line number information associated with the frame's pc. If symbol table/line information does not exist, or if this frame is deemed to be a special case, return None""" if hasattr(self._base, "line"): return self._base.line() frame = self.inferior_frame() if self._is_limited_frame(frame): return None sal = frame.find_sal() if (sal): return sal.line else: return None def inferior_frame(self): """ Return the gdb.Frame underpinning this frame decorator.""" # If 'base' is a frame decorator, we want to call its inferior # frame method. If '_base' is a gdb.Frame, just return that. if hasattr(self._base, "inferior_frame"): return self._base.inferior_frame() return self._base class SymValueWrapper(object): """A container class conforming to the Symbol/Value interface which holds frame locals or frame arguments.""" def __init__(self, symbol, value): self.sym = symbol self.val = value def value(self): """ Return the value associated with this symbol, or None""" return self.val def symbol(self): """ Return the symbol, or Python text, associated with this symbol, or None""" return self.sym class FrameVars(object): """Utility class to fetch and store frame local variables, or frame arguments.""" def __init__(self, frame): self.frame = frame self.symbol_class = { gdb.SYMBOL_LOC_STATIC: True, gdb.SYMBOL_LOC_REGISTER: True, gdb.SYMBOL_LOC_ARG: True, gdb.SYMBOL_LOC_REF_ARG: True, gdb.SYMBOL_LOC_LOCAL: True, gdb.SYMBOL_LOC_REGPARM_ADDR: True, gdb.SYMBOL_LOC_COMPUTED: True } def fetch_b(self, sym): """ Local utility method to determine if according to Symbol type whether it should be included in the iterator. Not all symbols are fetched, and only symbols that return True from this method should be fetched.""" # SYM may be a string instead of a symbol in the case of # synthetic local arguments or locals. If that is the case, # always fetch. if isinstance(sym, basestring): return True sym_type = sym.addr_class return self.symbol_class.get(sym_type, False) def fetch_frame_locals(self): """Public utility method to fetch frame local variables for the stored frame. Frame arguments are not fetched. If there are no frame local variables, return an empty list.""" lvars = [] try: block = self.frame.block() except RuntimeError: block = None while block != None: if block.is_global or block.is_static: break for sym in block: if sym.is_argument: continue; if self.fetch_b(sym): lvars.append(SymValueWrapper(sym, None)) block = block.superblock return lvars def fetch_frame_args(self): """Public utility method to fetch frame arguments for the stored frame. Frame arguments are the only type fetched. If there are no frame argument variables, return an empty list.""" args = [] try: block = self.frame.block() except RuntimeError: block = None while block != None: if block.function != None: break block = block.superblock if block != None: for sym in block: if not sym.is_argument: continue; args.append(SymValueWrapper(sym, None)) return args PK!Z6 ~python/gdb/__init__.pynu„[µü¤# Copyright (C) 2010-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import traceback import os import sys import _gdb if sys.version_info[0] > 2: # Python 3 moved "reload" from imp import reload from _gdb import * class _GdbFile (object): # These two are needed in Python 3 encoding = "UTF-8" errors = "strict" def close(self): # Do nothing. return None def isatty(self): return False def writelines(self, iterable): for line in iterable: self.write(line) def flush(self): flush() class GdbOutputFile (_GdbFile): def write(self, s): write(s, stream=STDOUT) sys.stdout = GdbOutputFile() class GdbOutputErrorFile (_GdbFile): def write(self, s): write(s, stream=STDERR) sys.stderr = GdbOutputErrorFile() # Default prompt hook does nothing. prompt_hook = None # Ensure that sys.argv is set to something. # We do not use PySys_SetArgvEx because it did not appear until 2.6.6. sys.argv = [''] # Initial pretty printers. pretty_printers = [] # Initial type printers. type_printers = [] # Initial xmethod matchers. xmethods = [] # Initial frame filters. frame_filters = {} # Initial frame unwinders. frame_unwinders = [] def execute_unwinders(pending_frame): """Internal function called from GDB to execute all unwinders. Runs each currently enabled unwinder until it finds the one that can unwind given frame. Arguments: pending_frame: gdb.PendingFrame instance. Returns: gdb.UnwindInfo instance or None. """ for objfile in _gdb.objfiles(): for unwinder in objfile.frame_unwinders: if unwinder.enabled: unwind_info = unwinder(pending_frame) if unwind_info is not None: return unwind_info current_progspace = _gdb.current_progspace() for unwinder in current_progspace.frame_unwinders: if unwinder.enabled: unwind_info = unwinder(pending_frame) if unwind_info is not None: return unwind_info for unwinder in frame_unwinders: if unwinder.enabled: unwind_info = unwinder(pending_frame) if unwind_info is not None: return unwind_info return None # Convenience variable to GDB's python directory PYTHONDIR = os.path.dirname(os.path.dirname(__file__)) # Auto-load all functions/commands. # Packages to auto-load. packages = [ 'function', 'command', 'printer' ] # pkgutil.iter_modules is not available prior to Python 2.6. Instead, # manually iterate the list, collating the Python files in each module # path. Construct the module name, and import. def auto_load_packages(): for package in packages: location = os.path.join(os.path.dirname(__file__), package) if os.path.exists(location): py_files = filter(lambda x: x.endswith('.py') and x != '__init__.py', os.listdir(location)) for py_file in py_files: # Construct from foo.py, gdb.module.foo modname = "%s.%s.%s" % ( __name__, package, py_file[:-3] ) try: if modname in sys.modules: # reload modules with duplicate names reload(__import__(modname)) else: __import__(modname) except: sys.stderr.write (traceback.format_exc() + "\n") auto_load_packages() def GdbSetPythonDirectory(dir): """Update sys.path, reload gdb and auto-load packages.""" global PYTHONDIR try: sys.path.remove(PYTHONDIR) except ValueError: pass sys.path.insert(0, dir) PYTHONDIR = dir # note that reload overwrites the gdb module without deleting existing # attributes reload(__import__(__name__)) auto_load_packages() PK!É4))python/gdb/FrameIterator.pynu„[µü¤# Copyright (C) 2013-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb import itertools class FrameIterator(object): """A gdb.Frame iterator. Iterates over gdb.Frames or objects that conform to that interface.""" def __init__(self, frame_obj): """Initialize a FrameIterator. Arguments: frame_obj the starting frame.""" super(FrameIterator, self).__init__() self.frame = frame_obj def __iter__(self): return self def next(self): """next implementation. Returns: The next oldest frame.""" result = self.frame if result is None: raise StopIteration self.frame = result.older() return result # Python 3.x requires __next__(self) while Python 2.x requires # next(self). Define next(self), and for Python 3.x create this # wrapper. def __next__(self): return self.next() PK!dÖïŽ__python/gdb/frames.pynu„[µü¤# Frame-filter commands. # Copyright (C) 2013-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Internal functions for working with frame-filters.""" import gdb from gdb.FrameIterator import FrameIterator from gdb.FrameDecorator import FrameDecorator import itertools import collections def get_priority(filter_item): """ Internal worker function to return the frame-filter's priority from a frame filter object. This is a fail free function as it is used in sorting and filtering. If a badly implemented frame filter does not implement the priority attribute, return zero (otherwise sorting/filtering will fail and prevent other frame filters from executing). Arguments: filter_item: An object conforming to the frame filter interface. Returns: The priority of the frame filter from the "priority" attribute, or zero. """ # Do not fail here, as the sort will fail. If a filter has not # (incorrectly) set a priority, set it to zero. return getattr(filter_item, "priority", 0) def set_priority(filter_item, priority): """ Internal worker function to set the frame-filter's priority. Arguments: filter_item: An object conforming to the frame filter interface. priority: The priority to assign as an integer. """ filter_item.priority = priority def get_enabled(filter_item): """ Internal worker function to return a filter's enabled state from a frame filter object. This is a fail free function as it is used in sorting and filtering. If a badly implemented frame filter does not implement the enabled attribute, return False (otherwise sorting/filtering will fail and prevent other frame filters from executing). Arguments: filter_item: An object conforming to the frame filter interface. Returns: The enabled state of the frame filter from the "enabled" attribute, or False. """ # If the filter class is badly implemented when called from the # Python filter command, do not cease filter operations, just set # enabled to False. return getattr(filter_item, "enabled", False) def set_enabled(filter_item, state): """ Internal Worker function to set the frame-filter's enabled state. Arguments: filter_item: An object conforming to the frame filter interface. state: True or False, depending on desired state. """ filter_item.enabled = state def return_list(name): """ Internal Worker function to return the frame filter dictionary, depending on the name supplied as an argument. If the name is not "all", "global" or "progspace", it is assumed to name an object-file. Arguments: name: The name of the list, as specified by GDB user commands. Returns: A dictionary object for a single specified dictionary, or a list containing all the items for "all" Raises: gdb.GdbError: A dictionary of that name cannot be found. """ # If all dictionaries are wanted in the case of "all" we # cannot return a combined dictionary as keys() may clash in # between different dictionaries. As we just want all the frame # filters to enable/disable them all, just return the combined # items() as a chained iterator of dictionary values. if name == "all": glob = gdb.frame_filters.values() prog = gdb.current_progspace().frame_filters.values() return_iter = itertools.chain(glob, prog) for objfile in gdb.objfiles(): return_iter = itertools.chain(return_iter, objfile.frame_filters.values()) return return_iter if name == "global": return gdb.frame_filters else: if name == "progspace": cp = gdb.current_progspace() return cp.frame_filters else: for objfile in gdb.objfiles(): if name == objfile.filename: return objfile.frame_filters msg = "Cannot find frame-filter dictionary for '" + name + "'" raise gdb.GdbError(msg) def _sort_list(): """ Internal Worker function to merge all known frame-filter lists, prune any filters with the state set to "disabled", and sort the list on the frame-filter's "priority" attribute. Returns: sorted_list: A sorted, pruned list of frame filters to execute. """ all_filters = return_list("all") sorted_frame_filters = sorted(all_filters, key = get_priority, reverse = True) sorted_frame_filters = filter(get_enabled, sorted_frame_filters) return sorted_frame_filters def execute_frame_filters(frame, frame_low, frame_high): """ Internal function called from GDB that will execute the chain of frame filters. Each filter is executed in priority order. After the execution completes, slice the iterator to frame_low - frame_high range. Arguments: frame: The initial frame. frame_low: The low range of the slice. If this is a negative integer then it indicates a backward slice (ie bt -4) which counts backward from the last frame in the backtrace. frame_high: The high range of the slice. If this is -1 then it indicates all frames until the end of the stack from frame_low. Returns: frame_iterator: The sliced iterator after all frame filters have had a change to execute, or None if no frame filters are registered. """ # Get a sorted list of frame filters. sorted_list = list(_sort_list()) # Check to see if there are any frame-filters. If not, just # return None and let default backtrace printing occur. if len(sorted_list) == 0: return None frame_iterator = FrameIterator(frame) # Apply a basic frame decorator to all gdb.Frames. This unifies # the interface. Python 3.x moved the itertools.imap # functionality to map(), so check if it is available. if hasattr(itertools,"imap"): frame_iterator = itertools.imap(FrameDecorator, frame_iterator) else: frame_iterator = map(FrameDecorator, frame_iterator) for ff in sorted_list: frame_iterator = ff.filter(frame_iterator) # Slicing # Is this a slice from the end of the backtrace, ie bt -2? if frame_low < 0: count = 0 slice_length = abs(frame_low) # We cannot use MAXLEN argument for deque as it is 2.6 onwards # and some GDB versions might be < 2.6. sliced = collections.deque() for frame_item in frame_iterator: if count >= slice_length: sliced.popleft(); count = count + 1 sliced.append(frame_item) return iter(sliced) # -1 for frame_high means until the end of the backtrace. Set to # None if that is the case, to indicate to itertools.islice to # slice to the end of the iterator. if frame_high == -1: frame_high = None else: # As frames start from 0, add one to frame_high so islice # correctly finds the end frame_high = frame_high + 1; sliced = itertools.islice(frame_iterator, frame_low, frame_high) return sliced PK!¾ú$ššpython/gdb/types.pynu„[µü¤# Type utilities. # Copyright (C) 2010-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Utilities for working with gdb.Types.""" import gdb def get_basic_type(type_): """Return the "basic" type of a type. Arguments: type_: The type to reduce to its basic type. Returns: type_ with const/volatile is stripped away, and typedefs/references converted to the underlying type. """ while (type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF or type_.code == gdb.TYPE_CODE_TYPEDEF): if (type_.code == gdb.TYPE_CODE_REF or type_.code == gdb.TYPE_CODE_RVALUE_REF): type_ = type_.target() else: type_ = type_.strip_typedefs() return type_.unqualified() def has_field(type_, field): """Return True if a type has the specified field. Arguments: type_: The type to examine. It must be one of gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION. field: The name of the field to look up. Returns: True if the field is present either in type_ or any baseclass. Raises: TypeError: The type is not a struct or union. """ type_ = get_basic_type(type_) if (type_.code != gdb.TYPE_CODE_STRUCT and type_.code != gdb.TYPE_CODE_UNION): raise TypeError("not a struct or union") for f in type_.fields(): if f.is_base_class: if has_field(f.type, field): return True else: # NOTE: f.name could be None if f.name == field: return True return False def make_enum_dict(enum_type): """Return a dictionary from a program's enum type. Arguments: enum_type: The enum to compute the dictionary for. Returns: The dictionary of the enum. Raises: TypeError: The type is not an enum. """ if enum_type.code != gdb.TYPE_CODE_ENUM: raise TypeError("not an enum type") enum_dict = {} for field in enum_type.fields(): # The enum's value is stored in "enumval". enum_dict[field.name] = field.enumval return enum_dict def deep_items (type_): """Return an iterator that recursively traverses anonymous fields. Arguments: type_: The type to traverse. It should be one of gdb.TYPE_CODE_STRUCT or gdb.TYPE_CODE_UNION. Returns: an iterator similar to gdb.Type.iteritems(), i.e., it returns pairs of key, value, but for any anonymous struct or union field that field is traversed recursively, depth-first. """ for k, v in type_.iteritems (): if k: yield k, v else: for i in deep_items (v.type): yield i class TypePrinter(object): """The base class for type printers. Instances of this type can be used to substitute type names during 'ptype'. A type printer must have at least 'name' and 'enabled' attributes, and supply an 'instantiate' method. The 'instantiate' method must either return None, or return an object which has a 'recognize' method. This method must accept a gdb.Type argument and either return None, meaning that the type was not recognized, or a string naming the type. """ def __init__(self, name): self.name = name self.enabled = True def instantiate(self): return None # Helper function for computing the list of type recognizers. def _get_some_type_recognizers(result, plist): for printer in plist: if printer.enabled: inst = printer.instantiate() if inst is not None: result.append(inst) return None def get_type_recognizers(): "Return a list of the enabled type recognizers for the current context." result = [] # First try the objfiles. for objfile in gdb.objfiles(): _get_some_type_recognizers(result, objfile.type_printers) # Now try the program space. _get_some_type_recognizers(result, gdb.current_progspace().type_printers) # Finally, globals. _get_some_type_recognizers(result, gdb.type_printers) return result def apply_type_recognizers(recognizers, type_obj): """Apply the given list of type recognizers to the type TYPE_OBJ. If any recognizer in the list recognizes TYPE_OBJ, returns the name given by the recognizer. Otherwise, this returns None.""" for r in recognizers: result = r.recognize(type_obj) if result is not None: return result return None def register_type_printer(locus, printer): """Register a type printer. PRINTER is the type printer instance. LOCUS is either an objfile, a program space, or None, indicating global registration.""" if locus is None: locus = gdb locus.type_printers.insert(0, printer) PK!(b‰4´´python/gdb/function/__init__.pynu„[µü¤# Copyright (C) 2012-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PK!Þ ,vvpython/gdb/function/in_scope.pynu„[µü¤# In-scope function. # Copyright (C) 2008 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb class InScope (gdb.Function): """Return True if all the given variables or macros are in scope. Takes one argument for each variable name to be checked.""" def __init__ (self): super (InScope, self).__init__ ("in_scope") def invoke (self, *vars): if len (vars) == 0: raise (TypeError, "in_scope takes at least one argument") # gdb.Value isn't hashable so it can't be put in a map. # Convert to string first. wanted = set (map (lambda x: x.string (), vars)) found = set () block = gdb.selected_frame ().block () while block: for sym in block: if (sym.is_argument or sym.is_constant or sym.is_function or sym.is_variable): if sym.name in wanted: found.add (sym.name) block = block.superblock return wanted == found InScope () PK!ÛGŸ�| | python/gdb/function/strfns.pynu„[µü¤# Useful gdb string convenience functions. # Copyright (C) 2012-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """$_memeq, $_strlen, $_streq, $_regex""" import gdb import re class _MemEq(gdb.Function): """$_memeq - compare bytes of memory Usage: $_memeq(a, b, len) Returns: True if len bytes at a and b compare equally. """ def __init__(self): super(_MemEq, self).__init__("_memeq") def invoke(self, a, b, length): if length < 0: raise ValueError("length must be non-negative") if length == 0: return True # The argument(s) to vector are [low_bound,]high_bound. byte_vector = gdb.lookup_type("char").vector(length - 1) ptr_byte_vector = byte_vector.pointer() a_ptr = a.reinterpret_cast(ptr_byte_vector) b_ptr = b.reinterpret_cast(ptr_byte_vector) return a_ptr.dereference() == b_ptr.dereference() class _StrLen(gdb.Function): """$_strlen - compute string length Usage: $_strlen(a) Returns: Length of string a, assumed to be a string in the current language. """ def __init__(self): super(_StrLen, self).__init__("_strlen") def invoke(self, a): s = a.string() return len(s) class _StrEq(gdb.Function): """$_streq - check string equality Usage: $_streq(a, b) Returns: True if a and b are identical strings in the current language. Example (amd64-linux): catch syscall open cond $bpnum $_streq((char*) $rdi, "foo") """ def __init__(self): super(_StrEq, self).__init__("_streq") def invoke(self, a, b): return a.string() == b.string() class _RegEx(gdb.Function): """$_regex - check if a string matches a regular expression Usage: $_regex(string, regex) Returns: True if string str (in the current language) matches the regular expression regex. """ def __init__(self): super(_RegEx, self).__init__("_regex") def invoke(self, string, regex): s = string.string() r = re.compile(regex.string()) return bool(r.match(s)) # GDB will import us automagically via gdb/__init__.py. _MemEq() _StrLen() _StrEq() _RegEx() PK!æk)z python/gdb/function/as_string.pynu„[µü¤# Copyright (C) 2016-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb class _AsString(gdb.Function): """Return the string representation of a value. Usage: $_as_string(value) Arguments: value: A gdb.Value. Returns: The string representation of the value. """ def __init__(self): super(_AsString, self).__init__("_as_string") def invoke(self, val): return str(val) _AsString() PK!‹O€öÑÑ python/gdb/function/caller_is.pynu„[µü¤# Caller-is functions. # Copyright (C) 2008-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb import re class CallerIs(gdb.Function): """Check the calling function's name. Usage: $_caller_is(name [, number_of_frames]) Arguments: name: The name of the function to search for. number_of_frames: How many stack frames to traverse back from the currently selected frame to compare with. If the value is greater than the depth of the stack from that point then the result is False. The default is 1. Returns: True if the function's name at the specified frame is equal to name. """ def __init__(self): super(CallerIs, self).__init__("_caller_is") def invoke(self, name, nframes = 1): if nframes < 0: raise ValueError("nframes must be >= 0") frame = gdb.selected_frame() while nframes > 0: frame = frame.older() if frame is None: return False nframes = nframes - 1 return frame.name() == name.string() class CallerMatches(gdb.Function): """Compare the calling function's name with a regexp. Usage: $_caller_matches(regex [, number_of_frames]) Arguments: regex: The regular expression to compare the function's name with. number_of_frames: How many stack frames to traverse back from the currently selected frame to compare with. If the value is greater than the depth of the stack from that point then the result is False. The default is 1. Returns: True if the function's name at the specified frame matches regex. """ def __init__(self): super(CallerMatches, self).__init__("_caller_matches") def invoke(self, name, nframes = 1): if nframes < 0: raise ValueError("nframes must be >= 0") frame = gdb.selected_frame() while nframes > 0: frame = frame.older() if frame is None: return False nframes = nframes - 1 return re.match(name.string(), frame.name()) is not None class AnyCallerIs(gdb.Function): """Check all calling function's names. Usage: $_any_caller_is(name [, number_of_frames]) Arguments: name: The name of the function to search for. number_of_frames: How many stack frames to traverse back from the currently selected frame to compare with. If the value is greater than the depth of the stack from that point then the result is False. The default is 1. Returns: True if any function's name is equal to name. """ def __init__(self): super(AnyCallerIs, self).__init__("_any_caller_is") def invoke(self, name, nframes = 1): if nframes < 0: raise ValueError("nframes must be >= 0") frame = gdb.selected_frame() while nframes >= 0: if frame.name() == name.string(): return True frame = frame.older() if frame is None: return False nframes = nframes - 1 return False class AnyCallerMatches(gdb.Function): """Compare all calling function's names with a regexp. Usage: $_any_caller_matches(regex [, number_of_frames]) Arguments: regex: The regular expression to compare the function's name with. number_of_frames: How many stack frames to traverse back from the currently selected frame to compare with. If the value is greater than the depth of the stack from that point then the result is False. The default is 1. Returns: True if any function's name matches regex. """ def __init__(self): super(AnyCallerMatches, self).__init__("_any_caller_matches") def invoke(self, name, nframes = 1): if nframes < 0: raise ValueError("nframes must be >= 0") frame = gdb.selected_frame() name_re = re.compile(name.string()) while nframes >= 0: if name_re.match(frame.name()) is not None: return True frame = frame.older() if frame is None: return False nframes = nframes - 1 return False CallerIs() CallerMatches() AnyCallerIs() AnyCallerMatches() PK!½ !qqpython/gdb/prompt.pynu„[µü¤# Extended prompt utilities. # Copyright (C) 2011-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ Extended prompt library functions.""" import gdb import os def _prompt_pwd(ignore): "The current working directory." return os.getcwd() def _prompt_object_attr(func, what, attr, nattr): """Internal worker for fetching GDB attributes.""" if attr is None: attr = nattr try: obj = func() except gdb.error: return '' % what if hasattr(obj, attr): result = getattr(obj, attr) if callable(result): result = result() return result else: return '' % (attr, what) def _prompt_frame(attr): "The selected frame; an argument names a frame parameter." return _prompt_object_attr(gdb.selected_frame, 'frame', attr, 'name') def _prompt_thread(attr): "The selected thread; an argument names a thread parameter." return _prompt_object_attr(gdb.selected_thread, 'thread', attr, 'num') def _prompt_version(attr): "The version of GDB." return gdb.VERSION def _prompt_esc(attr): "The ESC character." return '\033' def _prompt_bs(attr): "A backslash." return '\\' def _prompt_n(attr): "A newline." return '\n' def _prompt_r(attr): "A carriage return." return '\r' def _prompt_param(attr): "A parameter's value; the argument names the parameter." return gdb.parameter(attr) def _prompt_noprint_begin(attr): "Begins a sequence of non-printing characters." return '\001' def _prompt_noprint_end(attr): "Ends a sequence of non-printing characters." return '\002' prompt_substitutions = { 'e': _prompt_esc, '\\': _prompt_bs, 'n': _prompt_n, 'r': _prompt_r, 'v': _prompt_version, 'w': _prompt_pwd, 'f': _prompt_frame, 't': _prompt_thread, 'p': _prompt_param, '[': _prompt_noprint_begin, ']': _prompt_noprint_end } def prompt_help(): """Generate help dynamically from the __doc__ strings of attribute functions.""" result = '' keys = sorted (prompt_substitutions.keys()) for key in keys: result += ' \\%s\t%s\n' % (key, prompt_substitutions[key].__doc__) result += """ A substitution can be used in a simple form, like "\\f". An argument can also be passed to it, like "\\f{name}". The meaning of the argument depends on the particular substitution.""" return result def substitute_prompt(prompt): "Perform substitutions on PROMPT." result = '' plen = len(prompt) i = 0 while i < plen: if prompt[i] == '\\': i = i + 1 if i >= plen: break cmdch = prompt[i] if cmdch in prompt_substitutions: cmd = prompt_substitutions[cmdch] if i + 1 < plen and prompt[i + 1] == '{': j = i + 1 while j < plen and prompt[j] != '}': j = j + 1 # Just ignore formatting errors. if j >= plen or prompt[j] != '}': arg = None else: arg = prompt[i + 2 : j] i = j else: arg = None result += str(cmd(arg)) else: # Unrecognized escapes are turned into the escaped # character itself. result += prompt[i] else: result += prompt[i] i = i + 1 return result PK!ijDýA A python/gdb/unwinder.pynu„[µü¤# Copyright (C) 2015-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Unwinder class and register_unwinder function.""" import gdb class Unwinder(object): """Base class (or a template) for frame unwinders written in Python. An unwinder has a single method __call__ and the attributes described below. Attributes: name: The name of the unwinder. enabled: A boolean indicating whether the unwinder is enabled. """ def __init__(self, name): """Constructor. Args: name: An identifying name for the unwinder. """ self.name = name self.enabled = True def __call__(self, pending_frame): """GDB calls this method to unwind a frame. Arguments: pending_frame: gdb.PendingFrame instance. Returns: gdb.UnwindInfo instance. """ raise NotImplementedError("Unwinder __call__.") def register_unwinder(locus, unwinder, replace=False): """Register unwinder in given locus. The unwinder is prepended to the locus's unwinders list. Unwinder name should be unique. Arguments: locus: Either an objfile, progspace, or None (in which case the unwinder is registered globally). unwinder: An object of a gdb.Unwinder subclass replace: If True, replaces existing unwinder with the same name. Otherwise, raises exception if unwinder with the same name already exists. Returns: Nothing. Raises: RuntimeError: Unwinder name is not unique TypeError: Bad locus type """ if locus is None: if gdb.parameter("verbose"): gdb.write("Registering global %s unwinder ...\n" % unwinder.name) locus = gdb elif isinstance(locus, gdb.Objfile) or isinstance(locus, gdb.Progspace): if gdb.parameter("verbose"): gdb.write("Registering %s unwinder for %s ...\n" % (unwinder.name, locus.filename)) else: raise TypeError("locus should be gdb.Objfile or gdb.Progspace or None") i = 0 for needle in locus.frame_unwinders: if needle.name == unwinder.name: if replace: del locus.frame_unwinders[i] else: raise RuntimeError("Unwinder %s already exists." % unwinder.name) i += 1 locus.frame_unwinders.insert(0, unwinder) gdb.invalidate_cached_frames() PK!m«^%¡*¡*python/gdb/printing.pynu„[µü¤# Pretty-printer utilities. # Copyright (C) 2010-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Utilities for working with pretty-printers.""" import gdb import gdb.types import re import sys if sys.version_info[0] > 2: # Python 3 removed basestring and long basestring = str long = int class PrettyPrinter(object): """A basic pretty-printer. Attributes: name: A unique string among all printers for the context in which it is defined (objfile, progspace, or global(gdb)), and should meaningfully describe what can be pretty-printed. E.g., "StringPiece" or "protobufs". subprinters: An iterable object with each element having a `name' attribute, and, potentially, "enabled" attribute. Or this is None if there are no subprinters. enabled: A boolean indicating if the printer is enabled. Subprinters are for situations where "one" pretty-printer is actually a collection of several printers. E.g., The libstdc++ pretty-printer has a pretty-printer for each of several different types, based on regexps. """ # While one might want to push subprinters into the subclass, it's # present here to formalize such support to simplify # commands/pretty_printers.py. def __init__(self, name, subprinters=None): self.name = name self.subprinters = subprinters self.enabled = True def __call__(self, val): # The subclass must define this. raise NotImplementedError("PrettyPrinter __call__") class SubPrettyPrinter(object): """Baseclass for sub-pretty-printers. Sub-pretty-printers needn't use this, but it formalizes what's needed. Attributes: name: The name of the subprinter. enabled: A boolean indicating if the subprinter is enabled. """ def __init__(self, name): self.name = name self.enabled = True def register_pretty_printer(obj, printer, replace=False): """Register pretty-printer PRINTER with OBJ. The printer is added to the front of the search list, thus one can override an existing printer if one needs to. Use a different name when overriding an existing printer, otherwise an exception will be raised; multiple printers with the same name are disallowed. Arguments: obj: Either an objfile, progspace, or None (in which case the printer is registered globally). printer: Either a function of one argument (old way) or any object which has attributes: name, enabled, __call__. replace: If True replace any existing copy of the printer. Otherwise if the printer already exists raise an exception. Returns: Nothing. Raises: TypeError: A problem with the type of the printer. ValueError: The printer's name contains a semicolon ";". RuntimeError: A printer with the same name is already registered. If the caller wants the printer to be listable and disableable, it must follow the PrettyPrinter API. This applies to the old way (functions) too. If printer is an object, __call__ is a method of two arguments: self, and the value to be pretty-printed. See PrettyPrinter. """ # Watch for both __name__ and name. # Functions get the former for free, but we don't want to use an # attribute named __foo__ for pretty-printers-as-objects. # If printer has both, we use `name'. if not hasattr(printer, "__name__") and not hasattr(printer, "name"): raise TypeError("printer missing attribute: name") if hasattr(printer, "name") and not hasattr(printer, "enabled"): raise TypeError("printer missing attribute: enabled") if not hasattr(printer, "__call__"): raise TypeError("printer missing attribute: __call__") if hasattr(printer, "name"): name = printer.name else: name = printer.__name__ if obj is None or obj is gdb: if gdb.parameter("verbose"): gdb.write("Registering global %s pretty-printer ...\n" % name) obj = gdb else: if gdb.parameter("verbose"): gdb.write("Registering %s pretty-printer for %s ...\n" % ( name, obj.filename)) # Printers implemented as functions are old-style. In order to not risk # breaking anything we do not check __name__ here. if hasattr(printer, "name"): if not isinstance(printer.name, basestring): raise TypeError("printer name is not a string") # If printer provides a name, make sure it doesn't contain ";". # Semicolon is used by the info/enable/disable pretty-printer commands # to delimit subprinters. if printer.name.find(";") >= 0: raise ValueError("semicolon ';' in printer name") # Also make sure the name is unique. # Alas, we can't do the same for functions and __name__, they could # all have a canonical name like "lookup_function". # PERF: gdb records printers in a list, making this inefficient. i = 0 for p in obj.pretty_printers: if hasattr(p, "name") and p.name == printer.name: if replace: del obj.pretty_printers[i] break else: raise RuntimeError("pretty-printer already registered: %s" % printer.name) i = i + 1 obj.pretty_printers.insert(0, printer) class RegexpCollectionPrettyPrinter(PrettyPrinter): """Class for implementing a collection of regular-expression based pretty-printers. Intended usage: pretty_printer = RegexpCollectionPrettyPrinter("my_library") pretty_printer.add_printer("myclass1", "^myclass1$", MyClass1Printer) ... pretty_printer.add_printer("myclassN", "^myclassN$", MyClassNPrinter) register_pretty_printer(obj, pretty_printer) """ class RegexpSubprinter(SubPrettyPrinter): def __init__(self, name, regexp, gen_printer): super(RegexpCollectionPrettyPrinter.RegexpSubprinter, self).__init__(name) self.regexp = regexp self.gen_printer = gen_printer self.compiled_re = re.compile(regexp) def __init__(self, name): super(RegexpCollectionPrettyPrinter, self).__init__(name, []) def add_printer(self, name, regexp, gen_printer): """Add a printer to the list. The printer is added to the end of the list. Arguments: name: The name of the subprinter. regexp: The regular expression, as a string. gen_printer: A function/method that given a value returns an object to pretty-print it. Returns: Nothing. """ # NOTE: A previous version made the name of each printer the regexp. # That makes it awkward to pass to the enable/disable commands (it's # cumbersome to make a regexp of a regexp). So now the name is a # separate parameter. self.subprinters.append(self.RegexpSubprinter(name, regexp, gen_printer)) def __call__(self, val): """Lookup the pretty-printer for the provided value.""" # Get the type name. typename = gdb.types.get_basic_type(val.type).tag if not typename: typename = val.type.name if not typename: return None # Iterate over table of type regexps to determine # if a printer is registered for that type. # Return an instantiation of the printer if found. for printer in self.subprinters: if printer.enabled and printer.compiled_re.search(typename): return printer.gen_printer(val) # Cannot find a pretty printer. Return None. return None # A helper class for printing enum types. This class is instantiated # with a list of enumerators to print a particular Value. class _EnumInstance: def __init__(self, enumerators, val): self.enumerators = enumerators self.val = val def to_string(self): flag_list = [] v = long(self.val) any_found = False for (e_name, e_value) in self.enumerators: if v & e_value != 0: flag_list.append(e_name) v = v & ~e_value any_found = True if not any_found or v != 0: # Leftover value. flag_list.append('' % v) return "0x%x [%s]" % (int(self.val), " | ".join(flag_list)) class FlagEnumerationPrinter(PrettyPrinter): """A pretty-printer which can be used to print a flag-style enumeration. A flag-style enumeration is one where the enumerators are or'd together to create values. The new printer will print these symbolically using '|' notation. The printer must be registered manually. This printer is most useful when an enum is flag-like, but has some overlap. GDB's built-in printing will not handle this case, but this printer will attempt to.""" def __init__(self, enum_type): super(FlagEnumerationPrinter, self).__init__(enum_type) self.initialized = False def __call__(self, val): if not self.initialized: self.initialized = True flags = gdb.lookup_type(self.name) self.enumerators = [] for field in flags.fields(): self.enumerators.append((field.name, field.enumval)) # Sorting the enumerators by value usually does the right # thing. self.enumerators.sort(key = lambda x: x[1]) if self.enabled: return _EnumInstance(self.enumerators, val) else: return None # Builtin pretty-printers. # The set is defined as empty, and files in printing/*.py add their printers # to this with add_builtin_pretty_printer. _builtin_pretty_printers = RegexpCollectionPrettyPrinter("builtin") register_pretty_printer(None, _builtin_pretty_printers) # Add a builtin pretty-printer. def add_builtin_pretty_printer(name, regexp, printer): _builtin_pretty_printers.add_printer(name, regexp, printer) PK!ÇÍŒ¼´´python/gdb/printer/__init__.pynu„[µü¤# Copyright (C) 2014-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PK!Áx+Ëââ%python/gdb/printer/bound_registers.pynu„[µü¤# Pretty-printers for bounds registers. # Copyright (C) 2013-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys import gdb.printing if sys.version_info[0] > 2: # Python 3 removed basestring and long basestring = str long = int class MpxBound128Printer: """Adds size field to a mpx __gdb_builtin_type_bound128 type.""" def __init__ (self, val): self.val = val def to_string (self): upper = self.val["ubound"] lower = self.val["lbound"] size = (long) ((upper) - (lower)) if size > -1: size = size + 1 result = '{lbound = %s, ubound = %s} : size %s' % (lower, upper, size) return result gdb.printing.add_builtin_pretty_printer ('mpx_bound128', '^__gdb_builtin_type_bound128', MpxBound128Printer) PK!$mÐbiipython/gdb/command/explore.pynu„[µü¤# GDB 'explore' command. # Copyright (C) 2012-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Implementation of the GDB 'explore' command using the GDB Python API.""" import gdb import sys if sys.version_info[0] > 2: # Python 3 renamed raw_input to input raw_input = input class Explorer(object): """Internal class which invokes other explorers.""" # This map is filled by the Explorer.init_env() function type_code_to_explorer_map = { } _SCALAR_TYPE_LIST = ( gdb.TYPE_CODE_CHAR, gdb.TYPE_CODE_INT, gdb.TYPE_CODE_BOOL, gdb.TYPE_CODE_FLT, gdb.TYPE_CODE_VOID, gdb.TYPE_CODE_ENUM, ) @staticmethod def guard_expr(expr): length = len(expr) guard = False if expr[0] == '(' and expr[length-1] == ')': pass else: i = 0 while i < length: c = expr[i] if (c == '_' or ('a' <= c and c <= 'z') or ('A' <= c and c <= 'Z') or ('0' <= c and c <= '9')): pass else: guard = True break i += 1 if guard: return "(" + expr + ")" else: return expr @staticmethod def explore_expr(expr, value, is_child): """Main function to explore an expression value. Arguments: expr: The expression string that is being explored. value: The gdb.Value value of the expression. is_child: Boolean value to indicate if the expression is a child. An expression is a child if it is derived from the main expression entered by the user. For example, if the user entered an expression which evaluates to a struct, then when exploring the fields of the struct, is_child is set to True internally. Returns: No return value. """ type_code = value.type.code if type_code in Explorer.type_code_to_explorer_map: explorer_class = Explorer.type_code_to_explorer_map[type_code] while explorer_class.explore_expr(expr, value, is_child): pass else: print ("Explorer for type '%s' not yet available.\n" % str(value.type)) @staticmethod def explore_type(name, datatype, is_child): """Main function to explore a data type. Arguments: name: The string representing the path to the data type being explored. datatype: The gdb.Type value of the data type being explored. is_child: Boolean value to indicate if the name is a child. A name is a child if it is derived from the main name entered by the user. For example, if the user entered the name of struct type, then when exploring the fields of the struct, is_child is set to True internally. Returns: No return value. """ type_code = datatype.code if type_code in Explorer.type_code_to_explorer_map: explorer_class = Explorer.type_code_to_explorer_map[type_code] while explorer_class.explore_type(name, datatype, is_child): pass else: print ("Explorer for type '%s' not yet available.\n" % str(datatype)) @staticmethod def init_env(): """Initializes the Explorer environment. This function should be invoked before starting any exploration. If invoked before an exploration, it need not be invoked for subsequent explorations. """ Explorer.type_code_to_explorer_map = { gdb.TYPE_CODE_CHAR : ScalarExplorer, gdb.TYPE_CODE_INT : ScalarExplorer, gdb.TYPE_CODE_BOOL : ScalarExplorer, gdb.TYPE_CODE_FLT : ScalarExplorer, gdb.TYPE_CODE_VOID : ScalarExplorer, gdb.TYPE_CODE_ENUM : ScalarExplorer, gdb.TYPE_CODE_STRUCT : CompoundExplorer, gdb.TYPE_CODE_UNION : CompoundExplorer, gdb.TYPE_CODE_PTR : PointerExplorer, gdb.TYPE_CODE_REF : ReferenceExplorer, gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer, gdb.TYPE_CODE_TYPEDEF : TypedefExplorer, gdb.TYPE_CODE_ARRAY : ArrayExplorer } @staticmethod def is_scalar_type(type): """Checks whether a type is a scalar type. A type is a scalar type of its type is gdb.TYPE_CODE_CHAR or gdb.TYPE_CODE_INT or gdb.TYPE_CODE_BOOL or gdb.TYPE_CODE_FLT or gdb.TYPE_CODE_VOID or gdb.TYPE_CODE_ENUM. Arguments: type: The type to be checked. Returns: 'True' if 'type' is a scalar type. 'False' otherwise. """ return type.code in Explorer._SCALAR_TYPE_LIST @staticmethod def return_to_parent_value(): """A utility function which prints that the current exploration session is returning to the parent value. Useful when exploring values. """ print ("\nReturning to parent value...\n") @staticmethod def return_to_parent_value_prompt(): """A utility function which prompts the user to press the 'enter' key so that the exploration session can shift back to the parent value. Useful when exploring values. """ raw_input("\nPress enter to return to parent value: ") @staticmethod def return_to_enclosing_type(): """A utility function which prints that the current exploration session is returning to the enclosing type. Useful when exploring types. """ print ("\nReturning to enclosing type...\n") @staticmethod def return_to_enclosing_type_prompt(): """A utility function which prompts the user to press the 'enter' key so that the exploration session can shift back to the enclosing type. Useful when exploring types. """ raw_input("\nPress enter to return to enclosing type: ") class ScalarExplorer(object): """Internal class used to explore scalar values.""" @staticmethod def explore_expr(expr, value, is_child): """Function to explore scalar values. See Explorer.explore_expr and Explorer.is_scalar_type for more information. """ print ("'%s' is a scalar value of type '%s'." % (expr, value.type)) print ("%s = %s" % (expr, str(value))) if is_child: Explorer.return_to_parent_value_prompt() Explorer.return_to_parent_value() return False @staticmethod def explore_type(name, datatype, is_child): """Function to explore scalar types. See Explorer.explore_type and Explorer.is_scalar_type for more information. """ if datatype.code == gdb.TYPE_CODE_ENUM: if is_child: print ("%s is of an enumerated type '%s'." % (name, str(datatype))) else: print ("'%s' is an enumerated type." % name) else: if is_child: print ("%s is of a scalar type '%s'." % (name, str(datatype))) else: print ("'%s' is a scalar type." % name) if is_child: Explorer.return_to_enclosing_type_prompt() Explorer.return_to_enclosing_type() return False class PointerExplorer(object): """Internal class used to explore pointer values.""" @staticmethod def explore_expr(expr, value, is_child): """Function to explore pointer values. See Explorer.explore_expr for more information. """ print ("'%s' is a pointer to a value of type '%s'" % (expr, str(value.type.target()))) option = raw_input("Continue exploring it as a pointer to a single " "value [y/n]: ") if option == "y": deref_value = None try: deref_value = value.dereference() str(deref_value) except gdb.MemoryError: print ("'%s' a pointer pointing to an invalid memory " "location." % expr) if is_child: Explorer.return_to_parent_value_prompt() return False Explorer.explore_expr("*%s" % Explorer.guard_expr(expr), deref_value, is_child) return False option = raw_input("Continue exploring it as a pointer to an " "array [y/n]: ") if option == "y": while True: index = 0 try: index = int(raw_input("Enter the index of the element you " "want to explore in '%s': " % expr)) except ValueError: break element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index) element = value[index] try: str(element) except gdb.MemoryError: print ("Cannot read value at index %d." % index) continue Explorer.explore_expr(element_expr, element, True) return False if is_child: Explorer.return_to_parent_value() return False @staticmethod def explore_type(name, datatype, is_child): """Function to explore pointer types. See Explorer.explore_type for more information. """ target_type = datatype.target() print ("\n%s is a pointer to a value of type '%s'." % (name, str(target_type))) Explorer.explore_type("the pointee type of %s" % name, target_type, is_child) return False class ReferenceExplorer(object): """Internal class used to explore reference (TYPE_CODE_REF) values.""" @staticmethod def explore_expr(expr, value, is_child): """Function to explore array values. See Explorer.explore_expr for more information. """ referenced_value = value.referenced_value() Explorer.explore_expr(expr, referenced_value, is_child) return False @staticmethod def explore_type(name, datatype, is_child): """Function to explore pointer types. See Explorer.explore_type for more information. """ target_type = datatype.target() Explorer.explore_type(name, target_type, is_child) return False class ArrayExplorer(object): """Internal class used to explore arrays.""" @staticmethod def explore_expr(expr, value, is_child): """Function to explore array values. See Explorer.explore_expr for more information. """ target_type = value.type.target() print ("'%s' is an array of '%s'." % (expr, str(target_type))) index = 0 try: index = int(raw_input("Enter the index of the element you want to " "explore in '%s': " % expr)) except ValueError: if is_child: Explorer.return_to_parent_value() return False element = None try: element = value[index] str(element) except gdb.MemoryError: print ("Cannot read value at index %d." % index) raw_input("Press enter to continue... ") return True Explorer.explore_expr("%s[%d]" % (Explorer.guard_expr(expr), index), element, True) return True @staticmethod def explore_type(name, datatype, is_child): """Function to explore array types. See Explorer.explore_type for more information. """ target_type = datatype.target() print ("%s is an array of '%s'." % (name, str(target_type))) Explorer.explore_type("the array element of %s" % name, target_type, is_child) return False class CompoundExplorer(object): """Internal class used to explore struct, classes and unions.""" @staticmethod def _print_fields(print_list): """Internal function which prints the fields of a struct/class/union. """ max_field_name_length = 0 for pair in print_list: if max_field_name_length < len(pair[0]): max_field_name_length = len(pair[0]) for pair in print_list: print (" %*s = %s" % (max_field_name_length, pair[0], pair[1])) @staticmethod def _get_real_field_count(fields): real_field_count = 0; for field in fields: if not field.artificial: real_field_count = real_field_count + 1 return real_field_count @staticmethod def explore_expr(expr, value, is_child): """Function to explore structs/classes and union values. See Explorer.explore_expr for more information. """ datatype = value.type type_code = datatype.code fields = datatype.fields() if type_code == gdb.TYPE_CODE_STRUCT: type_desc = "struct/class" else: type_desc = "union" if CompoundExplorer._get_real_field_count(fields) == 0: print ("The value of '%s' is a %s of type '%s' with no fields." % (expr, type_desc, str(value.type))) if is_child: Explorer.return_to_parent_value_prompt() return False print ("The value of '%s' is a %s of type '%s' with the following " "fields:\n" % (expr, type_desc, str(value.type))) has_explorable_fields = False choice_to_compound_field_map = { } current_choice = 0 print_list = [ ] for field in fields: if field.artificial: continue field_full_name = Explorer.guard_expr(expr) + "." + field.name if field.is_base_class: field_value = value.cast(field.type) else: field_value = value[field.name] literal_value = "" if type_code == gdb.TYPE_CODE_UNION: literal_value = ("" % (current_choice, str(field.type))) has_explorable_fields = True else: if Explorer.is_scalar_type(field.type): literal_value = ("%s .. (Value of type '%s')" % (str(field_value), str(field.type))) else: if field.is_base_class: field_desc = "base class" else: field_desc = "field" literal_value = ("" % (current_choice, field_desc, str(field.type))) has_explorable_fields = True choice_to_compound_field_map[str(current_choice)] = ( field_full_name, field_value) current_choice = current_choice + 1 print_list.append((field.name, literal_value)) CompoundExplorer._print_fields(print_list) print ("") if has_explorable_fields: choice = raw_input("Enter the field number of choice: ") if choice in choice_to_compound_field_map: Explorer.explore_expr(choice_to_compound_field_map[choice][0], choice_to_compound_field_map[choice][1], True) return True else: if is_child: Explorer.return_to_parent_value() else: if is_child: Explorer.return_to_parent_value_prompt() return False @staticmethod def explore_type(name, datatype, is_child): """Function to explore struct/class and union types. See Explorer.explore_type for more information. """ type_code = datatype.code type_desc = "" if type_code == gdb.TYPE_CODE_STRUCT: type_desc = "struct/class" else: type_desc = "union" fields = datatype.fields() if CompoundExplorer._get_real_field_count(fields) == 0: if is_child: print ("%s is a %s of type '%s' with no fields." % (name, type_desc, str(datatype))) Explorer.return_to_enclosing_type_prompt() else: print ("'%s' is a %s with no fields." % (name, type_desc)) return False if is_child: print ("%s is a %s of type '%s' " "with the following fields:\n" % (name, type_desc, str(datatype))) else: print ("'%s' is a %s with the following " "fields:\n" % (name, type_desc)) has_explorable_fields = False current_choice = 0 choice_to_compound_field_map = { } print_list = [ ] for field in fields: if field.artificial: continue if field.is_base_class: field_desc = "base class" else: field_desc = "field" rhs = ("" % (current_choice, field_desc, str(field.type))) print_list.append((field.name, rhs)) choice_to_compound_field_map[str(current_choice)] = ( field.name, field.type, field_desc) current_choice = current_choice + 1 CompoundExplorer._print_fields(print_list) print ("") if len(choice_to_compound_field_map) > 0: choice = raw_input("Enter the field number of choice: ") if choice in choice_to_compound_field_map: if is_child: new_name = ("%s '%s' of %s" % (choice_to_compound_field_map[choice][2], choice_to_compound_field_map[choice][0], name)) else: new_name = ("%s '%s' of '%s'" % (choice_to_compound_field_map[choice][2], choice_to_compound_field_map[choice][0], name)) Explorer.explore_type(new_name, choice_to_compound_field_map[choice][1], True) return True else: if is_child: Explorer.return_to_enclosing_type() else: if is_child: Explorer.return_to_enclosing_type_prompt() return False class TypedefExplorer(object): """Internal class used to explore values whose type is a typedef.""" @staticmethod def explore_expr(expr, value, is_child): """Function to explore typedef values. See Explorer.explore_expr for more information. """ actual_type = value.type.strip_typedefs() print ("The value of '%s' is of type '%s' " "which is a typedef of type '%s'" % (expr, str(value.type), str(actual_type))) Explorer.explore_expr(expr, value.cast(actual_type), is_child) return False @staticmethod def explore_type(name, datatype, is_child): """Function to explore typedef types. See Explorer.explore_type for more information. """ actual_type = datatype.strip_typedefs() if is_child: print ("The type of %s is a typedef of type '%s'." % (name, str(actual_type))) else: print ("The type '%s' is a typedef of type '%s'." % (name, str(actual_type))) Explorer.explore_type(name, actual_type, is_child) return False class ExploreUtils(object): """Internal class which provides utilities for the main command classes.""" @staticmethod def check_args(name, arg_str): """Utility to check if adequate number of arguments are passed to an explore command. Arguments: name: The name of the explore command. arg_str: The argument string passed to the explore command. Returns: True if adequate arguments are passed, false otherwise. Raises: gdb.GdbError if adequate arguments are not passed. """ if len(arg_str) < 1: raise gdb.GdbError("ERROR: '%s' requires an argument." % name) return False else: return True @staticmethod def get_type_from_str(type_str): """A utility function to deduce the gdb.Type value from a string representing the type. Arguments: type_str: The type string from which the gdb.Type value should be deduced. Returns: The deduced gdb.Type value if possible, None otherwise. """ try: # Assume the current language to be C/C++ and make a try. return gdb.parse_and_eval("(%s *)0" % type_str).type.target() except RuntimeError: # If assumption of current language to be C/C++ was wrong, then # lookup the type using the API. try: return gdb.lookup_type(type_str) except RuntimeError: return None @staticmethod def get_value_from_str(value_str): """A utility function to deduce the gdb.Value value from a string representing the value. Arguments: value_str: The value string from which the gdb.Value value should be deduced. Returns: The deduced gdb.Value value if possible, None otherwise. """ try: return gdb.parse_and_eval(value_str) except RuntimeError: return None class ExploreCommand(gdb.Command): """Explore a value or a type valid in the current context. Usage: explore ARG - ARG is either a valid expression or a type name. - At any stage of exploration, hit the return key (instead of a choice, if any) to return to the enclosing type or value. """ def __init__(self): super(ExploreCommand, self).__init__(name = "explore", command_class = gdb.COMMAND_DATA, prefix = True) def invoke(self, arg_str, from_tty): if ExploreUtils.check_args("explore", arg_str) == False: return # Check if it is a value value = ExploreUtils.get_value_from_str(arg_str) if value is not None: Explorer.explore_expr(arg_str, value, False) return # If it is not a value, check if it is a type datatype = ExploreUtils.get_type_from_str(arg_str) if datatype is not None: Explorer.explore_type(arg_str, datatype, False) return # If it is neither a value nor a type, raise an error. raise gdb.GdbError( ("'%s' neither evaluates to a value nor is a type " "in the current context." % arg_str)) class ExploreValueCommand(gdb.Command): """Explore value of an expression valid in the current context. Usage: explore value ARG - ARG is a valid expression. - At any stage of exploration, hit the return key (instead of a choice, if any) to return to the enclosing value. """ def __init__(self): super(ExploreValueCommand, self).__init__( name = "explore value", command_class = gdb.COMMAND_DATA) def invoke(self, arg_str, from_tty): if ExploreUtils.check_args("explore value", arg_str) == False: return value = ExploreUtils.get_value_from_str(arg_str) if value is None: raise gdb.GdbError( (" '%s' does not evaluate to a value in the current " "context." % arg_str)) return Explorer.explore_expr(arg_str, value, False) class ExploreTypeCommand(gdb.Command): """Explore a type or the type of an expression valid in the current context. Usage: explore type ARG - ARG is a valid expression or a type name. - At any stage of exploration, hit the return key (instead of a choice, if any) to return to the enclosing type. """ def __init__(self): super(ExploreTypeCommand, self).__init__( name = "explore type", command_class = gdb.COMMAND_DATA) def invoke(self, arg_str, from_tty): if ExploreUtils.check_args("explore type", arg_str) == False: return datatype = ExploreUtils.get_type_from_str(arg_str) if datatype is not None: Explorer.explore_type(arg_str, datatype, False) return value = ExploreUtils.get_value_from_str(arg_str) if value is not None: print ("'%s' is of type '%s'." % (arg_str, str(value.type))) Explorer.explore_type(str(value.type), value.type, False) return raise gdb.GdbError(("'%s' is not a type or value in the current " "context." % arg_str)) Explorer.init_env() ExploreCommand() ExploreValueCommand() ExploreTypeCommand() PK! >xж¶python/gdb/command/__init__.pynu„[µü¤# Copyright (C) 2010-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . PK!¨ÄÅŠ8Š8%python/gdb/command/pretty_printers.pynu„[µü¤# Pretty-printer commands. # Copyright (C) 2010-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """GDB commands for working with pretty-printers.""" import copy import gdb import re def parse_printer_regexps(arg): """Internal utility to parse a pretty-printer command argv. Arguments: arg: The arguments to the command. The format is: [object-regexp [name-regexp]]. Individual printers in a collection are named as printer-name;subprinter-name. Returns: The result is a 3-tuple of compiled regular expressions, except that the resulting compiled subprinter regexp is None if not provided. Raises: SyntaxError: an error processing ARG """ argv = gdb.string_to_argv(arg); argc = len(argv) object_regexp = "" # match everything name_regexp = "" # match everything subname_regexp = None if argc > 3: raise SyntaxError("too many arguments") if argc >= 1: object_regexp = argv[0] if argc >= 2: name_subname = argv[1].split(";", 1) name_regexp = name_subname[0] if len(name_subname) == 2: subname_regexp = name_subname[1] # That re.compile raises SyntaxError was determined empirically. # We catch it and reraise it to provide a slightly more useful # error message for the user. try: object_re = re.compile(object_regexp) except SyntaxError: raise SyntaxError("invalid object regexp: %s" % object_regexp) try: name_re = re.compile (name_regexp) except SyntaxError: raise SyntaxError("invalid name regexp: %s" % name_regexp) if subname_regexp is not None: try: subname_re = re.compile(subname_regexp) except SyntaxError: raise SyntaxError("invalid subname regexp: %s" % subname_regexp) else: subname_re = None return(object_re, name_re, subname_re) def printer_enabled_p(printer): """Internal utility to see if printer (or subprinter) is enabled.""" if hasattr(printer, "enabled"): return printer.enabled else: return True class InfoPrettyPrinter(gdb.Command): """GDB command to list all registered pretty-printers. Usage: info pretty-printer [object-regexp [name-regexp]] OBJECT-REGEXP is a regular expression matching the objects to list. Objects are "global", the program space's file, and the objfiles within that program space. NAME-REGEXP matches the name of the pretty-printer. Individual printers in a collection are named as printer-name;subprinter-name. """ def __init__ (self): super(InfoPrettyPrinter, self).__init__("info pretty-printer", gdb.COMMAND_DATA) @staticmethod def enabled_string(printer): """Return "" if PRINTER is enabled, otherwise " [disabled]".""" if printer_enabled_p(printer): return "" else: return " [disabled]" @staticmethod def printer_name(printer): """Return the printer's name.""" if hasattr(printer, "name"): return printer.name if hasattr(printer, "__name__"): return printer.__name__ # This "shouldn't happen", but the public API allows for # direct additions to the pretty-printer list, and we shouldn't # crash because someone added a bogus printer. # Plus we want to give the user a way to list unknown printers. return "unknown" def list_pretty_printers(self, pretty_printers, name_re, subname_re): """Print a list of pretty-printers.""" # A potential enhancement is to provide an option to list printers in # "lookup order" (i.e. unsorted). sorted_pretty_printers = sorted (copy.copy(pretty_printers), key = self.printer_name) for printer in sorted_pretty_printers: name = self.printer_name(printer) enabled = self.enabled_string(printer) if name_re.match(name): print (" %s%s" % (name, enabled)) if (hasattr(printer, "subprinters") and printer.subprinters is not None): sorted_subprinters = sorted (copy.copy(printer.subprinters), key = self.printer_name) for subprinter in sorted_subprinters: if (not subname_re or subname_re.match(subprinter.name)): print (" %s%s" % (subprinter.name, self.enabled_string(subprinter))) def invoke1(self, title, printer_list, obj_name_to_match, object_re, name_re, subname_re): """Subroutine of invoke to simplify it.""" if printer_list and object_re.match(obj_name_to_match): print (title) self.list_pretty_printers(printer_list, name_re, subname_re) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" (object_re, name_re, subname_re) = parse_printer_regexps(arg) self.invoke1("global pretty-printers:", gdb.pretty_printers, "global", object_re, name_re, subname_re) cp = gdb.current_progspace() self.invoke1("progspace %s pretty-printers:" % cp.filename, cp.pretty_printers, "progspace", object_re, name_re, subname_re) for objfile in gdb.objfiles(): self.invoke1(" objfile %s pretty-printers:" % objfile.filename, objfile.pretty_printers, objfile.filename, object_re, name_re, subname_re) def count_enabled_printers(pretty_printers): """Return a 2-tuple of number of enabled and total printers.""" enabled = 0 total = 0 for printer in pretty_printers: if (hasattr(printer, "subprinters") and printer.subprinters is not None): if printer_enabled_p(printer): for subprinter in printer.subprinters: if printer_enabled_p(subprinter): enabled += 1 total += len(printer.subprinters) else: if printer_enabled_p(printer): enabled += 1 total += 1 return (enabled, total) def count_all_enabled_printers(): """Return a 2-tuble of the enabled state and total number of all printers. This includes subprinters. """ enabled_count = 0 total_count = 0 (t_enabled, t_total) = count_enabled_printers(gdb.pretty_printers) enabled_count += t_enabled total_count += t_total (t_enabled, t_total) = count_enabled_printers(gdb.current_progspace().pretty_printers) enabled_count += t_enabled total_count += t_total for objfile in gdb.objfiles(): (t_enabled, t_total) = count_enabled_printers(objfile.pretty_printers) enabled_count += t_enabled total_count += t_total return (enabled_count, total_count) def pluralize(text, n, suffix="s"): """Return TEXT pluralized if N != 1.""" if n != 1: return "%s%s" % (text, suffix) else: return text def show_pretty_printer_enabled_summary(): """Print the number of printers enabled/disabled. We count subprinters individually. """ (enabled_count, total_count) = count_all_enabled_printers() print ("%d of %d printers enabled" % (enabled_count, total_count)) def do_enable_pretty_printer_1 (pretty_printers, name_re, subname_re, flag): """Worker for enabling/disabling pretty-printers. Arguments: pretty_printers: list of pretty-printers name_re: regular-expression object to select printers subname_re: regular expression object to select subprinters or None if all are affected flag: True for Enable, False for Disable Returns: The number of printers affected. This is just for informational purposes for the user. """ total = 0 for printer in pretty_printers: if (hasattr(printer, "name") and name_re.match(printer.name) or hasattr(printer, "__name__") and name_re.match(printer.__name__)): if (hasattr(printer, "subprinters") and printer.subprinters is not None): if not subname_re: # Only record printers that change state. if printer_enabled_p(printer) != flag: for subprinter in printer.subprinters: if printer_enabled_p(subprinter): total += 1 # NOTE: We preserve individual subprinter settings. printer.enabled = flag else: # NOTE: Whether this actually disables the subprinter # depends on whether the printer's lookup function supports # the "enable" API. We can only assume it does. for subprinter in printer.subprinters: if subname_re.match(subprinter.name): # Only record printers that change state. if (printer_enabled_p(printer) and printer_enabled_p(subprinter) != flag): total += 1 subprinter.enabled = flag else: # This printer has no subprinters. # If the user does "disable pretty-printer .* .* foo" # should we disable printers that don't have subprinters? # How do we apply "foo" in this context? Since there is no # "foo" subprinter it feels like we should skip this printer. # There's still the issue of how to handle # "disable pretty-printer .* .* .*", and every other variation # that can match everything. For now punt and only support # "disable pretty-printer .* .*" (i.e. subname is elided) # to disable everything. if not subname_re: # Only record printers that change state. if printer_enabled_p(printer) != flag: total += 1 printer.enabled = flag return total def do_enable_pretty_printer (arg, flag): """Internal worker for enabling/disabling pretty-printers.""" (object_re, name_re, subname_re) = parse_printer_regexps(arg) total = 0 if object_re.match("global"): total += do_enable_pretty_printer_1(gdb.pretty_printers, name_re, subname_re, flag) cp = gdb.current_progspace() if object_re.match("progspace"): total += do_enable_pretty_printer_1(cp.pretty_printers, name_re, subname_re, flag) for objfile in gdb.objfiles(): if object_re.match(objfile.filename): total += do_enable_pretty_printer_1(objfile.pretty_printers, name_re, subname_re, flag) if flag: state = "enabled" else: state = "disabled" print ("%d %s %s" % (total, pluralize("printer", total), state)) # Print the total list of printers currently enabled/disabled. # This is to further assist the user in determining whether the result # is expected. Since we use regexps to select it's useful. show_pretty_printer_enabled_summary() # Enable/Disable one or more pretty-printers. # # This is intended for use when a broken pretty-printer is shipped/installed # and the user wants to disable that printer without disabling all the other # printers. # # A useful addition would be -v (verbose) to show each printer affected. class EnablePrettyPrinter (gdb.Command): """GDB command to enable the specified pretty-printer. Usage: enable pretty-printer [object-regexp [name-regexp]] OBJECT-REGEXP is a regular expression matching the objects to examine. Objects are "global", the program space's file, and the objfiles within that program space. NAME-REGEXP matches the name of the pretty-printer. Individual printers in a collection are named as printer-name;subprinter-name. """ def __init__(self): super(EnablePrettyPrinter, self).__init__("enable pretty-printer", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" do_enable_pretty_printer(arg, True) class DisablePrettyPrinter (gdb.Command): """GDB command to disable the specified pretty-printer. Usage: disable pretty-printer [object-regexp [name-regexp]] OBJECT-REGEXP is a regular expression matching the objects to examine. Objects are "global", the program space's file, and the objfiles within that program space. NAME-REGEXP matches the name of the pretty-printer. Individual printers in a collection are named as printer-name;subprinter-name. """ def __init__(self): super(DisablePrettyPrinter, self).__init__("disable pretty-printer", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" do_enable_pretty_printer(arg, False) def register_pretty_printer_commands(): """Call from a top level script to install the pretty-printer commands.""" InfoPrettyPrinter() EnablePrettyPrinter() DisablePrettyPrinter() register_pretty_printer_commands() PK!Ǩ'öpython/gdb/command/prompt.pynu„[µü¤# Extended prompt. # Copyright (C) 2011-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """GDB command for working with extended prompts.""" import gdb import gdb.prompt class _ExtendedPrompt(gdb.Parameter): """Set the extended prompt. Usage: set extended-prompt VALUE Substitutions are applied to VALUE to compute the real prompt. The currently defined substitutions are: """ # Add the prompt library's dynamically generated help to the # __doc__ string. __doc__ = __doc__ + gdb.prompt.prompt_help() set_doc = "Set the extended prompt." show_doc = "Show the extended prompt." def __init__(self): super(_ExtendedPrompt, self).__init__("extended-prompt", gdb.COMMAND_SUPPORT, gdb.PARAM_STRING_NOESCAPE) self.value = '' self.hook_set = False def get_show_string (self, pvalue): if self.value is not '': return "The extended prompt is: " + self.value else: return "The extended prompt is not set." def get_set_string (self): if self.hook_set == False: gdb.prompt_hook = self.before_prompt_hook self.hook_set = True return "" def before_prompt_hook(self, current): if self.value is not '': return gdb.prompt.substitute_prompt(self.value) else: return None _ExtendedPrompt() PK!¬žlyÏ'Ï'python/gdb/command/xmethods.pynu„[µü¤# Xmethod commands. # Copyright 2013-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb import re """GDB commands for working with xmethods.""" def validate_xm_regexp(part_name, regexp): try: return re.compile(regexp) except SyntaxError: raise SyntaxError("Invalid %s regexp: %s", part_name, regexp) def parse_xm_command_args(arg): """Parses the arguments passed to a xmethod command. Arguments: arg: The argument string passed to a xmethod command. Returns: A 3-tuple: (, , ) """ argv = gdb.string_to_argv(arg) argc = len(argv) if argc > 2: raise SyntaxError("Too many arguments to command.") locus_regexp = "" matcher_name_regexp = "" xm_name_regexp = None if argc >= 1: locus_regexp = argv[0] if argc == 2: parts = argv[1].split(";", 1) matcher_name_regexp = parts[0] if len(parts) > 1: xm_name_regexp = parts[1] if xm_name_regexp: name_re = validate_xm_regexp("xmethod name", xm_name_regexp) else: name_re = None return (validate_xm_regexp("locus", locus_regexp), validate_xm_regexp("matcher name", matcher_name_regexp), name_re) def get_global_method_matchers(locus_re, matcher_re): """Returns a dict of matching globally registered xmethods. Arguments: locus_re: Even though only globally registered xmethods are looked up, they will be looked up only if 'global' matches LOCUS_RE. matcher_re: The regular expression matching the names of xmethods. Returns: A dict of matching globally registered xmethod matchers. The only key in the dict will be 'global'. """ locus_str = "global" xm_dict = { locus_str: [] } if locus_re.match("global"): xm_dict[locus_str].extend( [m for m in gdb.xmethods if matcher_re.match(m.name)]) return xm_dict def get_method_matchers_in_loci(loci, locus_re, matcher_re): """Returns a dict of matching registered xmethods in the LOCI. Arguments: loci: The list of loci to lookup matching xmethods in. locus_re: If a locus is an objfile, then xmethod matchers will be looked up in it only if its filename matches the regular expression LOCUS_RE. If a locus is the current progspace, then xmethod matchers will be looked up in it only if the string "progspace" matches LOCUS_RE. matcher_re: The regular expression to match the xmethod matcher names. Returns: A dict of matching xmethod matchers. The keys of the dict are the filenames of the loci the xmethod matchers belong to. """ xm_dict = {} for locus in loci: if isinstance(locus, gdb.Progspace): if not locus_re.match('progspace'): continue locus_type = "progspace" else: if not locus_re.match(locus.filename): continue locus_type = "objfile" locus_str = "%s %s" % (locus_type, locus.filename) xm_dict[locus_str] = [ m for m in locus.xmethods if matcher_re.match(m.name)] return xm_dict def print_xm_info(xm_dict, name_re): """Print a dictionary of xmethods.""" def get_status_string(m): if not m.enabled: return " [disabled]" else: return "" if not xm_dict: return for locus_str in xm_dict: if not xm_dict[locus_str]: continue print ("Xmethods in %s:" % locus_str) for matcher in xm_dict[locus_str]: print (" %s%s" % (matcher.name, get_status_string(matcher))) if not matcher.methods: continue for m in matcher.methods: if name_re is None or name_re.match(m.name): print (" %s%s" % (m.name, get_status_string(m))) def set_xm_status1(xm_dict, name_re, status): """Set the status (enabled/disabled) of a dictionary of xmethods.""" for locus_str, matchers in xm_dict.items(): for matcher in matchers: if not name_re: # If the name regex is missing, then set the status of the # matcher and move on. matcher.enabled = status continue if not matcher.methods: # The methods attribute could be None. Move on. continue for m in matcher.methods: if name_re.match(m.name): m.enabled = status def set_xm_status(arg, status): """Set the status (enabled/disabled) of xmethods matching ARG. This is a helper function for enable/disable commands. ARG is the argument string passed to the commands. """ locus_re, matcher_re, name_re = parse_xm_command_args(arg) set_xm_status1(get_global_method_matchers(locus_re, matcher_re), name_re, status) set_xm_status1( get_method_matchers_in_loci( [gdb.current_progspace()], locus_re, matcher_re), name_re, status) set_xm_status1( get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re), name_re, status) class InfoXMethod(gdb.Command): """GDB command to list registered xmethod matchers. Usage: info xmethod [locus-regexp [name-regexp]] LOCUS-REGEXP is a regular expression matching the location of the xmethod matchers. If it is omitted, all registered xmethod matchers from all loci are listed. A locus could be 'global', a regular expression matching the current program space's filename, or a regular expression matching filenames of objfiles. Locus could be 'progspace' to specify that only xmethods from the current progspace should be listed. NAME-REGEXP is a regular expression matching the names of xmethod matchers. If this omitted for a specified locus, then all registered xmethods in the locus are listed. To list only a certain xmethods managed by a single matcher, the name regexp can be specified as matcher-name-regexp;xmethod-name-regexp. """ def __init__(self): super(InfoXMethod, self).__init__("info xmethod", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): locus_re, matcher_re, name_re = parse_xm_command_args(arg) print_xm_info(get_global_method_matchers(locus_re, matcher_re), name_re) print_xm_info( get_method_matchers_in_loci( [gdb.current_progspace()], locus_re, matcher_re), name_re) print_xm_info( get_method_matchers_in_loci(gdb.objfiles(), locus_re, matcher_re), name_re) class EnableXMethod(gdb.Command): """GDB command to enable a specified (group of) xmethod(s). Usage: enable xmethod [locus-regexp [name-regexp]] LOCUS-REGEXP is a regular expression matching the location of the xmethod matchers. If it is omitted, all registered xmethods matchers from all loci are enabled. A locus could be 'global', a regular expression matching the current program space's filename, or a regular expression matching filenames of objfiles. Locus could be 'progspace' to specify that only xmethods from the current progspace should be enabled. NAME-REGEXP is a regular expression matching the names of xmethods within a given locus. If this omitted for a specified locus, then all registered xmethod matchers in the locus are enabled. To enable only a certain xmethods managed by a single matcher, the name regexp can be specified as matcher-name-regexp;xmethod-name-regexp. """ def __init__(self): super(EnableXMethod, self).__init__("enable xmethod", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): set_xm_status(arg, True) class DisableXMethod(gdb.Command): """GDB command to disable a specified (group of) xmethod(s). Usage: disable xmethod [locus-regexp [name-regexp]] LOCUS-REGEXP is a regular expression matching the location of the xmethod matchers. If it is omitted, all registered xmethod matchers from all loci are disabled. A locus could be 'global', a regular expression matching the current program space's filename, or a regular expression filenames of objfiles. Locus could be 'progspace' to specify that only xmethods from the current progspace should be disabled. NAME-REGEXP is a regular expression matching the names of xmethods within a given locus. If this omitted for a specified locus, then all registered xmethod matchers in the locus are disabled. To disable only a certain xmethods managed by a single matcher, the name regexp can be specified as matcher-name-regexp;xmethod-name-regexp. """ def __init__(self): super(DisableXMethod, self).__init__("disable xmethod", gdb.COMMAND_DATA) def invoke(self, arg, from_tty): set_xm_status(arg, False) def register_xmethod_commands(): """Installs the xmethod commands.""" InfoXMethod() EnableXMethod() DisableXMethod() register_xmethod_commands() PK!_.ëLL#python/gdb/command/type_printers.pynu„[µü¤# Type printer commands. # Copyright (C) 2010-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import copy import gdb """GDB commands for working with type-printers.""" class InfoTypePrinter(gdb.Command): """GDB command to list all registered type-printers. Usage: info type-printers """ def __init__ (self): super(InfoTypePrinter, self).__init__("info type-printers", gdb.COMMAND_DATA) def list_type_printers(self, type_printers): """Print a list of type printers.""" # A potential enhancement is to provide an option to list printers in # "lookup order" (i.e. unsorted). sorted_type_printers = sorted (copy.copy(type_printers), key = lambda x: x.name) for printer in sorted_type_printers: if printer.enabled: enabled = '' else: enabled = " [disabled]" print (" %s%s" % (printer.name, enabled)) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" sep = '' for objfile in gdb.objfiles(): if objfile.type_printers: print ("%sType printers for %s:" % (sep, objfile.filename)) self.list_type_printers(objfile.type_printers) sep = '\n' if gdb.current_progspace().type_printers: print ("%sType printers for program space:" % sep) self.list_type_printers(gdb.current_progspace().type_printers) sep = '\n' if gdb.type_printers: print ("%sGlobal type printers:" % sep) self.list_type_printers(gdb.type_printers) class _EnableOrDisableCommand(gdb.Command): def __init__(self, setting, name): super(_EnableOrDisableCommand, self).__init__(name, gdb.COMMAND_DATA) self.setting = setting def set_some(self, name, printers): result = False for p in printers: if name == p.name: p.enabled = self.setting result = True return result def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" for name in arg.split(): ok = False for objfile in gdb.objfiles(): if self.set_some(name, objfile.type_printers): ok = True if self.set_some(name, gdb.current_progspace().type_printers): ok = True if self.set_some(name, gdb.type_printers): ok = True if not ok: print ("No type printer named '%s'" % name) def add_some(self, result, word, printers): for p in printers: if p.name.startswith(word): result.append(p.name) def complete(self, text, word): result = [] for objfile in gdb.objfiles(): self.add_some(result, word, objfile.type_printers) self.add_some(result, word, gdb.current_progspace().type_printers) self.add_some(result, word, gdb.type_printers) return result class EnableTypePrinter(_EnableOrDisableCommand): """GDB command to enable the specified type printer. Usage: enable type-printer NAME NAME is the name of the type-printer. """ def __init__(self): super(EnableTypePrinter, self).__init__(True, "enable type-printer") class DisableTypePrinter(_EnableOrDisableCommand): """GDB command to disable the specified type-printer. Usage: disable type-printer NAME NAME is the name of the type-printer. """ def __init__(self): super(DisableTypePrinter, self).__init__(False, "disable type-printer") InfoTypePrinter() EnableTypePrinter() DisableTypePrinter() PK!Xsîšææpython/gdb/command/unwinders.pynu„[µü¤# Unwinder commands. # Copyright 2015-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb import re def validate_regexp(exp, idstring): try: return re.compile(exp) except SyntaxError: raise SyntaxError("Invalid %s regexp: %s." % (idstring, exp)) def parse_unwinder_command_args(arg): """Internal utility to parse unwinder command argv. Arguments: arg: The arguments to the command. The format is: [locus-regexp [name-regexp]] Returns: A 2-tuple of compiled regular expressions. Raises: SyntaxError: an error processing ARG """ argv = gdb.string_to_argv(arg) argc = len(argv) if argc > 2: raise SyntaxError("Too many arguments.") locus_regexp = "" name_regexp = "" if argc >= 1: locus_regexp = argv[0] if argc >= 2: name_regexp = argv[1] return (validate_regexp(locus_regexp, "locus"), validate_regexp(name_regexp, "unwinder")) class InfoUnwinder(gdb.Command): """GDB command to list unwinders. Usage: info unwinder [locus-regexp [name-regexp]] LOCUS-REGEXP is a regular expression matching the location of the unwinder. If it is omitted, all registered unwinders from all loci are listed. A locus can be 'global', 'progspace' to list the unwinders from the current progspace, or a regular expression matching filenames of objfiles. NAME-REGEXP is a regular expression to filter unwinder names. If this omitted for a specified locus, then all registered unwinders in the locus are listed. """ def __init__(self): super(InfoUnwinder, self).__init__("info unwinder", gdb.COMMAND_STACK) def list_unwinders(self, title, unwinders, name_re): """Lists the unwinders whose name matches regexp. Arguments: title: The line to print before the list. unwinders: The list of the unwinders. name_re: unwinder name filter. """ if not unwinders: return print(title) for unwinder in unwinders: if name_re.match(unwinder.name): print(" %s%s" % (unwinder.name, "" if unwinder.enabled else " [disabled]")) def invoke(self, arg, from_tty): locus_re, name_re = parse_unwinder_command_args(arg) if locus_re.match("global"): self.list_unwinders("Global:", gdb.frame_unwinders, name_re) if locus_re.match("progspace"): cp = gdb.current_progspace() self.list_unwinders("Progspace %s:" % cp.filename, cp.frame_unwinders, name_re) for objfile in gdb.objfiles(): if locus_re.match(objfile.filename): self.list_unwinders("Objfile %s:" % objfile.filename, objfile.frame_unwinders, name_re) def do_enable_unwinder1(unwinders, name_re, flag): """Enable/disable unwinders whose names match given regex. Arguments: unwinders: The list of unwinders. name_re: Unwinder name filter. flag: Enable/disable. Returns: The number of unwinders affected. """ total = 0 for unwinder in unwinders: if name_re.match(unwinder.name): unwinder.enabled = flag total += 1 return total def do_enable_unwinder(arg, flag): """Enable/disable unwinder(s).""" (locus_re, name_re) = parse_unwinder_command_args(arg) total = 0 if locus_re.match("global"): total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag) if locus_re.match("progspace"): total += do_enable_unwinder1(gdb.current_progspace().frame_unwinders, name_re, flag) for objfile in gdb.objfiles(): if locus_re.match(objfile.filename): total += do_enable_unwinder1(objfile.frame_unwinders, name_re, flag) if total > 0: gdb.invalidate_cached_frames() print("%d unwinder%s %s" % (total, "" if total == 1 else "s", "enabled" if flag else "disabled")) class EnableUnwinder(gdb.Command): """GDB command to enable unwinders. Usage: enable unwinder [locus-regexp [name-regexp]] LOCUS-REGEXP is a regular expression specifying the unwinders to enable. It can 'global', 'progspace', or the name of an objfile within that progspace. NAME_REGEXP is a regular expression to filter unwinder names. If this omitted for a specified locus, then all registered unwinders in the locus are affected. """ def __init__(self): super(EnableUnwinder, self).__init__("enable unwinder", gdb.COMMAND_STACK) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" do_enable_unwinder(arg, True) class DisableUnwinder(gdb.Command): """GDB command to disable the specified unwinder. Usage: disable unwinder [locus-regexp [name-regexp]] LOCUS-REGEXP is a regular expression specifying the unwinders to disable. It can 'global', 'progspace', or the name of an objfile within that progspace. NAME_REGEXP is a regular expression to filter unwinder names. If this omitted for a specified locus, then all registered unwinders in the locus are affected. """ def __init__(self): super(DisableUnwinder, self).__init__("disable unwinder", gdb.COMMAND_STACK) def invoke(self, arg, from_tty): """GDB calls this to perform the command.""" do_enable_unwinder(arg, False) def register_unwinder_commands(): """Installs the unwinder commands.""" InfoUnwinder() EnableUnwinder() DisableUnwinder() register_unwinder_commands() PK!Y¢�eRR#python/gdb/command/ignore_errors.pynu„[µü¤# Ignore errors in user commands. # Copyright (C) 2008 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import gdb class IgnoreErrorsCommand (gdb.Command): """Execute a single command, ignoring all errors. Only one-line commands are supported. This is primarily useful in scripts.""" def __init__ (self): super (IgnoreErrorsCommand, self).__init__ ("ignore-errors", gdb.COMMAND_OBSCURE, # FIXME... gdb.COMPLETE_COMMAND) def invoke (self, arg, from_tty): try: gdb.execute (arg, from_tty) except: pass IgnoreErrorsCommand () PK!` ÔÜ?Ü?#python/gdb/command/frame_filters.pynu„[µü¤# Frame-filter commands. # Copyright (C) 2013-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """GDB commands for working with frame-filters.""" import sys import gdb import copy from gdb.FrameIterator import FrameIterator from gdb.FrameDecorator import FrameDecorator import gdb.frames import itertools # GDB Commands. class SetFilterPrefixCmd(gdb.Command): """Prefix command for 'set' frame-filter related operations.""" def __init__(self): super(SetFilterPrefixCmd, self).__init__("set frame-filter", gdb.COMMAND_OBSCURE, gdb.COMPLETE_NONE, True) class ShowFilterPrefixCmd(gdb.Command): """Prefix command for 'show' frame-filter related operations.""" def __init__(self): super(ShowFilterPrefixCmd, self).__init__("show frame-filter", gdb.COMMAND_OBSCURE, gdb.COMPLETE_NONE, True) class InfoFrameFilter(gdb.Command): """List all registered Python frame-filters. Usage: info frame-filters """ def __init__(self): super(InfoFrameFilter, self).__init__("info frame-filter", gdb.COMMAND_DATA) @staticmethod def enabled_string(state): """Return "Yes" if filter is enabled, otherwise "No".""" if state: return "Yes" else: return "No" def print_list(self, title, frame_filters, blank_line): sorted_frame_filters = sorted(frame_filters.items(), key=lambda i: gdb.frames.get_priority(i[1]), reverse=True) if len(sorted_frame_filters) == 0: return 0 print(title) print(" Priority Enabled Name") for frame_filter in sorted_frame_filters: name = frame_filter[0] try: priority = '{:<8}'.format( str(gdb.frames.get_priority(frame_filter[1]))) enabled = '{:<7}'.format( self.enabled_string(gdb.frames.get_enabled(frame_filter[1]))) print(" %s %s %s" % (priority, enabled, name)) except Exception: e = sys.exc_info()[1] print(" Error printing filter '"+name+"': "+str(e)) if blank_line: print("") return 1 def invoke(self, arg, from_tty): any_printed = self.print_list("global frame-filters:", gdb.frame_filters, True) cp = gdb.current_progspace() any_printed += self.print_list("progspace %s frame-filters:" % cp.filename, cp.frame_filters, True) for objfile in gdb.objfiles(): any_printed += self.print_list("objfile %s frame-filters:" % objfile.filename, objfile.frame_filters, False) if any_printed == 0: print ("No frame filters.") # Internal enable/disable functions. def _enable_parse_arg(cmd_name, arg): """ Internal worker function to take an argument from enable/disable and return a tuple of arguments. Arguments: cmd_name: Name of the command invoking this function. args: The argument as a string. Returns: A tuple containing the dictionary, and the argument, or just the dictionary in the case of "all". """ argv = gdb.string_to_argv(arg); argc = len(argv) if argv[0] == "all" and argc > 1: raise gdb.GdbError(cmd_name + ": with 'all' " \ "you may not specify a filter.") else: if argv[0] != "all" and argc != 2: raise gdb.GdbError(cmd_name + " takes exactly two arguments.") return argv def _do_enable_frame_filter(command_tuple, flag): """Worker for enabling/disabling frame_filters. Arguments: command_type: A tuple with the first element being the frame filter dictionary, and the second being the frame filter name. flag: True for Enable, False for Disable. """ list_op = command_tuple[0] op_list = gdb.frames.return_list(list_op) if list_op == "all": for item in op_list: gdb.frames.set_enabled(item, flag) else: frame_filter = command_tuple[1] try: ff = op_list[frame_filter] except KeyError: msg = "frame-filter '" + str(frame_filter) + "' not found." raise gdb.GdbError(msg) gdb.frames.set_enabled(ff, flag) def _complete_frame_filter_list(text, word, all_flag): """Worker for frame filter dictionary name completion. Arguments: text: The full text of the command line. word: The most recent word of the command line. all_flag: Whether to include the word "all" in completion. Returns: A list of suggested frame filter dictionary name completions from text/word analysis. This list can be empty when there are no suggestions for completion. """ if all_flag == True: filter_locations = ["all", "global", "progspace"] else: filter_locations = ["global", "progspace"] for objfile in gdb.objfiles(): filter_locations.append(objfile.filename) # If the user just asked for completions with no completion # hints, just return all the frame filter dictionaries we know # about. if (text == ""): return filter_locations # Otherwise filter on what we know. flist = filter(lambda x,y=text:x.startswith(y), filter_locations) # If we only have one completion, complete it and return it. if len(flist) == 1: flist[0] = flist[0][len(text)-len(word):] # Otherwise, return an empty list, or a list of frame filter # dictionaries that the previous filter operation returned. return flist def _complete_frame_filter_name(word, printer_dict): """Worker for frame filter name completion. Arguments: word: The most recent word of the command line. printer_dict: The frame filter dictionary to search for frame filter name completions. Returns: A list of suggested frame filter name completions from word analysis of the frame filter dictionary. This list can be empty when there are no suggestions for completion. """ printer_keys = printer_dict.keys() if (word == ""): return printer_keys flist = filter(lambda x,y=word:x.startswith(y), printer_keys) return flist class EnableFrameFilter(gdb.Command): """GDB command to disable the specified frame-filter. Usage: enable frame-filter enable DICTIONARY [NAME] DICTIONARY is the name of the frame filter dictionary on which to operate. If dictionary is set to "all", perform operations on all dictionaries. Named dictionaries are: "global" for the global frame filter dictionary, "progspace" for the program space's frame filter dictionary. If either all, or the two named dictionaries are not specified, the dictionary name is assumed to be the name of the object-file name. NAME matches the name of the frame-filter to operate on. If DICTIONARY is "all", NAME is ignored. """ def __init__(self): super(EnableFrameFilter, self).__init__("enable frame-filter", gdb.COMMAND_DATA) def complete(self, text, word): """Completion function for both frame filter dictionary, and frame filter name.""" if text.count(" ") == 0: return _complete_frame_filter_list(text, word, True) else: printer_list = gdb.frames.return_list(text.split()[0].rstrip()) return _complete_frame_filter_name(word, printer_list) def invoke(self, arg, from_tty): command_tuple = _enable_parse_arg("enable frame-filter", arg) _do_enable_frame_filter(command_tuple, True) class DisableFrameFilter(gdb.Command): """GDB command to disable the specified frame-filter. Usage: disable frame-filter disable DICTIONARY [NAME] DICTIONARY is the name of the frame filter dictionary on which to operate. If dictionary is set to "all", perform operations on all dictionaries. Named dictionaries are: "global" for the global frame filter dictionary, "progspace" for the program space's frame filter dictionary. If either all, or the two named dictionaries are not specified, the dictionary name is assumed to be the name of the object-file name. NAME matches the name of the frame-filter to operate on. If DICTIONARY is "all", NAME is ignored. """ def __init__(self): super(DisableFrameFilter, self).__init__("disable frame-filter", gdb.COMMAND_DATA) def complete(self, text, word): """Completion function for both frame filter dictionary, and frame filter name.""" if text.count(" ") == 0: return _complete_frame_filter_list(text, word, True) else: printer_list = gdb.frames.return_list(text.split()[0].rstrip()) return _complete_frame_filter_name(word, printer_list) def invoke(self, arg, from_tty): command_tuple = _enable_parse_arg("disable frame-filter", arg) _do_enable_frame_filter(command_tuple, False) class SetFrameFilterPriority(gdb.Command): """GDB command to set the priority of the specified frame-filter. Usage: set frame-filter priority DICTIONARY NAME PRIORITY DICTIONARY is the name of the frame filter dictionary on which to operate. Named dictionaries are: "global" for the global frame filter dictionary, "progspace" for the program space's framefilter dictionary. If either of these two are not specified, the dictionary name is assumed to be the name of the object-file name. NAME matches the name of the frame filter to operate on. PRIORITY is the an integer to assign the new priority to the frame filter. """ def __init__(self): super(SetFrameFilterPriority, self).__init__("set frame-filter " \ "priority", gdb.COMMAND_DATA) def _parse_pri_arg(self, arg): """Internal worker to parse a priority from a tuple. Arguments: arg: Tuple which contains the arguments from the command. Returns: A tuple containing the dictionary, name and priority from the arguments. Raises: gdb.GdbError: An error parsing the arguments. """ argv = gdb.string_to_argv(arg); argc = len(argv) if argc != 3: print("set frame-filter priority " \ "takes exactly three arguments.") return None return argv def _set_filter_priority(self, command_tuple): """Internal worker for setting priority of frame-filters, by parsing a tuple and calling _set_priority with the parsed tuple. Arguments: command_tuple: Tuple which contains the arguments from the command. """ list_op = command_tuple[0] frame_filter = command_tuple[1] # GDB returns arguments as a string, so convert priority to # a number. priority = int(command_tuple[2]) op_list = gdb.frames.return_list(list_op) try: ff = op_list[frame_filter] except KeyError: msg = "frame-filter '" + str(frame_filter) + "' not found." raise gdb.GdbError(msg) gdb.frames.set_priority(ff, priority) def complete(self, text, word): """Completion function for both frame filter dictionary, and frame filter name.""" if text.count(" ") == 0: return _complete_frame_filter_list(text, word, False) else: printer_list = gdb.frames.return_list(text.split()[0].rstrip()) return _complete_frame_filter_name(word, printer_list) def invoke(self, arg, from_tty): command_tuple = self._parse_pri_arg(arg) if command_tuple != None: self._set_filter_priority(command_tuple) class ShowFrameFilterPriority(gdb.Command): """GDB command to show the priority of the specified frame-filter. Usage: show frame-filter priority DICTIONARY NAME DICTIONARY is the name of the frame filter dictionary on which to operate. Named dictionaries are: "global" for the global frame filter dictionary, "progspace" for the program space's framefilter dictionary. If either of these two are not specified, the dictionary name is assumed to be the name of the object-file name. NAME matches the name of the frame-filter to operate on. """ def __init__(self): super(ShowFrameFilterPriority, self).__init__("show frame-filter " \ "priority", gdb.COMMAND_DATA) def _parse_pri_arg(self, arg): """Internal worker to parse a dictionary and name from a tuple. Arguments: arg: Tuple which contains the arguments from the command. Returns: A tuple containing the dictionary, and frame filter name. Raises: gdb.GdbError: An error parsing the arguments. """ argv = gdb.string_to_argv(arg); argc = len(argv) if argc != 2: print("show frame-filter priority " \ "takes exactly two arguments.") return None return argv def get_filter_priority(self, frame_filters, name): """Worker for retrieving the priority of frame_filters. Arguments: frame_filters: Name of frame filter dictionary. name: object to select printers. Returns: The priority of the frame filter. Raises: gdb.GdbError: A frame filter cannot be found. """ op_list = gdb.frames.return_list(frame_filters) try: ff = op_list[name] except KeyError: msg = "frame-filter '" + str(name) + "' not found." raise gdb.GdbError(msg) return gdb.frames.get_priority(ff) def complete(self, text, word): """Completion function for both frame filter dictionary, and frame filter name.""" if text.count(" ") == 0: return _complete_frame_filter_list(text, word, False) else: printer_list = frame._return_list(text.split()[0].rstrip()) return _complete_frame_filter_name(word, printer_list) def invoke(self, arg, from_tty): command_tuple = self._parse_pri_arg(arg) if command_tuple == None: return filter_name = command_tuple[1] list_name = command_tuple[0] try: priority = self.get_filter_priority(list_name, filter_name); except Exception: e = sys.exc_info()[1] print("Error printing filter priority for '"+name+"':"+str(e)) else: print("Priority of filter '" + filter_name + "' in list '" \ + list_name + "' is: " + str(priority)) # Register commands SetFilterPrefixCmd() ShowFilterPrefixCmd() InfoFrameFilter() EnableFrameFilter() DisableFrameFilter() SetFrameFilterPriority() ShowFrameFilterPriority() PK!ýë"�E+E+python/gdb/xmethod.pynu„[µü¤# Python side of the support for xmethods. # Copyright (C) 2013-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Utilities for defining xmethods""" import gdb import re import sys if sys.version_info[0] > 2: # Python 3 removed basestring and long basestring = str long = int class XMethod(object): """Base class (or a template) for an xmethod description. Currently, the description requires only the 'name' and 'enabled' attributes. Description objects are managed by 'XMethodMatcher' objects (see below). Note that this is only a template for the interface of the XMethodMatcher.methods objects. One could use this class or choose to use an object which supports this exact same interface. Also, an XMethodMatcher can choose not use it 'methods' attribute. In such cases this class (or an equivalent) is not used. Attributes: name: The name of the xmethod. enabled: A boolean indicating if the xmethod is enabled. """ def __init__(self, name): self.name = name self.enabled = True class XMethodMatcher(object): """Abstract base class for matching an xmethod. When looking for xmethods, GDB invokes the `match' method of a registered xmethod matcher to match the object type and method name. The `match' method in concrete classes derived from this class should return an `XMethodWorker' object, or a list of `XMethodWorker' objects if there is a match (see below for 'XMethodWorker' class). Attributes: name: The name of the matcher. enabled: A boolean indicating if the matcher is enabled. methods: A sequence of objects of type 'XMethod', or objects which have at least the attributes of an 'XMethod' object. This list is used by the 'enable'/'disable'/'info' commands to enable/disable/list the xmethods registered with GDB. See the 'match' method below to know how this sequence is used. This attribute is None if the matcher chooses not have any xmethods managed by it. """ def __init__(self, name): """ Args: name: An identifying name for the xmethod or the group of xmethods returned by the `match' method. """ self.name = name self.enabled = True self.methods = None def match(self, class_type, method_name): """Match class type and method name. In derived classes, it should return an XMethodWorker object, or a sequence of 'XMethodWorker' objects. Only those xmethod workers whose corresponding 'XMethod' descriptor object is enabled should be returned. Args: class_type: The class type (gdb.Type object) to match. method_name: The name (string) of the method to match. """ raise NotImplementedError("XMethodMatcher match") class XMethodWorker(object): """Base class for all xmethod workers defined in Python. An xmethod worker is an object which matches the method arguments, and invokes the method when GDB wants it to. Internally, GDB first invokes the 'get_arg_types' method to perform overload resolution. If GDB selects to invoke this Python xmethod, then it invokes it via the overridden '__call__' method. The 'get_result_type' method is used to implement 'ptype' on the xmethod. Derived classes should override the 'get_arg_types', 'get_result_type' and '__call__' methods. """ def get_arg_types(self): """Return arguments types of an xmethod. A sequence of gdb.Type objects corresponding to the arguments of the xmethod are returned. If the xmethod takes no arguments, then 'None' or an empty sequence is returned. If the xmethod takes only a single argument, then a gdb.Type object or a sequence with a single gdb.Type element is returned. """ raise NotImplementedError("XMethodWorker get_arg_types") def get_result_type(self, *args): """Return the type of the result of the xmethod. Args: args: Arguments to the method. Each element of the tuple is a gdb.Value object. The first element is the 'this' pointer value. These are the same arguments passed to '__call__'. Returns: A gdb.Type object representing the type of the result of the xmethod. """ raise NotImplementedError("XMethodWorker get_result_type") def __call__(self, *args): """Invoke the xmethod. Args: args: Arguments to the method. Each element of the tuple is a gdb.Value object. The first element is the 'this' pointer value. Returns: A gdb.Value corresponding to the value returned by the xmethod. Returns 'None' if the method does not return anything. """ raise NotImplementedError("XMethodWorker __call__") class SimpleXMethodMatcher(XMethodMatcher): """A utility class to implement simple xmethod mathers and workers. See the __init__ method below for information on how instances of this class can be used. For simple classes and methods, one can choose to use this class. For complex xmethods, which need to replace/implement template methods on possibly template classes, one should implement their own xmethod matchers and workers. See py-xmethods.py in testsuite/gdb.python directory of the GDB source tree for examples. """ class SimpleXMethodWorker(XMethodWorker): def __init__(self, method_function, arg_types): self._arg_types = arg_types self._method_function = method_function def get_arg_types(self): return self._arg_types def __call__(self, *args): return self._method_function(*args) def __init__(self, name, class_matcher, method_matcher, method_function, *arg_types): """ Args: name: Name of the xmethod matcher. class_matcher: A regular expression used to match the name of the class whose method this xmethod is implementing/replacing. method_matcher: A regular expression used to match the name of the method this xmethod is implementing/replacing. method_function: A Python callable which would be called via the 'invoke' method of the worker returned by the objects of this class. This callable should accept the object (*this) as the first argument followed by the rest of the arguments to the method. All arguments to this function should be gdb.Value objects. arg_types: The gdb.Type objects corresponding to the arguments that this xmethod takes. It can be None, or an empty sequence, or a single gdb.Type object, or a sequence of gdb.Type objects. """ XMethodMatcher.__init__(self, name) assert callable(method_function), ( "The 'method_function' argument to 'SimpleXMethodMatcher' " "__init__ method should be a callable.") self._method_function = method_function self._class_matcher = class_matcher self._method_matcher = method_matcher self._arg_types = arg_types def match(self, class_type, method_name): cm = re.match(self._class_matcher, str(class_type.unqualified().tag)) mm = re.match(self._method_matcher, method_name) if cm and mm: return SimpleXMethodMatcher.SimpleXMethodWorker( self._method_function, self._arg_types) # A helper function for register_xmethod_matcher which returns an error # object if MATCHER is not having the requisite attributes in the proper # format. def _validate_xmethod_matcher(matcher): if not hasattr(matcher, "match"): return TypeError("Xmethod matcher is missing method: match") if not hasattr(matcher, "name"): return TypeError("Xmethod matcher is missing attribute: name") if not hasattr(matcher, "enabled"): return TypeError("Xmethod matcher is missing attribute: enabled") if not isinstance(matcher.name, basestring): return TypeError("Attribute 'name' of xmethod matcher is not a " "string") if matcher.name.find(";") >= 0: return ValueError("Xmethod matcher name cannot contain ';' in it") # A helper function for register_xmethod_matcher which looks up an # xmethod matcher with NAME in LOCUS. Returns the index of the xmethod # matcher in 'xmethods' sequence attribute of the LOCUS. If NAME is not # found in LOCUS, then -1 is returned. def _lookup_xmethod_matcher(locus, name): for i in range(0, len(locus.xmethods)): if locus.xmethods[i].name == name: return i return -1 def register_xmethod_matcher(locus, matcher, replace=False): """Registers a xmethod matcher MATCHER with a LOCUS. Arguments: locus: The locus in which the xmethods should be registered. It can be 'None' to indicate that the xmethods should be registered globally. Or, it could be a gdb.Objfile or a gdb.Progspace object in which the xmethods should be registered. matcher: The xmethod matcher to register with the LOCUS. It should be an instance of 'XMethodMatcher' class. replace: If True, replace any existing xmethod matcher with the same name in the locus. Otherwise, if a matcher with the same name exists in the locus, raise an exception. """ err = _validate_xmethod_matcher(matcher) if err: raise err if not locus: locus = gdb if locus == gdb: locus_name = "global" else: locus_name = locus.filename index = _lookup_xmethod_matcher(locus, matcher.name) if index >= 0: if replace: del locus.xmethods[index] else: raise RuntimeError("Xmethod matcher already registered with " "%s: %s" % (locus_name, matcher.name)) if gdb.parameter("verbose"): gdb.write("Registering xmethod matcher '%s' with %s' ...\n") locus.xmethods.insert(0, matcher) PK!$ô¼ÙÙLauto-load/usr/lib64/__pycache__/libstdc++.so.6.0.25-gdb.cpython-36.opt-1.pycnu„[µü¤3 @¨»jM ã@sddlZddlZddlZddlZdZdZejƒdk rìejjeƒZejjeƒZejj eegƒZ e ddkrxejj e ƒdZ ee e ƒd…Zee e ƒd…Zdej e ejej ƒƒZejƒjZejjejj eƒeeƒZeejkrìejjdeƒddlmZeejƒƒdS) éNz/usr/share/gcc-8/pythonz/usr/lib/../lib64éú/z..)Úregister_libstdcxx_printerséÿÿÿÿ)ÚsysZgdbÚosZos.pathZ pythondirZlibdirZcurrent_objfileÚpathÚnormpathÚ commonprefixÚprefixÚdirnameÚlenÚsepÚsplitZdotdotsÚfilenameZobjfileÚjoinZdir_ÚinsertZ libstdcxx.v6r©rrú>/usr/share/gdb/auto-load//usr/lib64/libstdc++.so.6.0.25-gdb.pyÚs(       PK!$ô¼ÙÙFauto-load/usr/lib64/__pycache__/libstdc++.so.6.0.25-gdb.cpython-36.pycnu„[µü¤3 @¨»jM ã@sddlZddlZddlZddlZdZdZejƒdk rìejjeƒZejjeƒZejj eegƒZ e ddkrxejj e ƒdZ ee e ƒd…Zee e ƒd…Zdej e ejej ƒƒZejƒjZejjejj eƒeeƒZeejkrìejjdeƒddlmZeejƒƒdS) éNz/usr/share/gcc-8/pythonz/usr/lib/../lib64éú/z..)Úregister_libstdcxx_printerséÿÿÿÿ)ÚsysZgdbÚosZos.pathZ pythondirZlibdirZcurrent_objfileÚpathÚnormpathÚ commonprefixÚprefixÚdirnameÚlenÚsepÚsplitZdotdotsÚfilenameZobjfileÚjoinZdir_ÚinsertZ libstdcxx.v6r©rrú>/usr/share/gdb/auto-load//usr/lib64/libstdc++.so.6.0.25-gdb.pyÚs(       PK!· Ÿ¢cc+auto-load/usr/lib64/libisl.so.15.1.1-gdb.pynu„[µü¤import gdb import re # GDB Pretty Printers for most isl objects class IslObjectPrinter: """Print an isl object""" def __init__ (self, val, type): self.val = val self.type = type def to_string (self): # Cast val to a void pointer to stop gdb using this pretty # printer for the pointer which would lead to an infinite loop. void_ptr = gdb.lookup_type('void').pointer() value = str(self.val.cast(void_ptr)) printer = gdb.parse_and_eval("isl_printer_to_str(isl_" + str(self.type) + "_get_ctx(" + value + "))") printer = gdb.parse_and_eval("isl_printer_print_" + str(self.type) + "(" + str(printer) + ", " + value + ")") string = gdb.parse_and_eval("(char*)isl_printer_get_str(" + str(printer) + ")") gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")") return string def display_hint (self): return 'string' class IslIntPrinter: """Print an isl_int """ def __init__ (self, val): self.val = val def to_string (self): # Cast val to a void pointer to stop gdb using this pretty # printer for the pointer which would lead to an infinite loop. void_ptr = gdb.lookup_type('void').pointer() value = str(self.val.cast(void_ptr)) context = gdb.parse_and_eval("isl_ctx_alloc()") printer = gdb.parse_and_eval("isl_printer_to_str(" + str(context) + ")") printer = gdb.parse_and_eval("isl_printer_print_isl_int(" + str(printer) + ", " + value + ")") string = gdb.parse_and_eval("(char*)isl_printer_get_str(" + str(printer) + ")") gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")") gdb.parse_and_eval("isl_ctx_free(" + str(context) + ")") return string def display_hint (self): return 'string' class IslPrintCommand (gdb.Command): """Print an isl value.""" def __init__ (self): super (IslPrintCommand, self).__init__ ("islprint", gdb.COMMAND_OBSCURE) def invoke (self, arg, from_tty): arg = gdb.parse_and_eval(arg); printer = str_lookup_function(arg) if printer == None: print "No isl printer for this type" return print printer.to_string() IslPrintCommand() def str_lookup_function (val): if val.type.code != gdb.TYPE_CODE_PTR: if str(val.type) == "isl_int": return IslIntPrinter(val) else: return None lookup_tag = val.type.target() regex = re.compile ("^isl_(.*)$") if lookup_tag == None: return None m = regex.match (str(lookup_tag)) if m: # Those types of printers defined in isl. if m.group(1) in ["basic_set", "set", "union_set", "basic_map", "map", "union_map", "qpolynomial", "pw_qpolynomial", "pw_qpolynomial_fold", "union_pw_qpolynomial", "union_pw_qpolynomial_fold"]: return IslObjectPrinter(val, m.group(1)) return None # Do not register the pretty printer. # gdb.current_objfile().pretty_printers.append(str_lookup_function) PK!· Ÿ¢cc+auto-load/usr/lib64/libisl.so.13.1.0-gdb.pynu„[µü¤import gdb import re # GDB Pretty Printers for most isl objects class IslObjectPrinter: """Print an isl object""" def __init__ (self, val, type): self.val = val self.type = type def to_string (self): # Cast val to a void pointer to stop gdb using this pretty # printer for the pointer which would lead to an infinite loop. void_ptr = gdb.lookup_type('void').pointer() value = str(self.val.cast(void_ptr)) printer = gdb.parse_and_eval("isl_printer_to_str(isl_" + str(self.type) + "_get_ctx(" + value + "))") printer = gdb.parse_and_eval("isl_printer_print_" + str(self.type) + "(" + str(printer) + ", " + value + ")") string = gdb.parse_and_eval("(char*)isl_printer_get_str(" + str(printer) + ")") gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")") return string def display_hint (self): return 'string' class IslIntPrinter: """Print an isl_int """ def __init__ (self, val): self.val = val def to_string (self): # Cast val to a void pointer to stop gdb using this pretty # printer for the pointer which would lead to an infinite loop. void_ptr = gdb.lookup_type('void').pointer() value = str(self.val.cast(void_ptr)) context = gdb.parse_and_eval("isl_ctx_alloc()") printer = gdb.parse_and_eval("isl_printer_to_str(" + str(context) + ")") printer = gdb.parse_and_eval("isl_printer_print_isl_int(" + str(printer) + ", " + value + ")") string = gdb.parse_and_eval("(char*)isl_printer_get_str(" + str(printer) + ")") gdb.parse_and_eval("isl_printer_free(" + str(printer) + ")") gdb.parse_and_eval("isl_ctx_free(" + str(context) + ")") return string def display_hint (self): return 'string' class IslPrintCommand (gdb.Command): """Print an isl value.""" def __init__ (self): super (IslPrintCommand, self).__init__ ("islprint", gdb.COMMAND_OBSCURE) def invoke (self, arg, from_tty): arg = gdb.parse_and_eval(arg); printer = str_lookup_function(arg) if printer == None: print "No isl printer for this type" return print printer.to_string() IslPrintCommand() def str_lookup_function (val): if val.type.code != gdb.TYPE_CODE_PTR: if str(val.type) == "isl_int": return IslIntPrinter(val) else: return None lookup_tag = val.type.target() regex = re.compile ("^isl_(.*)$") if lookup_tag == None: return None m = regex.match (str(lookup_tag)) if m: # Those types of printers defined in isl. if m.group(1) in ["basic_set", "set", "union_set", "basic_map", "map", "union_map", "qpolynomial", "pw_qpolynomial", "pw_qpolynomial_fold", "union_pw_qpolynomial", "union_pw_qpolynomial_fold"]: return IslObjectPrinter(val, m.group(1)) return None # Do not register the pretty printer. # gdb.current_objfile().pretty_printers.append(str_lookup_function) PK!I< aM M .auto-load/usr/lib64/libstdc++.so.6.0.25-gdb.pynu„[µü¤# -*- python -*- # Copyright (C) 2009-2018 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys import gdb import os import os.path pythondir = '/usr/share/gcc-8/python' libdir = '/usr/lib/../lib64' # This file might be loaded when there is no current objfile. This # can happen if the user loads it manually. In this case we don't # update sys.path; instead we just hope the user managed to do that # beforehand. if gdb.current_objfile () is not None: # Update module path. We want to find the relative path from libdir # to pythondir, and then we want to apply that relative path to the # directory holding the objfile with which this file is associated. # This preserves relocatability of the gcc tree. # Do a simple normalization that removes duplicate separators. pythondir = os.path.normpath (pythondir) libdir = os.path.normpath (libdir) prefix = os.path.commonprefix ([libdir, pythondir]) # In some bizarre configuration we might have found a match in the # middle of a directory name. if prefix[-1] != '/': prefix = os.path.dirname (prefix) + '/' # Strip off the prefix. pythondir = pythondir[len (prefix):] libdir = libdir[len (prefix):] # Compute the ".."s needed to get from libdir to the prefix. dotdots = ('..' + os.sep) * len (libdir.split (os.sep)) objfile = gdb.current_objfile ().filename dir_ = os.path.join (os.path.dirname (objfile), dotdots, pythondir) if not dir_ in sys.path: sys.path.insert(0, dir_) # Call a function as a plain import would not execute body of the included file # on repeated reloads of this object file. from libstdcxx.v6 import register_libstdcxx_printers register_libstdcxx_printers(gdb.current_objfile()) PK!auto-load/usr/libnuȯÝíPK!auto-load/usr/binnuȯÝíPK!auto-load/usr/lib64nuȯÝíPK!auto-load/usr/sbinnuȯÝíPK!/ÞL‰‰guile/gdb/experimental.gonu„[µü¤GOOF----LE-8-2.0q](4h›] gguile¤ ¤ gdefine-module*¤ ¤ ¤ ggdb¤ g experimental¤ ¤ gfilenameS¤ fgdb/experimental.scm¤ gimportsS¤ ¤  ¤  ¤ gset-current-module¤ ¤ ¤ g%with-gdb-output-to-port¤  ¤  ¤ gwith-gdb-output-to-port¤ gcall-with-deferred-observers¤ ¤ ¤ gmodule-export!¤ ¤ ¤ gcurrent-module¤ ¤ ¤ ¤ g%with-gdb-error-to-port¤ !  ¤ "  ¤ #gwith-gdb-error-to-port¤ $#¤ %gcall-with-output-string¤ &gwith-gdb-output-to-string¤ '&¤C5ho]4   54>"GR4hF]456>gfilenamefgdb/experimental.scmŒ  ŒŒ  C>"G"#R4$hF]456>gfilenamefgdb/experimental.scmŒ  ŒŒ  C>"G%h_]L6Wgp  gfilenamefgdb/experimental.scmŒ ! ŒŒ ! ŒŒ  ChÑ]O6Égthunk  gfilenamefgdb/experimental.scmŒ  ŒŒ ŒŒ  gnamegwith-gdb-output-to-stringŒg documentationf3Calls THUNK and returns all GDB output as a string.ŒC&R'hF]456>gfilenamefgdb/experimental.scmŒ  ŒŒ  C6ggm  (gfilenamefgdb/experimental.scmŒ   ŒŒ -  ŒŒ °  ŒŒ ¤  ŒŒ   C6PK!µ� Ž Ž guile/gdb/printing.gonu„[µü¤GOOF----LE-8-2.0v ]24h‹] gguile¤ ¤ gdefine-module*¤ ¤ ¤ ggdb¤ gprinting¤ ¤ gfilenameS¤ fgdb/printing.scm¤ gimportsS¤ ¤ gselectS¤ gpretty-printer?¤ gobjfile?¤ g progspace?¤ gpretty-printers¤ gset-pretty-printers!¤ gobjfile-pretty-printers¤ gset-objfile-pretty-printers!¤ gprogspace-pretty-printers¤ gset-progspace-pretty-printers!¤  ¤   ¤ gsupport¤ ¤ ¤ ¤ gset-current-module¤ ¤ ¤ g assert-type¤ !gSCM_ARG1¤ "gprepend-pretty-printer!¤ #fpretty-printer¤ $f#f, objfile, or progspace¤ %gcall-with-deferred-observers¤ &%¤ '%¤ (gmodule-export!¤ )(¤ *(¤ +gcurrent-module¤ ,+¤ -+¤ ."¤ /gappend-pretty-printer!¤ 0gappend!¤ 1/¤C5h0d]4   54>"G !"#$hxÁ]445>"G& 45Œ645$ 4 5Œ64 5$ 4 5Œ66¹gobj  wgmatcher  wgfilenamefgdb/printing.scmŒ  ŒŒ   ŒŒ   ŒŒ   ŒŒ   (ŒŒ   ŒŒ ( ŒŒ - ! -ŒŒ 2 ! ŒŒ 4 ! ŒŒ 5 " ŒŒ ? ŒŒ F $ ŒŒ M $ ŒŒ O # ŒŒ P % ŒŒ Z ŒŒ a ' ŒŒ h ' ŒŒ j & ŒŒ s ) &ŒŒ u * ŒŒ w ) ŒŒ  w gnamegprepend-pretty-printer!Œg documentationfnAdd MATCHER to the beginning of the pretty-printer list for OBJ. If OBJ is #f, add MATCHER to the global list.ŒC"R4'*-.hB]456:gfilenamefgdb/printing.scmŒ  ŒŒ  C>"G !/#0$h�ð]445>"G&445564 5$ 44 5564 5$ 445566ègobj  Œgmatcher  Œgfilenamefgdb/printing.scmŒ , ŒŒ  / ŒŒ  / ŒŒ  0 ŒŒ  0 'ŒŒ  / ŒŒ ( 1 ŒŒ + 2 ŒŒ . 2 (ŒŒ 7 2 :ŒŒ 9 2 ŒŒ ; 2 ŒŒ < 3 ŒŒ F 1 ŒŒ K 5 ŒŒ N 5 ŒŒ Y 5 5ŒŒ [ 5 ŒŒ ] 4 ŒŒ ^ 6 ŒŒ h 1 ŒŒ m 8 ŒŒ p 8 ŒŒ { 8 7ŒŒ } 8 ŒŒ  7 ŒŒ ˆ : &ŒŒ Š ; ŒŒ Œ : ŒŒ  Œ gnamegappend-pretty-printer!Œg documentationfhAdd MATCHER to the end of the pretty-printer list for OBJ. If OBJ is #f, add MATCHER to the global list.ŒC/R'*-1hB]456:gfilenamefgdb/printing.scmŒ , ŒŒ  C6\gm  (gfilenamefgdb/printing.scmŒ   ŒŒ ”  ŒŒ à , ŒŒ  , C6PK!½ºq ÉÉguile/gdb/support.scmnu„[µü¤;; Internal support routines. ;; ;; Copyright (C) 2014-2018 Free Software Foundation, Inc. ;; ;; This file is part of GDB. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . (define-module (gdb support)) ;; Symbolic values for the ARG parameter of assert-type. (define-public SCM_ARG1 1) (define-public SCM_ARG2 2) ;; Utility to check the type of an argument, akin to SCM_ASSERT_TYPE. (define-public (assert-type test-result arg pos func-name expecting) (if (not test-result) (scm-error 'wrong-type-arg func-name "Wrong type argument in position ~a (expecting ~a): ~s" (list pos expecting arg) (list arg)))) PK!-~[ë ë guile/gdb/types.gonu„[µü¤GOOF----LE-8-2.0Ó ]=4hõ] gguile¤ ¤ gdefine-module*¤ ¤ ¤ ggdb¤ gtypes¤ ¤ gfilenameS¤ f gdb/types.scm¤ gimportsS¤ ¤  ¤ giterator¤ ¤ ¤ gsupport¤ ¤ ¤  ¤ gset-current-module¤ ¤ ¤ gtype-has-field?¤ giterator-until¤ gfield-baseclass?¤ g field-type¤ gendS¤ gmake-field-iterator¤ g type-code¤ g TYPE_CODE_REF¤ g type-target¤ !gtype-strip-typedefs¤ "g assert-type¤ #gmemq¤ $gTYPE_CODE_STRUCT¤ %gTYPE_CODE_UNION¤ &gSCM_ARG1¤ 'gtype-has-field-deep?¤ (fstruct or union¤ )gcall-with-deferred-observers¤ *)¤ +)¤ ,gmodule-export!¤ -,¤ .,¤ /gcurrent-module¤ 0/¤ 1/¤ 2'¤ 3gTYPE_CODE_ENUM¤ 4gmake-enum-hashtable¤ 5fenum¤ 6gmake-hash-table¤ 7gfor-each¤ 8g hash-set!¤ 9g field-name¤ :g field-enumval¤ ;g type-fields¤ <4¤C5h a]4   54>"Gh ’]45$ L456CŠgfield  gfilenamef gdb/types.scmŒ # ŒŒ  $ #ŒŒ $ ŒŒ  % 1ŒŒ  % #ŒŒ   gnamegfind-in-baseclassŒCh0²] 4L5$C4LO455‚€Cªgtype  .gt .gfilenamef gdb/types.scmŒ " ŒŒ  - ŒŒ - ŒŒ  + ŒŒ ! , ŒŒ ) + ŒŒ , . ŒŒ - . ŒŒ  . gnameg search-classŒC !"#$%&'( hp�] HOQ4J5‘$ 4J5K"4J5K444J5 5J   >"GJ6ˆgtype  kg field-name  kg search-class   kgfilenamef gdb/types.scmŒ  ŒŒ  0 ŒŒ 0 ŒŒ $ 0 ŒŒ % 1 ŒŒ - 1 ŒŒ 2 2 ŒŒ : 2 ŒŒ ; 4 ŒŒ > 4 ŒŒ A 4 ŒŒ N 4 &ŒŒ P 4 ŒŒ V 5 ŒŒ X 5 3ŒŒ ] 4 ŒŒ k 7 ŒŒ  k gnamegtype-has-field-deep?Œg documentationfUReturn #t if the type, including baseclasses, has the specified field. Arguments: type: The type to examine. It must be a struct or union. field-name: The name of the field to look up. Returns: True if the field is present either in type_ or any baseclass. Raises: wrong-type-arg: The type is not a struct or union.ŒC'R4+.12h?]4567gfilenamef gdb/types.scmŒ  ŒŒ  C>"G"3&456789:hk]L45456cgenum  gfilenamef gdb/types.scmŒ J ŒŒ  K ŒŒ  K 2ŒŒ  K ŒŒ   C; hP] 445‘>"G454 O4 5>"GCg enum-type  Lghtab ) Lgfilenamef gdb/types.scmŒ 9 ŒŒ  G ŒŒ  G ŒŒ  G ŒŒ  H "ŒŒ  H 7ŒŒ  G ŒŒ % I ŒŒ ) I ŒŒ , J ŒŒ 6 L ŒŒ A J ŒŒ  L gnamegmake-enum-hashtableŒg documentationfReturn a hash table from a program's enum type. Elements in the hash table are fetched with hashq-ref. Arguments: enum-type: The enum to compute the hash table for. Returns: The hash table of the enum. Raises: wrong-type-arg: The type is not an enum.ŒC4R+.1<h?]4567gfilenamef gdb/types.scmŒ 9 ŒŒ  C6Ygm  (gfilenamef gdb/types.scmŒ   ŒŒ   ŒŒ « 9 ŒŒ   C6PK!ÚAR 4 4 guile/gdb/types.scmnu„[µü¤;; Type utilities. ;; Copyright (C) 2010-2018 Free Software Foundation, Inc. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . (define-module (gdb types) #:use-module (gdb) #:use-module (gdb iterator) #:use-module (gdb support)) (define-public (type-has-field-deep? type field-name) "Return #t if the type, including baseclasses, has the specified field. Arguments: type: The type to examine. It must be a struct or union. field-name: The name of the field to look up. Returns: True if the field is present either in type_ or any baseclass. Raises: wrong-type-arg: The type is not a struct or union." (define (search-class type) (let ((find-in-baseclass (lambda (field) (if (field-baseclass? field) (search-class (field-type field)) ;; Not a baseclass, search ends now. ;; Return #:end to end search. #:end)))) (let ((search-baseclasses (lambda (type) (iterator-until find-in-baseclass (make-field-iterator type))))) (or (type-has-field? type field-name) (not (eq? (search-baseclasses type) #:end)))))) (if (= (type-code type) TYPE_CODE_REF) (set! type (type-target type))) (set! type (type-strip-typedefs type)) (assert-type (memq (type-code type) (list TYPE_CODE_STRUCT TYPE_CODE_UNION)) type SCM_ARG1 'type-has-field-deep? "struct or union") (search-class type)) (define-public (make-enum-hashtable enum-type) "Return a hash table from a program's enum type. Elements in the hash table are fetched with hashq-ref. Arguments: enum-type: The enum to compute the hash table for. Returns: The hash table of the enum. Raises: wrong-type-arg: The type is not an enum." (assert-type (= (type-code enum-type) TYPE_CODE_ENUM) enum-type SCM_ARG1 'make-enum-hashtable "enum") (let ((htab (make-hash-table))) (for-each (lambda (enum) (hash-set! htab (field-name enum) (field-enumval enum))) (type-fields enum-type)) htab)) PK!.áæH¤¤guile/gdb/support.gonu„[µü¤GOOF----LE-8-2.0Œ] 4h] gguile¤ ¤ gdefine-module*¤ ¤ ¤ ggdb¤ gsupport¤ ¤ gfilenameS¤ fgdb/support.scm¤ gset-current-module¤  ¤  ¤ gSCM_ARG1¤ gcall-with-deferred-observers¤ ¤ ¤ gmodule-export!¤ ¤ ¤ gcurrent-module¤ ¤ ¤ ¤ gSCM_ARG2¤ ¤ g scm-error¤ gwrong-type-arg¤ f5Wrong type argument in position ~a (expecting ~a): ~s¤ g assert-type¤ ¤C5hÈj]4  54 >"G R4hA]4569gfilenamefgdb/support.scmŒ  ŒŒ  C>"G R4hA]4569gfilenamefgdb/support.scmŒ  ŒŒ  C>"Gh(ó]$C6ëg test-result  "garg  "gpos   "g func-name   "g expecting   "gfilenamefgdb/support.scmŒ  ŒŒ   ŒŒ   ŒŒ   ŒŒ  ŒŒ *ŒŒ "  ŒŒ  " gnameg assert-typeŒCRhA]4569gfilenamefgdb/support.scmŒ  ŒŒ  C6bgm $gfilenamefgdb/support.scmŒ   ŒŒ (  ŒŒ £  ŒŒ V  ŒŒ  à C6PK!(Jär» » guile/gdb/iterator.scmnu„[µü¤;; Iteration utilities. ;; Anything in this file can change or disappear. ;; ;; Copyright (C) 2014-2018 Free Software Foundation, Inc. ;; ;; This file is part of GDB. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . (define-module (gdb iterator) #:use-module (gdb) #:use-module (gdb support)) (define-public (make-list-iterator l) "Return a object for a list." (assert-type (list? l) l SCM_ARG1 'make-list-iterator "list") (let ((next! (lambda (iter) (let ((l (iterator-progress iter))) (if (eq? l '()) (end-of-iteration) (begin (set-iterator-progress! iter (cdr l)) (car l))))))) (make-iterator l l next!))) (define-public (iterator->list iter) "Return the elements of ITER as a list." (let loop ((iter iter) (result '())) (let ((next (iterator-next! iter))) (if (end-of-iteration? next) (reverse! result) (loop iter (cons next result)))))) (define-public (iterator-map proc iter) "Return a list of PROC applied to each element." (let loop ((proc proc) (iter iter) (result '())) (let ((next (iterator-next! iter))) (if (end-of-iteration? next) (reverse! result) (loop proc iter (cons (proc next) result)))))) (define-public (iterator-for-each proc iter) "Apply PROC to each element. The result is unspecified." (let ((next (iterator-next! iter))) (if (not (end-of-iteration? next)) (begin (proc next) (iterator-for-each proc iter))))) (define-public (iterator-filter pred iter) "Return the elements that satify predicate PRED." (let loop ((result '())) (let ((next (iterator-next! iter))) (cond ((end-of-iteration? next) (reverse! result)) ((pred next) (loop (cons next result))) (else (loop result)))))) (define-public (iterator-until pred iter) "Run the iterator until the result of (pred element) is true. Returns: The result of the first (pred element) call that returns true, or #f if no element matches." (let loop ((next (iterator-next! iter))) (cond ((end-of-iteration? next) #f) ((pred next) => identity) (else (loop (iterator-next! iter)))))) PK!£Ô e† † guile/gdb/printing.scmnu„[µü¤;; Additional pretty-printer support. ;; ;; Copyright (C) 2014-2018 Free Software Foundation, Inc. ;; ;; This file is part of GDB. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . (define-module (gdb printing) #:use-module ((gdb) #:select (pretty-printer? objfile? progspace? pretty-printers set-pretty-printers! objfile-pretty-printers set-objfile-pretty-printers! progspace-pretty-printers set-progspace-pretty-printers!)) #:use-module (gdb support)) (define-public (prepend-pretty-printer! obj matcher) "Add MATCHER to the beginning of the pretty-printer list for OBJ. If OBJ is #f, add MATCHER to the global list." (assert-type (pretty-printer? matcher) matcher SCM_ARG1 'prepend-pretty-printer! "pretty-printer") (cond ((eq? obj #f) (set-pretty-printers! (cons matcher (pretty-printers)))) ((objfile? obj) (set-objfile-pretty-printers! obj (cons matcher (objfile-pretty-printers obj)))) ((progspace? obj) (set-progspace-pretty-printers! obj (cons matcher (progspace-pretty-printers obj)))) (else (assert-type #f obj SCM_ARG1 'prepend-pretty-printer! "#f, objfile, or progspace")))) (define-public (append-pretty-printer! obj matcher) "Add MATCHER to the end of the pretty-printer list for OBJ. If OBJ is #f, add MATCHER to the global list." (assert-type (pretty-printer? matcher) matcher SCM_ARG1 'append-pretty-printer! "pretty-printer") (cond ((eq? obj #f) (set-pretty-printers! (append! (pretty-printers) (list matcher)))) ((objfile? obj) (set-objfile-pretty-printers! obj (append! (objfile-pretty-printers obj) (list matcher)))) ((progspace? obj) (set-progspace-pretty-printers! obj (append! (progspace-pretty-printers obj) (list matcher)))) (else (assert-type #f obj SCM_ARG1 'append-pretty-printer! "#f, objfile, or progspace")))) PK!jÝØRQQguile/gdb/init.scmnu„[µü¤;; Scheme side of the gdb module. ;; ;; Copyright (C) 2014-2018 Free Software Foundation, Inc. ;; ;; This file is part of GDB. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;; This file is included by (gdb). ;; The original i/o ports. In case the user wants them back. (define %orig-input-port #f) (define %orig-output-port #f) (define %orig-error-port #f) ;; Keys for GDB-generated exceptions. ;; gdb:with-stack is handled separately. (define %exception-keys '(gdb:error gdb:invalid-object-error gdb:memory-error gdb:pp-type-error gdb:user-error)) ;; Printer for gdb exceptions, used when Scheme tries to print them directly. (define (%exception-printer port key args default-printer) (apply (case-lambda ((subr msg args . rest) (if subr (format port "In procedure ~a: " subr)) (apply format port msg (or args '()))) (_ (default-printer))) args)) ;; Print the message part of a gdb:with-stack exception. ;; The arg list is the way it is because it's passed to set-exception-printer!. ;; We don't print a backtrace here because Guile will have already printed a ;; backtrace. (define (%with-stack-exception-printer port key args default-printer) (let ((real-key (car args)) (real-args (cddr args))) (%exception-printer port real-key real-args default-printer))) ;; Copy of Guile's print-exception that tweaks the output for our purposes. ;; TODO: It's not clear the tweaking is still necessary. (define (%print-exception-message-worker port key args) (define (default-printer) (format port "Throw to key `~a' with args `~s'." key args)) (format port "ERROR: ") ;; Pass #t for tag to catch all errors. (catch #t (lambda () (%exception-printer port key args default-printer)) (lambda (k . args) (format port "Error while printing gdb exception: ~a ~s." k args))) (newline port) (force-output port)) ;; Called from the C code to print an exception. ;; Guile prints them a little differently than we want. ;; See boot-9.scm:print-exception. (define (%print-exception-message port frame key args) (cond ((memq key %exception-keys) (%print-exception-message-worker port key args)) (else (print-exception port frame key args))) *unspecified*) ;; Called from the C code to print an exception according to the setting ;; of "guile print-stack". ;; ;; If PORT is #f, use the standard error port. ;; If STACK is #f, never print the stack, regardless of whether printing it ;; is enabled. If STACK is #t, then print it if it is contained in ARGS ;; (i.e., KEY is gdb:with-stack). Otherwise STACK is the result of calling ;; scm_make_stack (which will be ignored in favor of the stack in ARGS if ;; KEY is gdb:with-stack). ;; KEY, ARGS are the standard arguments to scm_throw, et.al. (define (%print-exception-with-stack port stack key args) (let ((style (%exception-print-style))) (if (not (eq? style 'none)) (let ((error-port (current-error-port)) (frame #f)) (if (not port) (set! port error-port)) (if (eq? port error-port) (begin (force-output (current-output-port)) ;; In case the current output port is not gdb's output port. (force-output (output-port)))) ;; If the exception is gdb:with-stack, unwrap it to get the stack and ;; underlying exception. If the caller happens to pass in a stack, ;; we ignore it and use the one in ARGS instead. (if (eq? key 'gdb:with-stack) (begin (set! key (car args)) (if stack (set! stack (cadr args))) (set! args (cddr args)))) ;; If caller wanted a stack and there isn't one, disable backtracing. (if (eq? stack #t) (set! stack #f)) ;; At this point if stack is true, then it is assumed to be a stack. (if stack (set! frame (stack-ref stack 0))) (if (and (eq? style 'full) stack) (begin ;; This is derived from libguile/throw.c:handler_message. ;; We include "Guile" in "Guile Backtrace" whereas the Guile ;; version does not so that tests can know it's us printing ;; the backtrace. Plus it could help beginners. (display "Guile Backtrace:\n" port) (display-backtrace stack port #f #f '()) (newline port))) (%print-exception-message port frame key args))))) ;; Internal utility called during startup to initialize the Scheme side of ;; GDB+Guile. (define (%initialize!) (for-each (lambda (key) (set-exception-printer! key %exception-printer)) %exception-keys) (set-exception-printer! 'gdb:with-stack %with-stack-exception-printer) (set! %orig-input-port (set-current-input-port (input-port))) (set! %orig-output-port (set-current-output-port (output-port))) (set! %orig-error-port (set-current-error-port (error-port)))) ;; Dummy routine to silence "possibly unused local top-level variable" ;; warnings from the compiler. (define-public (%silence-compiler-warnings%) (list %print-exception-with-stack %initialize!)) ;; Public routines. (define-public (orig-input-port) %orig-input-port) (define-public (orig-output-port) %orig-output-port) (define-public (orig-error-port) %orig-error-port) ;; Utility to throw gdb:user-error for use in writing gdb commands. ;; The requirements for the arguments to "throw" are a bit obscure, ;; so give the user something simpler. (define-public (throw-user-error message . args) (throw 'gdb:user-error #f message args)) PK!·èsguile/gdb/boot.scmnu„[µü¤;; Bootstrap the Scheme side of the gdb module. ;; ;; Copyright (C) 2014-2018 Free Software Foundation, Inc. ;; ;; This file is part of GDB. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;; This file is loaded with scm_c_primitive_load, which is ok, but files ;; loaded with it are not compiled. So we do very little here, and do ;; most of the initialization elsewhere. ;; Initialize the source and compiled file search paths. ;; Note: 'guile-data-directory' is provided by the C code. (let ((module-dir (guile-data-directory))) (set! %load-path (cons module-dir %load-path)) (set! %load-compiled-path (cons module-dir %load-compiled-path))) ;; Load the (gdb) module. This needs to be done here because C code relies on ;; the availability of Scheme bindings such as '%print-exception-with-stack'. ;; Note: as of Guile 2.0.11, 'primitive-load' evaluates the code and 'load' ;; somehow ignores the '.go', hence 'load-compiled'. (let ((gdb-go-file (search-path %load-compiled-path "gdb.go"))) (if gdb-go-file (load-compiled gdb-go-file) (error "Unable to find gdb.go file."))) ;; Now that the Scheme side support is loaded, initialize it. (let ((init-proc (@@ (gdb) %initialize!))) (init-proc)) PK!ž.Þ11guile/gdb/experimental.scmnu„[µü¤;; Various experimental utilities. ;; Anything in this file can change or disappear. ;; ;; Copyright (C) 2014-2018 Free Software Foundation, Inc. ;; ;; This file is part of GDB. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;; TODO: Split this file up by function? ;; E.g., (gdb experimental ports), etc. (define-module (gdb experimental) #:use-module (gdb)) ;; These are defined in C. (define-public with-gdb-output-to-port (@@ (gdb) %with-gdb-output-to-port)) (define-public with-gdb-error-to-port (@@ (gdb) %with-gdb-error-to-port)) (define-public (with-gdb-output-to-string thunk) "Calls THUNK and returns all GDB output as a string." (call-with-output-string (lambda (p) (with-gdb-output-to-port p thunk)))) PK!<4Xguile/gdb/iterator.gonu„[µü¤GOOF----LE-8-2.0ö]54hS] gguile¤ ¤ gdefine-module*¤ ¤ ¤ ggdb¤ giterator¤ ¤ gfilenameS¤ fgdb/iterator.scm¤ gimportsS¤ ¤  ¤ gsupport¤ ¤ ¤  ¤ gset-current-module¤ ¤ ¤ g assert-type¤ gSCM_ARG1¤ gmake-list-iterator¤ flist¤ g make-iterator¤ giterator-progress¤ gend-of-iteration¤ gset-iterator-progress!¤ gcall-with-deferred-observers¤ ¤ ¤ gmodule-export!¤ ! ¤ " ¤ #gcurrent-module¤ $#¤ %#¤ &¤ 'giterator-next!¤ (gend-of-iteration?¤ )greverse!¤ *giterator->list¤ +*¤ ,g iterator-map¤ -,¤ .giterator-for-each¤ /.¤ 0giterator-filter¤ 10¤ 2gidentity¤ 3giterator-until¤ 43¤C5hÈ „]4   54>"Gh0¾] 45&64Ž>"G�C¶giter  /gl /gfilenamefgdb/iterator.scmŒ  ŒŒ   ŒŒ  ŒŒ   ŒŒ   ŒŒ   ŒŒ  ŒŒ  6ŒŒ # ŒŒ . ! ŒŒ  / gnamegnext!ŒCh(á]4‰>"G6Ùgl  'gfilenamefgdb/iterator.scmŒ  ŒŒ   ŒŒ   ŒŒ   $ŒŒ   8ŒŒ   ŒŒ ' " ŒŒ  ' gnamegmake-list-iteratorŒg documentationf*Return a object for a list.ŒCR4"%&hB]456:gfilenamefgdb/iterator.scmŒ  ŒŒ  C>"G'()h@;]")4545$6Œ"ÿÿ×"ÿÿÌ3giter  :giter  /gresult   /gnext  /gfilenamefgdb/iterator.scmŒ $ ŒŒ  & ŒŒ  ( ŒŒ ( ŒŒ  ) ŒŒ  ) ŒŒ * ŒŒ ' + ŒŒ / + ŒŒ / & ŒŒ 2 ' ŒŒ : & ŒŒ  : gnamegiterator->listŒg documentationf&Return the elements of ITER as a list.ŒC*R4"%+hB]456:gfilenamefgdb/iterator.scmŒ $ ŒŒ  C>"G'()hHn]""24545$645Œ"ÿÿÎ"ÿÿ¿fgproc  Ggiter  Ggproc   8giter   8gresult   8gnext  8gfilenamefgdb/iterator.scmŒ - ŒŒ  / ŒŒ  2 ŒŒ 2 ŒŒ  3 ŒŒ  3 ŒŒ 4 ŒŒ % 5 ŒŒ . 5 ŒŒ 8 5 ŒŒ 8 / ŒŒ = 1 ŒŒ G / ŒŒ  G gnameg iterator-mapŒg documentationf.Return a list of PROC applied to each element.ŒC,R4"%-hB]456:gfilenamefgdb/iterator.scmŒ - ŒŒ  C>"G'(.h8] 4545$C4>"G6 gproc  2giter  2gnext  2gfilenamefgdb/iterator.scmŒ 7 ŒŒ  9 ŒŒ 9 ŒŒ : ŒŒ  : ŒŒ  < ŒŒ 2 = ŒŒ  2 gnamegiterator-for-eachŒg documentationf7Apply PROC to each element. The result is unspecified.ŒC.R4"%/hB]456:gfilenamefgdb/iterator.scmŒ 7 ŒŒ  C>"G'()hH^]"84545$645$ Œ"ÿÿÐ"ÿÿÈ"ÿÿÁVgpred  Egiter  Egresult   >gnext  >gfilenamefgdb/iterator.scmŒ ? ŒŒ  A ŒŒ  B ŒŒ B ŒŒ  C ŒŒ  C ŒŒ C &ŒŒ ! D ŒŒ + C ŒŒ 0 D ŒŒ 6 D ŒŒ > E ŒŒ > A ŒŒ ? A ŒŒ E A ŒŒ  E gnamegiterator-filterŒg documentationf/Return the elements that satify predicate PRED.ŒC0R4"%1hB]456:gfilenamefgdb/iterator.scmŒ ? ŒŒ  C>"G(2'hHµ]"/45$C45$645"ÿÿÑ45"ÿÿÄ­gpred  Bgiter  Bgnext   5gt   5gfilenamefgdb/iterator.scmŒ G ŒŒ  M ŒŒ  N ŒŒ  N ŒŒ  O ŒŒ  N ŒŒ ) P ŒŒ 5 P ŒŒ 5 M ŒŒ 6 M ŒŒ B M ŒŒ  B gnamegiterator-untilŒg documentationf¬Run the iterator until the result of (pred element) is true. Returns: The result of the first (pred element) call that returns true, or #f if no element matches.ŒC3R"%4hB]456:gfilenamefgdb/iterator.scmŒ G ŒŒ  C6|gm  (gfilenamefgdb/iterator.scmŒ   ŒŒ T  ŒŒ f $ ŒŒ ± - ŒŒ � 7 ŒŒ É ? ŒŒ X G ŒŒ  Ä C6PK!g[ž9G"G" guile/gdb.scmnu„[µü¤;; Scheme side of the gdb module. ;; ;; Copyright (C) 2014-2018 Free Software Foundation, Inc. ;; ;; This file is part of GDB. ;; ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;; This file is loaded with scm_c_primitive_load, which is ok, but files ;; loaded with it are not compiled. So we do very little here, and do ;; most of the initialization in init.scm. (define-module (gdb) ;; The version of the (gdb) module as (major minor). ;; Incompatible changes bump the major version. ;; Other changes bump the minor version. ;; It's not clear whether we need a patch-level as well, but this can ;; be added later if necessary. ;; This is not the GDB version on purpose. This version tracks the Scheme ;; gdb module version. ;; TODO: Change to (1 0) when ready. #:version (0 1)) ;; Export the bits provided by the C side. ;; This is so that the compiler can see the exports when ;; other code uses this module. ;; TODO: Generating this list would be nice, but it would require an addition ;; to the GDB build system. Still, I think it's worth it. (export ;; guile.c execute data-directory gdb-version host-config target-config ;; scm-arch.c arch? current-arch arch-name arch-charset arch-wide-charset arch-void-type arch-char-type arch-short-type arch-int-type arch-long-type arch-schar-type arch-uchar-type arch-ushort-type arch-uint-type arch-ulong-type arch-float-type arch-double-type arch-longdouble-type arch-bool-type arch-longlong-type arch-ulonglong-type arch-int8-type arch-uint8-type arch-int16-type arch-uint16-type arch-int32-type arch-uint32-type arch-int64-type arch-uint64-type ;; scm-block.c block? block-valid? block-start block-end block-function block-superblock block-global-block block-static-block block-global? block-static? block-symbols make-block-symbols-iterator block-symbols-progress? lookup-block ;; scm-breakpoint.c BP_NONE BP_BREAKPOINT BP_WATCHPOINT BP_HARDWARE_WATCHPOINT BP_READ_WATCHPOINT BP_ACCESS_WATCHPOINT WP_READ WP_WRITE WP_ACCESS make-breakpoint register-breakpoint! delete-breakpoint! breakpoints breakpoint? breakpoint-valid? breakpoint-number breakpoint-type brekapoint-visible? breakpoint-location breakpoint-expression breakpoint-enabled? set-breakpoint-enabled! breakpoint-silent? set-breakpoint-silent! breakpoint-ignore-count set-breakpoint-ignore-count! breakpoint-hit-count set-breakpoint-hit-count! breakpoint-thread set-breakpoint-thread! breakpoint-task set-breakpoint-task! breakpoint-condition set-breakpoint-condition! breakpoint-stop set-breakpoint-stop! breakpoint-commands ;; scm-cmd.c make-command register-command! command? command-valid? dont-repeat COMPLETE_NONE COMPLETE_FILENAME COMPLETE_LOCATION COMPLETE_COMMAND COMPLETE_SYMBOL COMPLETE_EXPRESSION COMMAND_NONE COMMAND_RUNNING COMMAND_DATA COMMAND_STACK COMMAND_FILES COMMAND_SUPPORT COMMAND_STATUS COMMAND_BREAKPOINTS COMMAND_TRACEPOINTS COMMAND_OBSCURE COMMAND_MAINTENANCE COMMAND_USER ;; scm-disasm.c arch-disassemble ;; scm-exception.c make-exception exception? exception-key exception-args ;; scm-frame.c NORMAL_FRAME DUMMY_FRAME INLINE_FRAME TAILCALL_FRAME SIGTRAMP_FRAME ARCH_FRAME SENTINEL_FRAME FRAME_UNWIND_NO_REASON FRAME_UNWIND_NULL_ID FRAME_UNWIND_OUTERMOST FRAME_UNWIND_UNAVAILABLE FRAME_UNWIND_INNER_ID FRAME_UNWIND_SAME_ID FRAME_UNWIND_NO_SAVED_PC FRAME_UNWIND_MEMORY_ERROR frame? frame-valid? frame-name frame-type frame-arch frame-unwind-stop-reason frame-pc frame-block frame-function frame-older frame-newer frame-sal frame-read-register frame-read-var frame-select newest-frame selected-frame unwind-stop-reason-string ;; scm-iterator.c make-iterator iterator? iterator-object iterator-progress set-iterator-progress! iterator-next! end-of-iteration end-of-iteration? ;; scm-lazy-string.c ;; FIXME: Where's the constructor? lazy-string? lazy-string-address lazy-string-length lazy-string-encoding lazy-string-type lazy-string->value ;; scm-math.c valid-add value-sub value-mul value-div value-rem value-mod value-pow value-not value-neg value-pos value-abs value-lsh value-rsh value-min value-max value-lognot value-logand value-logior value-logxor value=? value? value>=? ;; scm-objfile.c objfile? objfile-valid? objfile-filename objfile-progspace objfile-pretty-printers set-objfile-pretty-printers! current-objfile objfiles ;; scm-param.c PARAM_BOOLEAN PARAM_AUTO_BOOLEAN PARAM_ZINTEGER PARAM_UINTEGER PARAM_ZUINTEGER PARAM_ZUINTEGER_UNLIMITED PARAM_STRING PARAM_STRING_NOESCAPE PARAM_OPTIONAL_FILENAME PARAM_FILENAME PARAM_ENUM make-parameter register-parameter! parameter? parameter-value set-parameter-value! ;; scm-ports.c input-port output-port error-port stdio-port? open-memory memory-port? memory-port-range memory-port-read-buffer-size set-memory-port-read-buffer-size! memory-port-write-buffer-size set-memory-port-write-buffer-size! ;; with-gdb-output-to-port, with-gdb-error-to-port are in experimental.scm. ;; scm-pretty-print.c make-pretty-printer pretty-printer? pretty-printer-enabled? set-pretty-printer-enabled! make-pretty-printer-worker pretty-printer-worker? pretty-printers set-pretty-printers! ;; scm-progspace.c progspace? progspace-valid? progspace-filename progspace-objfiles progspace-pretty-printers set-progspace-pretty-printers! current-progspace progspaces ;; scm-gsmob.c gdb-object-kind ;; scm-string.c string->argv ;; scm-symbol.c SYMBOL_LOC_UNDEF SYMBOL_LOC_CONST SYMBOL_LOC_STATIC SYMBOL_LOC_REGISTER SYMBOL_LOC_ARG SYMBOL_LOC_REF_ARG SYMBOL_LOC_LOCAL SYMBOL_LOC_TYPEDEF SYMBOL_LOC_LABEL SYMBOL_LOC_BLOCK SYMBOL_LOC_CONST_BYTES SYMBOL_LOC_UNRESOLVED SYMBOL_LOC_OPTIMIZED_OUT SYMBOL_LOC_COMPUTED SYMBOL_LOC_REGPARM_ADDR SYMBOL_UNDEF_DOMAIN SYMBOL_VAR_DOMAIN SYMBOL_STRUCT_DOMAIN SYMBOL_LABEL_DOMAIN SYMBOL_VARIABLES_DOMAIN SYMBOL_FUNCTIONS_DOMAIN SYMBOL_TYPES_DOMAIN symbol? symbol-valid? symbol-type symbol-symtab symbol-line symbol-name symbol-linkage-name symbol-print-name symbol-addr-class symbol-argument? symbol-constant? symbol-function? symbol-variable? symbol-needs-frame? symbol-value lookup-symbol lookup-global-symbol ;; scm-symtab.c symtab? symtab-valid? symtab-filename symtab-fullname symtab-objfile symtab-global-block symtab-static-block sal? sal-valid? sal-symtab sal-line sal-pc sal-last find-pc-line ;; scm-type.c TYPE_CODE_BITSTRING TYPE_CODE_PTR TYPE_CODE_ARRAY TYPE_CODE_STRUCT TYPE_CODE_UNION TYPE_CODE_ENUM TYPE_CODE_FLAGS TYPE_CODE_FUNC TYPE_CODE_INT TYPE_CODE_FLT TYPE_CODE_VOID TYPE_CODE_SET TYPE_CODE_RANGE TYPE_CODE_STRING TYPE_CODE_ERROR TYPE_CODE_METHOD TYPE_CODE_METHODPTR TYPE_CODE_MEMBERPTR TYPE_CODE_REF TYPE_CODE_CHAR TYPE_CODE_BOOL TYPE_CODE_COMPLEX TYPE_CODE_TYPEDEF TYPE_CODE_NAMESPACE TYPE_CODE_DECFLOAT TYPE_CODE_INTERNAL_FUNCTION type? lookup-type type-code type-fields type-tag type-sizeof type-strip-typedefs type-array type-vector type-pointer type-range type-reference type-target type-const type-volatile type-unqualified type-name type-num-fields type-fields make-field-iterator type-field type-has-field? field? field-name field-type field-enumval field-bitpos field-bitsize field-artificial? field-baseclass? ;; scm-value.c value? make-value value-optimized-out? value-address value-type value-dynamic-type value-cast value-dynamic-cast value-reinterpret-cast value-dereference value-referenced-value value-field value-subscript value-call value->bool value->integer value->real value->bytevector value->string value->lazy-string value-lazy? make-lazy-value value-fetch-lazy! value-print parse-and-eval history-ref ) ;; Load the rest of the Scheme side. (include "gdb/init.scm") ;; These come from other files, but they're really part of this module. (export ;; init.scm orig-input-port orig-output-port orig-error-port throw-user-error ) PK!½‘à×B×B guile/gdb.gonu„[µü¤GOOF----LE-8-2.0¿B]Á4h*,] gguile¤ ¤ gdefine-module*¤ ¤ ¤ ggdb¤ ¤ gfilenameS¤ f ./gdb.scm¤ gversionS¤ ¤ gset-current-module¤  ¤  ¤ gcall-with-deferred-observers¤ ¤ ¤ gmodule-export!¤ ¤ ¤ gcurrent-module¤ ¤ ¤ gexecute¤ gdata-directory¤ g gdb-version¤ g host-config¤ g target-config¤ garch?¤ g current-arch¤ g arch-name¤ g arch-charset¤ !garch-wide-charset¤ "garch-void-type¤ #garch-char-type¤ $garch-short-type¤ %g arch-int-type¤ &garch-long-type¤ 'garch-schar-type¤ (garch-uchar-type¤ )garch-ushort-type¤ *garch-uint-type¤ +garch-ulong-type¤ ,garch-float-type¤ -garch-double-type¤ .garch-longdouble-type¤ /garch-bool-type¤ 0garch-longlong-type¤ 1garch-ulonglong-type¤ 2garch-int8-type¤ 3garch-uint8-type¤ 4garch-int16-type¤ 5garch-uint16-type¤ 6garch-int32-type¤ 7garch-uint32-type¤ 8garch-int64-type¤ 9garch-uint64-type¤ :gblock?¤ ;g block-valid?¤ gblock-function¤ ?gblock-superblock¤ @gblock-global-block¤ Agblock-static-block¤ Bg block-global?¤ Cg block-static?¤ Dg block-symbols¤ Egmake-block-symbols-iterator¤ Fgblock-symbols-progress?¤ Gg lookup-block¤ HgBP_NONE¤ Ig BP_BREAKPOINT¤ Jg BP_WATCHPOINT¤ KgBP_HARDWARE_WATCHPOINT¤ LgBP_READ_WATCHPOINT¤ MgBP_ACCESS_WATCHPOINT¤ NgWP_READ¤ OgWP_WRITE¤ Pg WP_ACCESS¤ Qgmake-breakpoint¤ Rgregister-breakpoint!¤ Sgdelete-breakpoint!¤ Tg breakpoints¤ Ug breakpoint?¤ Vgbreakpoint-valid?¤ Wgbreakpoint-number¤ Xgbreakpoint-type¤ Ygbrekapoint-visible?¤ Zgbreakpoint-location¤ [gbreakpoint-expression¤ \gbreakpoint-enabled?¤ ]gset-breakpoint-enabled!¤ ^gbreakpoint-silent?¤ _gset-breakpoint-silent!¤ `gbreakpoint-ignore-count¤ agset-breakpoint-ignore-count!¤ bgbreakpoint-hit-count¤ cgset-breakpoint-hit-count!¤ dgbreakpoint-thread¤ egset-breakpoint-thread!¤ fgbreakpoint-task¤ ggset-breakpoint-task!¤ hgbreakpoint-condition¤ igset-breakpoint-condition!¤ jgbreakpoint-stop¤ kgset-breakpoint-stop!¤ lgbreakpoint-commands¤ mg make-command¤ ngregister-command!¤ ogcommand?¤ pgcommand-valid?¤ qg dont-repeat¤ rg COMPLETE_NONE¤ sgCOMPLETE_FILENAME¤ tgCOMPLETE_LOCATION¤ ugCOMPLETE_COMMAND¤ vgCOMPLETE_SYMBOL¤ wgCOMPLETE_EXPRESSION¤ xg COMMAND_NONE¤ ygCOMMAND_RUNNING¤ zg COMMAND_DATA¤ {g COMMAND_STACK¤ |g COMMAND_FILES¤ }gCOMMAND_SUPPORT¤ ~gCOMMAND_STATUS¤ gCOMMAND_BREAKPOINTS¤ €gCOMMAND_TRACEPOINTS¤ �gCOMMAND_OBSCURE¤ ‚gCOMMAND_MAINTENANCE¤ ƒg COMMAND_USER¤ „garch-disassemble¤ …gmake-exception¤ †g exception?¤ ‡g exception-key¤ ˆgexception-args¤ ‰g NORMAL_FRAME¤ Šg DUMMY_FRAME¤ ‹g INLINE_FRAME¤ ŒgTAILCALL_FRAME¤ �gSIGTRAMP_FRAME¤ Žg ARCH_FRAME¤ �gSENTINEL_FRAME¤ �gFRAME_UNWIND_NO_REASON¤ ‘gFRAME_UNWIND_NULL_ID¤ ’gFRAME_UNWIND_OUTERMOST¤ “gFRAME_UNWIND_UNAVAILABLE¤ ”gFRAME_UNWIND_INNER_ID¤ •gFRAME_UNWIND_SAME_ID¤ –gFRAME_UNWIND_NO_SAVED_PC¤ —gFRAME_UNWIND_MEMORY_ERROR¤ ˜gframe?¤ ™g frame-valid?¤ šg frame-name¤ ›g frame-type¤ œg frame-arch¤ �gframe-unwind-stop-reason¤ žgframe-pc¤ Ÿg frame-block¤  gframe-function¤ ¡g frame-older¤ ¢g frame-newer¤ £g frame-sal¤ ¤gframe-read-register¤ ¥gframe-read-var¤ ¦g frame-select¤ §g newest-frame¤ ¨gselected-frame¤ ©gunwind-stop-reason-string¤ ªg make-iterator¤ «g iterator?¤ ¬giterator-object¤ ­giterator-progress¤ ®gset-iterator-progress!¤ ¯giterator-next!¤ °gend-of-iteration¤ ±gend-of-iteration?¤ ²g lazy-string?¤ ³glazy-string-address¤ ´glazy-string-length¤ µglazy-string-encoding¤ ¶glazy-string-type¤ ·glazy-string->value¤ ¸g valid-add¤ ¹g value-sub¤ ºg value-mul¤ »g value-div¤ ¼g value-rem¤ ½g value-mod¤ ¾g value-pow¤ ¿g value-not¤ Àg value-neg¤ Ág value-pos¤ Âg value-abs¤ Ãg value-lsh¤ Äg value-rsh¤ Åg value-min¤ Æg value-max¤ Çg value-lognot¤ Èg value-logand¤ Ég value-logior¤ Êg value-logxor¤ Ëgvalue=?¤ Ìgvalue?¤ Ïgvalue>=?¤ Ðgobjfile?¤ Ñgobjfile-valid?¤ Ògobjfile-filename¤ Ógobjfile-progspace¤ Ôgobjfile-pretty-printers¤ Õgset-objfile-pretty-printers!¤ Ögcurrent-objfile¤ ×gobjfiles¤ Øg PARAM_BOOLEAN¤ ÙgPARAM_AUTO_BOOLEAN¤ ÚgPARAM_ZINTEGER¤ ÛgPARAM_UINTEGER¤ ÜgPARAM_ZUINTEGER¤ ÝgPARAM_ZUINTEGER_UNLIMITED¤ Þg PARAM_STRING¤ ßgPARAM_STRING_NOESCAPE¤ àgPARAM_OPTIONAL_FILENAME¤ ágPARAM_FILENAME¤ âg PARAM_ENUM¤ ãgmake-parameter¤ ägregister-parameter!¤ åg parameter?¤ ægparameter-value¤ çgset-parameter-value!¤ èg input-port¤ ég output-port¤ êg error-port¤ ëg stdio-port?¤ ìg open-memory¤ íg memory-port?¤ îgmemory-port-range¤ ïgmemory-port-read-buffer-size¤ ðg!set-memory-port-read-buffer-size!¤ ñgmemory-port-write-buffer-size¤ òg"set-memory-port-write-buffer-size!¤ ógmake-pretty-printer¤ ôgpretty-printer?¤ õgpretty-printer-enabled?¤ ögset-pretty-printer-enabled!¤ ÷gmake-pretty-printer-worker¤ øgpretty-printer-worker?¤ ùgpretty-printers¤ úgset-pretty-printers!¤ ûg progspace?¤ ügprogspace-valid?¤ ýgprogspace-filename¤ þgprogspace-objfiles¤ ÿgprogspace-pretty-printers¤ gset-progspace-pretty-printers!¤ gcurrent-progspace¤ g progspaces¤ ggdb-object-kind¤ g string->argv¤ gSYMBOL_LOC_UNDEF¤ gSYMBOL_LOC_CONST¤ gSYMBOL_LOC_STATIC¤ gSYMBOL_LOC_REGISTER¤  gSYMBOL_LOC_ARG¤  gSYMBOL_LOC_REF_ARG¤  gSYMBOL_LOC_LOCAL¤  gSYMBOL_LOC_TYPEDEF¤  gSYMBOL_LOC_LABEL¤ gSYMBOL_LOC_BLOCK¤ gSYMBOL_LOC_CONST_BYTES¤ gSYMBOL_LOC_UNRESOLVED¤ gSYMBOL_LOC_OPTIMIZED_OUT¤ gSYMBOL_LOC_COMPUTED¤ gSYMBOL_LOC_REGPARM_ADDR¤ gSYMBOL_UNDEF_DOMAIN¤ gSYMBOL_VAR_DOMAIN¤ gSYMBOL_STRUCT_DOMAIN¤ gSYMBOL_LABEL_DOMAIN¤ gSYMBOL_VARIABLES_DOMAIN¤ gSYMBOL_FUNCTIONS_DOMAIN¤ gSYMBOL_TYPES_DOMAIN¤ gsymbol?¤ g symbol-valid?¤ g symbol-type¤ g symbol-symtab¤ g symbol-line¤  g symbol-name¤ !gsymbol-linkage-name¤ "gsymbol-print-name¤ #gsymbol-addr-class¤ $gsymbol-argument?¤ %gsymbol-constant?¤ &gsymbol-function?¤ 'gsymbol-variable?¤ (gsymbol-needs-frame?¤ )g symbol-value¤ *g lookup-symbol¤ +glookup-global-symbol¤ ,gsymtab?¤ -g symtab-valid?¤ .gsymtab-filename¤ /gsymtab-fullname¤ 0gsymtab-objfile¤ 1gsymtab-global-block¤ 2gsymtab-static-block¤ 3gsal?¤ 4g sal-valid?¤ 5g sal-symtab¤ 6gsal-line¤ 7gsal-pc¤ 8gsal-last¤ 9g find-pc-line¤ :gTYPE_CODE_BITSTRING¤ ;g TYPE_CODE_PTR¤ gTYPE_CODE_UNION¤ ?gTYPE_CODE_ENUM¤ @gTYPE_CODE_FLAGS¤ AgTYPE_CODE_FUNC¤ Bg TYPE_CODE_INT¤ Cg TYPE_CODE_FLT¤ DgTYPE_CODE_VOID¤ Eg TYPE_CODE_SET¤ FgTYPE_CODE_RANGE¤ GgTYPE_CODE_STRING¤ HgTYPE_CODE_ERROR¤ IgTYPE_CODE_METHOD¤ JgTYPE_CODE_METHODPTR¤ KgTYPE_CODE_MEMBERPTR¤ Lg TYPE_CODE_REF¤ MgTYPE_CODE_CHAR¤ NgTYPE_CODE_BOOL¤ OgTYPE_CODE_COMPLEX¤ PgTYPE_CODE_TYPEDEF¤ QgTYPE_CODE_NAMESPACE¤ RgTYPE_CODE_DECFLOAT¤ SgTYPE_CODE_INTERNAL_FUNCTION¤ Tgtype?¤ Ug lookup-type¤ Vg type-code¤ Wg type-fields¤ Xgtype-tag¤ Yg type-sizeof¤ Zgtype-strip-typedefs¤ [g type-array¤ \g type-vector¤ ]g type-pointer¤ ^g type-range¤ _gtype-reference¤ `g type-target¤ ag type-const¤ bg type-volatile¤ cgtype-unqualified¤ dg type-name¤ egtype-num-fields¤ fgmake-field-iterator¤ gg type-field¤ hgtype-has-field?¤ igfield?¤ jg field-name¤ kg field-type¤ lg field-enumval¤ mg field-bitpos¤ ng field-bitsize¤ ogfield-artificial?¤ pgfield-baseclass?¤ qgvalue?¤ rg make-value¤ sgvalue-optimized-out?¤ tg value-address¤ ug value-type¤ vgvalue-dynamic-type¤ wg value-cast¤ xgvalue-dynamic-cast¤ ygvalue-reinterpret-cast¤ zgvalue-dereference¤ {gvalue-referenced-value¤ |g value-field¤ }gvalue-subscript¤ ~g value-call¤ g value->bool¤ €gvalue->integer¤ �g value->real¤ ‚gvalue->bytevector¤ ƒg value->string¤ „gvalue->lazy-string¤ …g value-lazy?¤ †gmake-lazy-value¤ ‡gvalue-fetch-lazy!¤ ˆg value-print¤ ‰gparse-and-eval¤ Šg history-ref¤ ‹ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdeWfghijklmnopqrstuvwxyz{|}~€�‚ƒ„…†‡ˆ‰Št¤ Œg%orig-input-port¤ �g%orig-output-port¤ Žg%orig-error-port¤ �g gdb:error¤ �ggdb:invalid-object-error¤ ‘ggdb:memory-error¤ ’ggdb:pp-type-error¤ “ggdb:user-error¤ ”��‘’“¤ •g%exception-keys¤ –gformat¤ —fIn procedure ~a: ¤ ˜g%exception-printer¤ ™g%with-stack-exception-printer¤ šfERROR: ¤ ›gcatch¤ œf!Throw to key `~a' with args `~s'.¤ �f*Error while printing gdb exception: ~a ~s.¤ žgnewline¤ Ÿg force-output¤  g%print-exception-message-worker¤ ¡gmemq¤ ¢gprint-exception¤ £g%print-exception-message¤ ¤g%exception-print-style¤ ¥gnone¤ ¦gcurrent-error-port¤ §gcurrent-output-port¤ ¨ggdb:with-stack¤ ©g stack-ref¤ ªgfull¤ «gdisplay¤ ¬fGuile Backtrace: ¤ ­gdisplay-backtrace¤ ®g%print-exception-with-stack¤ ¯gfor-each¤ °gset-exception-printer!¤ ±gset-current-input-port¤ ²gset-current-output-port¤ ³gset-current-error-port¤ ´g %initialize!¤ µg%silence-compiler-warnings%¤ ¶µ¤ ·gorig-input-port¤ ¸·¤ ¹gorig-output-port¤ º¹¤ »gorig-error-port¤ ¼»¤ ½gthrow¤ ¾gthrow-user-error¤ ¿¾¤ À·¹»¾¤C5h�]4   54>"G4‹h;]4563gfilenamef ./gdb.scmŒ ( ŒŒ  C>"GŒR�RŽR”•R–—hPì*;13$4L>"G"L$"@-13L6ägsubr Agmsg Agargs  Agrest  Ag_ J Ngfilenamef./gdb/init.scmŒ & ŒŒ  ( ŒŒ  ) ŒŒ  ) ŒŒ ) ŒŒ 8 * "ŒŒ ? * +ŒŒ A * ŒŒ J & ŒŒ N + ŒŒ A   J N Chº]O@²gport  gkey  gargs   gdefault-printer   gfilenamef./gdb/init.scmŒ % ŒŒ  & ŒŒ   gnameg%exception-printerŒC˜R˜h ]�ŽŽ6gport  gkey  gargs   gdefault-printer   greal-key  g real-args  gfilenamef./gdb/init.scmŒ 3 ŒŒ  4 ŒŒ  5 ŒŒ 4 ŒŒ  6 ŒŒ   gnameg%with-stack-exception-printerŒC™R–š›˜–œhm]LLL6egfilenamef./gdb/init.scmŒ < ŒŒ  = ŒŒ  = ŒŒ   gnamegdefault-printerŒChI]LLLLLLO6Agfilenamef./gdb/init.scmŒ A ŒŒ  B ŒŒ   C–�ht-13L6lgk gargs gfilenamef./gdb/init.scmŒ C ŒŒ  D ŒŒ  D ŒŒ  CžŸhXÒ]4>"G4OO>"G4>"G6Êgport  Qgkey  Qgargs   Qgfilenamef./gdb/init.scmŒ ; ŒŒ  > ŒŒ > ŒŒ  > ŒŒ  @ ŒŒ : F ŒŒ Q G ŒŒ  Q gnameg%print-exception-message-workerŒC R¡• ¢hHÎ]45$4>"G"4>"GCÆgport  Cgframe  Cgkey   Cgargs   Cgfilenamef./gdb/init.scmŒ M ŒŒ  N ŒŒ  N ŒŒ  O ŒŒ * Q ŒŒ  C gnameg%print-exception-messageŒC£R¤¥¦Ÿ§é¨©ª«¬­ž£h T]HHHH45&C45HJ$"KJ&.445>"G445>"G"J&J�KJ$ JŽ�K"JŽŽK"J&K"J$4J 5K" &KJ$A4  J>"G4 JJ>"G4 J>"G""JJJJ6Lgport  gstack  gkey   gargs   gstyle   g error-port  ) gframe  ) gfilenamef./gdb/init.scmŒ _ ŒŒ  ` ŒŒ  ` ŒŒ  a ŒŒ ! a ŒŒ $ b ŒŒ ) b ŒŒ 3 d ŒŒ ; e ŒŒ C f ŒŒ D h ŒŒ G h ŒŒ P h ŒŒ Y j ŒŒ \ j ŒŒ e j ŒŒ u o ŒŒ y o ŒŒ | q ŒŒ ~ q ŒŒ „ r ŒŒ ‡ s ŒŒ Š s ŒŒ ‘ t ŒŒ ” t ŒŒ Ÿ w ŒŒ ¢ x ŒŒ ¬ z ŒŒ ­ { ŒŒ ¶ { ŒŒ ¾ } ŒŒ  } ŒŒ È } ŒŒ É ƒ ŒŒ Í ƒ ŒŒ Ô ƒ ŒŒ Ý „ ŒŒ æ „ 4ŒŒ ë „ ŒŒ ô … ŒŒ  ‡ ŒŒ*   gnameg%print-exception-with-stackŒC®R¯°˜h]]6Ugkey  gfilenamef./gdb/init.scmŒ � ŒŒ Ž ŒŒ  C•°¨™±èŒ²é�³êŽhPê]4>"G4>"G4455 4 4 55 4 455 Câgfilenamef./gdb/init.scmŒ Œ ŒŒ  � ŒŒ  � ŒŒ  � ŒŒ " � ŒŒ + ’ ŒŒ . ’ 1ŒŒ 4 ’ ŒŒ 6 ’ ŒŒ 7 “ ŒŒ : “ 3ŒŒ @ “ ŒŒ B “ ŒŒ C ” ŒŒ F ” 1ŒŒ L ” ŒŒ N ” ŒŒ  P gnameg %initialize!ŒC´R®´hr]Cjgfilenamef./gdb/init.scmŒ ™ ŒŒ š ŒŒ  gnameg%silence-compiler-warnings%ŒCµR4¶hA]4569gfilenamef./gdb/init.scmŒ ™ ŒŒ  C>"GŒh]]CUgfilenamef./gdb/init.scmŒ ž ŒŒ   gnamegorig-input-portŒC·R4¸hA]4569gfilenamef./gdb/init.scmŒ ž ŒŒ  C>"G�h^]CVgfilenamef./gdb/init.scmŒ Ÿ ŒŒ   gnamegorig-output-portŒC¹R4ºhA]4569gfilenamef./gdb/init.scmŒ Ÿ ŒŒ  C>"GŽh]]CUgfilenamef./gdb/init.scmŒ   ŒŒ   gnamegorig-error-portŒC»R4¼hA]4569gfilenamef./gdb/init.scmŒ   ŒŒ  C>"G½“h™-136‘gmessage gargs gfilenamef./gdb/init.scmŒ ¦ ŒŒ § ŒŒ  § ŒŒ  gnamegthrow-user-errorŒC¾R4¿hA]4569gfilenamef./gdb/init.scmŒ ¦ ŒŒ  C>"GÀh<]4564gfilenamef ./gdb.scmŒ ö ŒŒ  C6gm  (gfilenamef ./gdb.scmŒ   ŒŒ ) ( ŒŒgfilenamef./gdb/init.scmŒ �  ŒŒ ¢  ŒŒ §  ŒŒ ª  ŒŒ ®  ŒŒ Þ % ŒŒ  3 ŒŒ  ; ŒŒ J M ŒŒ ø _ ŒŒ î Œ ŒŒ Ž ™ ŒŒ � ž ŒŒ r Ÿ ŒŒ i   ŒŒ ­ ¦ ŒŒgfilenamef ./gdb.scmŒ Ž ö ŒŒ  Ž C6PK!¾ûT ¶?¶?syscalls/amd64-linux.xmlnu„[µü¤ PK!\Ù¢9¢9syscalls/ppc64-linux.xmlnu„[µü¤ PK!5pDDsyscalls/freebsd.xmlnu„[µü¤ PK!u]ÝsRsRsyscalls/arm-linux.xmlnu„[µü¤ PK!¼GÓ+¡J¡Jsyscalls/s390-linux.xmlnu„[µü¤ PK!¹êìx«C«Csyscalls/i386-linux.xmlnu„[µü¤ PK!+ó­'`=`=syscalls/ppc-linux.xmlnu„[µü¤ PK!8zg%ààsyscalls/gdb-syscalls.dtdnu„[µü¤ PK!\³j½8D8Dsyscalls/s390x-linux.xmlnu„[µü¤ PK!Ŷ>Îð7ð7syscalls/aarch64-linux.xmlnu„[µü¤ PK!®¦bŸ5/5/ jit-reader.hnu„[µü¤/* JIT declarations for GDB, the GNU Debugger. Copyright (C) 2011-2018 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef GDB_JIT_READER_H #define GDB_JIT_READER_H #ifdef __cplusplus extern "C" { #endif /* Versioning information. See gdb_reader_funcs. */ #define GDB_READER_INTERFACE_VERSION 1 /* Readers must be released under a GPL compatible license. To declare that the reader is indeed released under a GPL compatible license, invoke the macro GDB_DECLARE_GPL_COMPATIBLE in a source file. */ #ifdef __cplusplus #define GDB_DECLARE_GPL_COMPATIBLE_READER \ extern "C" { \ extern int plugin_is_GPL_compatible (void); \ extern int plugin_is_GPL_compatible (void) \ { \ return 0; \ } \ } #else #define GDB_DECLARE_GPL_COMPATIBLE_READER \ extern int plugin_is_GPL_compatible (void); \ extern int plugin_is_GPL_compatible (void) \ { \ return 0; \ } #endif /* Represents an address on the target system. */ typedef unsigned long long GDB_CORE_ADDR; /* Return status codes. */ enum gdb_status { GDB_FAIL = 0, GDB_SUCCESS = 1 }; struct gdb_object; struct gdb_symtab; struct gdb_block; struct gdb_symbol_callbacks; /* An array of these are used to represent a map from code addresses to line numbers in the source file. */ struct gdb_line_mapping { int line; GDB_CORE_ADDR pc; }; /* Create a new GDB code object. Each code object can have one or more symbol tables, each representing a compiled source file. */ typedef struct gdb_object *(gdb_object_open) (struct gdb_symbol_callbacks *cb); /* The callback used to create new symbol table. CB is the gdb_symbol_callbacks which the structure is part of. FILE_NAME is an (optionally NULL) file name to associate with this new symbol table. Returns a new instance to gdb_symtab that can later be passed to gdb_block_new, gdb_symtab_add_line_mapping and gdb_symtab_close. */ typedef struct gdb_symtab *(gdb_symtab_open) (struct gdb_symbol_callbacks *cb, struct gdb_object *obj, const char *file_name); /* Creates a new block in a given symbol table. A symbol table is a forest of blocks, each block representing an code address range and a corresponding (optionally NULL) NAME. In case the block corresponds to a function, the NAME passed should be the name of the function. If the new block to be created is a child of (i.e. is nested in) another block, the parent block can be passed in PARENT. SYMTAB is the symbol table the new block is to belong in. BEGIN, END is the code address range the block corresponds to. Returns a new instance of gdb_block, which, as of now, has no use. Note that the gdb_block returned must not be freed by the caller. */ typedef struct gdb_block *(gdb_block_open) (struct gdb_symbol_callbacks *cb, struct gdb_symtab *symtab, struct gdb_block *parent, GDB_CORE_ADDR begin, GDB_CORE_ADDR end, const char *name); /* Adds a PC to line number mapping for the symbol table SYMTAB. NLINES is the number of elements in LINES, each element corresponding to one (PC, line) pair. */ typedef void (gdb_symtab_add_line_mapping) (struct gdb_symbol_callbacks *cb, struct gdb_symtab *symtab, int nlines, struct gdb_line_mapping *lines); /* Close the symtab SYMTAB. This signals to GDB that no more blocks will be opened on this symtab. */ typedef void (gdb_symtab_close) (struct gdb_symbol_callbacks *cb, struct gdb_symtab *symtab); /* Closes the gdb_object OBJ and adds the emitted information into GDB's internal structures. Once this is done, the debug information will be picked up and used; this will usually be the last operation in gdb_read_debug_info. */ typedef void (gdb_object_close) (struct gdb_symbol_callbacks *cb, struct gdb_object *obj); /* Reads LEN bytes from TARGET_MEM in the target's virtual address space into GDB_BUF. Returns GDB_FAIL on failure, and GDB_SUCCESS on success. */ typedef enum gdb_status (gdb_target_read) (GDB_CORE_ADDR target_mem, void *gdb_buf, int len); /* The list of callbacks that are passed to read. These callbacks are to be used to construct the symbol table. The functions have been described above. */ struct gdb_symbol_callbacks { gdb_object_open *object_open; gdb_symtab_open *symtab_open; gdb_block_open *block_open; gdb_symtab_close *symtab_close; gdb_object_close *object_close; gdb_symtab_add_line_mapping *line_mapping_add; gdb_target_read *target_read; /* For internal use by GDB. */ void *priv_data; }; /* Forward declaration. */ struct gdb_reg_value; /* A function of this type is used to free a gdb_reg_value. See the comment on `free' in struct gdb_reg_value. */ typedef void (gdb_reg_value_free) (struct gdb_reg_value *); /* Denotes the value of a register. */ struct gdb_reg_value { /* The size of the register in bytes. The reader need not set this field. This will be set for (defined) register values being read from GDB using reg_get. */ int size; /* Set to non-zero if the value for the register is known. The registers for which the reader does not call reg_set are also assumed to be undefined */ int defined; /* Since gdb_reg_value is a variable sized structure, it will usually be allocated on the heap. This function is expected to contain the corresponding "free" function. When a pointer to gdb_reg_value is being sent from GDB to the reader (via gdb_unwind_reg_get), the reader is expected to call this function (with the same gdb_reg_value as argument) once it is done with the value. When the function sends the a gdb_reg_value to GDB (via gdb_unwind_reg_set), it is expected to set this field to point to an appropriate cleanup routine (or to NULL if no cleanup is required). */ gdb_reg_value_free *free; /* The value of the register. */ unsigned char value[1]; }; /* get_frame_id in gdb_reader_funcs is to return a gdb_frame_id corresponding to the current frame. The registers corresponding to the current frame can be read using reg_get. Calling get_frame_id on a particular frame should return the same gdb_frame_id throughout its lifetime (i.e. till before it gets unwound). One way to do this is by having the CODE_ADDRESS point to the function's first instruction and STACK_ADDRESS point to the value of the stack pointer when entering the function. */ struct gdb_frame_id { GDB_CORE_ADDR code_address; GDB_CORE_ADDR stack_address; }; /* Forward declaration. */ struct gdb_unwind_callbacks; /* Returns the value of a particular register in the current frame. The current frame is the frame that needs to be unwound into the outer (earlier) frame. CB is the struct gdb_unwind_callbacks * the callback belongs to. REGNUM is the DWARF register number of the register that needs to be unwound. Returns the gdb_reg_value corresponding to the register requested. In case the value of the register has been optimized away or otherwise unavailable, the defined flag in the returned gdb_reg_value will be zero. */ typedef struct gdb_reg_value *(gdb_unwind_reg_get) (struct gdb_unwind_callbacks *cb, int regnum); /* Sets the previous value of a particular register. REGNUM is the (DWARF) register number whose value is to be set. VAL is the value the register is to be set to. VAL is *not* copied, so the memory allocated to it cannot be reused. Once GDB no longer needs the value, it is deallocated using the FREE function (see gdb_reg_value). A register can also be "set" to an undefined value by setting the defined in VAL to zero. */ typedef void (gdb_unwind_reg_set) (struct gdb_unwind_callbacks *cb, int regnum, struct gdb_reg_value *val); /* This struct is passed to unwind in gdb_reader_funcs, and is to be used to unwind the current frame (current being the frame whose registers can be read using reg_get) into the earlier frame. The functions have been described above. */ struct gdb_unwind_callbacks { gdb_unwind_reg_get *reg_get; gdb_unwind_reg_set *reg_set; gdb_target_read *target_read; /* For internal use by GDB. */ void *priv_data; }; /* Forward declaration. */ struct gdb_reader_funcs; /* Parse the debug info off a block of memory, pointed to by MEMORY (already copied to GDB's address space) and MEMORY_SZ bytes long. The implementation has to use the functions in CB to actually emit the parsed data into GDB. SELF is the same structure returned by gdb_init_reader. Return GDB_FAIL on failure and GDB_SUCCESS on success. */ typedef enum gdb_status (gdb_read_debug_info) (struct gdb_reader_funcs *self, struct gdb_symbol_callbacks *cb, void *memory, long memory_sz); /* Unwind the current frame, CB is the set of unwind callbacks that are to be used to do this. Return GDB_FAIL on failure and GDB_SUCCESS on success. */ typedef enum gdb_status (gdb_unwind_frame) (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *cb); /* Return the frame ID corresponding to the current frame, using C to read the current register values. See the comment on struct gdb_frame_id. */ typedef struct gdb_frame_id (gdb_get_frame_id) (struct gdb_reader_funcs *self, struct gdb_unwind_callbacks *c); /* Called when a reader is being unloaded. This function should also free SELF, if required. */ typedef void (gdb_destroy_reader) (struct gdb_reader_funcs *self); /* Called when the reader is loaded. Must either return a properly populated gdb_reader_funcs or NULL. The memory allocated for the gdb_reader_funcs is to be managed by the reader itself (i.e. if it is allocated from the heap, it must also be freed in gdb_destroy_reader). */ extern struct gdb_reader_funcs *gdb_init_reader (void); /* Pointer to the functions which implement the reader's functionality. The individual functions have been documented above. None of the fields are optional. */ struct gdb_reader_funcs { /* Must be set to GDB_READER_INTERFACE_VERSION. */ int reader_version; /* For use by the reader. */ void *priv_data; gdb_read_debug_info *read; gdb_unwind_frame *unwind; gdb_get_frame_id *get_frame_id; gdb_destroy_reader *destroy; }; #ifdef __cplusplus } /* extern "C" */ #endif #endif PK!&tɘ(˜(python/gdb/FrameDecorator.pynu„[µü¤PK!Z6 ~ä(python/gdb/__init__.pynu„[µü¤PK!É4))+;python/gdb/FrameIterator.pynu„[µü¤PK!dÖïŽ__ŸApython/gdb/frames.pynu„[µü¤PK!¾ú$ššBapython/gdb/types.pynu„[µü¤PK!(b‰4´´wpython/gdb/function/__init__.pynu„[µü¤PK!Þ ,vv"zpython/gdb/function/in_scope.pynu„[µü¤PK!ÛGŸ�| | ç€python/gdb/function/strfns.pynu„[µü¤PK!æk)z °‹python/gdb/function/as_string.pynu„[µü¤PK!‹O€öÑÑ �python/gdb/function/caller_is.pynu„[µü¤PK!½ !qq>£python/gdb/prompt.pynu„[µü¤PK!ijDýA A ó³python/gdb/unwinder.pynu„[µü¤PK!m«^%¡*¡*zÀpython/gdb/printing.pynu„[µü¤PK!ÇÍŒ¼´´aëpython/gdb/printer/__init__.pynu„[µü¤PK!Áx+Ëââ%cîpython/gdb/printer/bound_registers.pynu„[µü¤PK!$mÐbiišôpython/gdb/command/explore.pynu„[µü¤PK! >xж¶è]python/gdb/command/__init__.pynu„[µü¤PK!¨ÄÅŠ8Š8%ì`python/gdb/command/pretty_printers.pynu„[µü¤PK!Ǩ'öË™python/gdb/command/prompt.pynu„[µü¤PK!¬žlyÏ'Ï'6¢python/gdb/command/xmethods.pynu„[µü¤PK!_.ëLL#SÊpython/gdb/command/type_printers.pynu„[µü¤PK!XsîšææòÛpython/gdb/command/unwinders.pynu„[µü¤PK!Y¢�eRR#'öpython/gdb/command/ignore_errors.pynu„[µü¤PK!` ÔÜ?Ü?#Ìûpython/gdb/command/frame_filters.pynu„[µü¤PK!ýë"�E+E+û;python/gdb/xmethod.pynu„[µü¤PK!$ô¼ÙÙL…gauto-load/usr/lib64/__pycache__/libstdc++.so.6.0.25-gdb.cpython-36.opt-1.pycnu„[µü¤PK!$ô¼ÙÙFÚjauto-load/usr/lib64/__pycache__/libstdc++.so.6.0.25-gdb.cpython-36.pycnu„[µü¤PK!· Ÿ¢cc+)nauto-load/usr/lib64/libisl.so.15.1.1-gdb.pynu„[µü¤PK!· Ÿ¢cc+ç}auto-load/usr/lib64/libisl.so.13.1.0-gdb.pynu„[µü¤PK!I< aM M .¥�auto-load/usr/lib64/libstdc++.so.6.0.25-gdb.pynu„[µü¤PK!P—auto-load/usr/libnuȯÝíPK!‘—auto-load/usr/binnuȯÝíPK!Ò—auto-load/usr/lib64nuȯÝíPK!˜auto-load/usr/sbinnuȯÝíPK!/ÞL‰‰W˜guile/gdb/experimental.gonu„[µü¤PK!µ� Ž Ž )Ÿguile/gdb/printing.gonu„[µü¤PK!½ºq ÉÉü©guile/gdb/support.scmnu„[µü¤PK!-~[ë ë  ¯guile/gdb/types.gonu„[µü¤PK!ÚAR 4 4 7½guile/gdb/types.scmnu„[µü¤PK!.áæH¤¤®Çguile/gdb/support.gonu„[µü¤PK!(Jär» » –Íguile/gdb/iterator.scmnu„[µü¤PK!£Ô e† † —Øguile/gdb/printing.scmnu„[µü¤PK!jÝØRQQcâguile/gdb/init.scmnu„[µü¤PK!·èsöùguile/gdb/boot.scmnu„[µü¤PK!ž.Þ11Wguile/gdb/experimental.scmnu„[µü¤PK!<4XÒguile/gdb/iterator.gonu„[µü¤PK!g[ž9G"G" %guile/gdb.scmnu„[µü¤PK!½‘à×B×B ©;guile/gdb.gonu„[µü¤PK!¾ûT ¶?¶?¼~syscalls/amd64-linux.xmlnu„[µü¤PK!\Ù¢9¢9º¾syscalls/ppc64-linux.xmlnu„[µü¤PK!5pDD¤øsyscalls/freebsd.xmlnu„[µü¤PK!u]ÝsRsR=syscalls/arm-linux.xmlnu„[µü¤PK!¼GÓ+¡J¡J¾�syscalls/s390-linux.xmlnu„[µü¤PK!¹êìx«C«C¦Úsyscalls/i386-linux.xmlnu„[µü¤PK!+ó­'`=`=˜syscalls/ppc-linux.xmlnu„[µü¤PK!8zg%àà>\syscalls/gdb-syscalls.dtdnu„[µü¤PK!\³j½8D8Dg^syscalls/s390x-linux.xmlnu„[µü¤PK!Ŷ>Îð7ð7ç¢syscalls/aarch64-linux.xmlnu„[µü¤PK!®¦bŸ5/5/ !Ûjit-reader.hnu„[µü¤PK;;ï’