GDB (API)
|
00001 # Copyright (C) 2013 Free Software Foundation, Inc. 00002 00003 # This program is free software; you can redistribute it and/or modify 00004 # it under the terms of the GNU General Public License as published by 00005 # the Free Software Foundation; either version 3 of the License, or 00006 # (at your option) any later version. 00007 # 00008 # This program is distributed in the hope that it will be useful, 00009 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 # GNU General Public License for more details. 00012 # 00013 # You should have received a copy of the GNU General Public License 00014 # along with this program. If not, see <http://www.gnu.org/licenses/>. 00015 00016 import gdb 00017 00018 # This small code snippet deals with problem of strings in Python 2.x 00019 # and Python 3.x. Python 2.x has str and unicode classes which are 00020 # sub-classes of basestring. In Python 3.x all strings are encoded 00021 # and basestring has been removed. 00022 try: 00023 basestring 00024 except NameError: 00025 basestring = str 00026 00027 class FrameDecorator(object): 00028 """Basic implementation of a Frame Decorator""" 00029 00030 """ This base frame decorator decorates a frame or another frame 00031 decorator, and provides convenience methods. If this object is 00032 wrapping a frame decorator, defer to that wrapped object's method 00033 if it has one. This allows for frame decorators that have 00034 sub-classed FrameDecorator object, but also wrap other frame 00035 decorators on the same frame to correctly execute. 00036 00037 E.g 00038 00039 If the result of frame filters running means we have one gdb.Frame 00040 wrapped by multiple frame decorators, all sub-classed from 00041 FrameDecorator, the resulting hierarchy will be: 00042 00043 Decorator1 00044 -- (wraps) Decorator2 00045 -- (wraps) FrameDecorator 00046 -- (wraps) gdb.Frame 00047 00048 In this case we have two frame decorators, both of which are 00049 sub-classed from FrameDecorator. If Decorator1 just overrides the 00050 'function' method, then all of the other methods are carried out 00051 by the super-class FrameDecorator. But Decorator2 may have 00052 overriden other methods, so FrameDecorator will look at the 00053 'base' parameter and defer to that class's methods. And so on, 00054 down the chain.""" 00055 00056 # 'base' can refer to a gdb.Frame or another frame decorator. In 00057 # the latter case, the child class will have called the super 00058 # method and _base will be an object conforming to the Frame Filter 00059 # class. 00060 def __init__(self, base): 00061 self._base = base 00062 00063 @staticmethod 00064 def _is_limited_frame(frame): 00065 """Internal utility to determine if the frame is special or 00066 limited.""" 00067 sal = frame.find_sal() 00068 00069 if (not sal.symtab or not sal.symtab.filename 00070 or frame.type() == gdb.DUMMY_FRAME 00071 or frame.type() == gdb.SIGTRAMP_FRAME): 00072 00073 return True 00074 00075 return False 00076 00077 def elided(self): 00078 """Return any elided frames that this class might be 00079 wrapping, or None.""" 00080 if hasattr(self._base, "elided"): 00081 return self._base.elided() 00082 00083 return None 00084 00085 def function(self): 00086 """ Return the name of the frame's function or an address of 00087 the function of the frame. First determine if this is a 00088 special frame. If not, try to determine filename from GDB's 00089 frame internal function API. Finally, if a name cannot be 00090 determined return the address. If this function returns an 00091 address, GDB will attempt to determine the function name from 00092 its internal minimal symbols store (for example, for inferiors 00093 without debug-info).""" 00094 00095 # Both gdb.Frame, and FrameDecorator have a method called 00096 # "function", so determine which object this is. 00097 if not isinstance(self._base, gdb.Frame): 00098 if hasattr(self._base, "function"): 00099 # If it is not a gdb.Frame, and there is already a 00100 # "function" method, use that. 00101 return self._base.function() 00102 00103 frame = self.inferior_frame() 00104 00105 if frame.type() == gdb.DUMMY_FRAME: 00106 return "<function called from gdb>" 00107 elif frame.type() == gdb.SIGTRAMP_FRAME: 00108 return "<signal handler called>" 00109 00110 func = frame.function() 00111 00112 # If we cannot determine the function name, return the 00113 # address. If GDB detects an integer value from this function 00114 # it will attempt to find the function name from minimal 00115 # symbols via its own internal functions. 00116 if func == None: 00117 pc = frame.pc() 00118 return pc 00119 00120 return str(func) 00121 00122 def address(self): 00123 """ Return the address of the frame's pc""" 00124 00125 if hasattr(self._base, "address"): 00126 return self._base.address() 00127 00128 frame = self.inferior_frame() 00129 return frame.pc() 00130 00131 def filename(self): 00132 """ Return the filename associated with this frame, detecting 00133 and returning the appropriate library name is this is a shared 00134 library.""" 00135 00136 if hasattr(self._base, "filename"): 00137 return self._base.filename() 00138 00139 frame = self.inferior_frame() 00140 sal = frame.find_sal() 00141 if not sal.symtab or not sal.symtab.filename: 00142 pc = frame.pc() 00143 return gdb.solib_name(pc) 00144 else: 00145 return sal.symtab.filename 00146 00147 def frame_args(self): 00148 """ Return an iterable of frame arguments for this frame, if 00149 any. The iterable object contains objects conforming with the 00150 Symbol/Value interface. If there are no frame arguments, or 00151 if this frame is deemed to be a special case, return None.""" 00152 00153 if hasattr(self._base, "frame_args"): 00154 return self._base.frame_args() 00155 00156 frame = self.inferior_frame() 00157 if self._is_limited_frame(frame): 00158 return None 00159 00160 args = FrameVars(frame) 00161 return args.fetch_frame_args() 00162 00163 def frame_locals(self): 00164 """ Return an iterable of local variables for this frame, if 00165 any. The iterable object contains objects conforming with the 00166 Symbol/Value interface. If there are no frame locals, or if 00167 this frame is deemed to be a special case, return None.""" 00168 00169 if hasattr(self._base, "frame_locals"): 00170 return self._base.frame_locals() 00171 00172 frame = self.inferior_frame() 00173 if self._is_limited_frame(frame): 00174 return None 00175 00176 args = FrameVars(frame) 00177 return args.fetch_frame_locals() 00178 00179 def line(self): 00180 """ Return line number information associated with the frame's 00181 pc. If symbol table/line information does not exist, or if 00182 this frame is deemed to be a special case, return None""" 00183 00184 if hasattr(self._base, "line"): 00185 return self._base.line() 00186 00187 frame = self.inferior_frame() 00188 if self._is_limited_frame(frame): 00189 return None 00190 00191 sal = frame.find_sal() 00192 if (sal): 00193 return sal.line 00194 else: 00195 return None 00196 00197 def inferior_frame(self): 00198 """ Return the gdb.Frame underpinning this frame decorator.""" 00199 00200 # If 'base' is a frame decorator, we want to call its inferior 00201 # frame method. If '_base' is a gdb.Frame, just return that. 00202 if hasattr(self._base, "inferior_frame"): 00203 return self._base.inferior_frame() 00204 return self._base 00205 00206 class SymValueWrapper(object): 00207 """A container class conforming to the Symbol/Value interface 00208 which holds frame locals or frame arguments.""" 00209 def __init__(self, symbol, value): 00210 self.sym = symbol 00211 self.val = value 00212 00213 def value(self): 00214 """ Return the value associated with this symbol, or None""" 00215 return self.val 00216 00217 def symbol(self): 00218 """ Return the symbol, or Python text, associated with this 00219 symbol, or None""" 00220 return self.sym 00221 00222 class FrameVars(object): 00223 00224 """Utility class to fetch and store frame local variables, or 00225 frame arguments.""" 00226 00227 def __init__(self, frame): 00228 self.frame = frame 00229 self.symbol_class = { 00230 gdb.SYMBOL_LOC_STATIC: True, 00231 gdb.SYMBOL_LOC_REGISTER: True, 00232 gdb.SYMBOL_LOC_ARG: True, 00233 gdb.SYMBOL_LOC_REF_ARG: True, 00234 gdb.SYMBOL_LOC_LOCAL: True, 00235 gdb.SYMBOL_LOC_REGPARM_ADDR: True, 00236 gdb.SYMBOL_LOC_COMPUTED: True 00237 } 00238 00239 def fetch_b(self, sym): 00240 """ Local utility method to determine if according to Symbol 00241 type whether it should be included in the iterator. Not all 00242 symbols are fetched, and only symbols that return 00243 True from this method should be fetched.""" 00244 00245 # SYM may be a string instead of a symbol in the case of 00246 # synthetic local arguments or locals. If that is the case, 00247 # always fetch. 00248 if isinstance(sym, basestring): 00249 return True 00250 00251 sym_type = sym.addr_class 00252 00253 return self.symbol_class.get(sym_type, False) 00254 00255 def fetch_frame_locals(self): 00256 """Public utility method to fetch frame local variables for 00257 the stored frame. Frame arguments are not fetched. If there 00258 are no frame local variables, return an empty list.""" 00259 lvars = [] 00260 00261 block = self.frame.block() 00262 00263 while block != None: 00264 if block.is_global or block.is_static: 00265 break 00266 for sym in block: 00267 if sym.is_argument: 00268 continue; 00269 if self.fetch_b(sym): 00270 lvars.append(SymValueWrapper(sym, None)) 00271 00272 block = block.superblock 00273 00274 return lvars 00275 00276 def fetch_frame_args(self): 00277 """Public utility method to fetch frame arguments for the 00278 stored frame. Frame arguments are the only type fetched. If 00279 there are no frame argument variables, return an empty list.""" 00280 00281 args = [] 00282 block = self.frame.block() 00283 while block != None: 00284 if block.function != None: 00285 break 00286 block = block.superblock 00287 00288 if block != None: 00289 for sym in block: 00290 if not sym.is_argument: 00291 continue; 00292 args.append(SymValueWrapper(sym, None)) 00293 00294 return args