def to_string(self): ret = "{" viz = gdb.default_visualizer(self.val['_storage']) vizRC = gdb.default_visualizer(self.val['_refCount']) for (name,val), (name2,val2) in zip(viz.children(), vizRC.children()): ret += str(val['fName']) + ": " + str(val2) + ", " return ret + "}"
def get_fiber_managers(only=None): """iterator of (mid, manager) tuples Can filter output with "M.*" or "M" format, e.g. "2.3" for manager 2 (fiber is ignored) or "1" for manager 1. """ # first check if pre-cached if get_fiber_managers.cache: for (mid, manager) in get_fiber_managers.cache.items(): # output only if matching filter if not only or str(mid) in only: yield (mid, manager) return # extract the unique managers from the fiber filters only = {i.partition(".")[0] for i in only or []} managers = collections.OrderedDict() mgr_map = None for evb_type in ("folly::EventBase", "folly::VirtualEventBase"): # this can possibly return an empty map, even if it exists try: mgr_map = get_fiber_manager_map(evb_type) except gdb.GdbError: continue # the map pretty printer knows how to extract map entries map_pp = gdb.default_visualizer(mgr_map) # The children are alternating pairs of (_, (evb, int))/(_, uptr<FiberManager>) # the first entry is irrelevant, just an internal name for the pretty printer mid = 0 for _, entry in map_pp.children(): # The "key" in this map is std::pair<EventBaseT, long>, and the long is # almost always 0 (used for frozen options). We'll ignore it and just use # our own internal id. We unwrap the unique_ptr, though. if "unique_ptr" not in entry.type.tag: mid += 1 continue # we have a value, make sure we have a unique key assert mid not in managers value = entry # unfortunately the stl gdb libs don't expose the unique_ptr target address # except through the pretty printer, as the last space-delimited word. # We extract that address using the pretty printer, then create a new # gdb.Value of that address cast to the fibermanager type. address = int( gdb.default_visualizer(value).to_string().split(" ")[-1], 16) manager = (gdb.Value(address).cast( gdb.lookup_type( "folly::fibers::FiberManager").pointer()).dereference()) # output only if matching filter if not only or str(mid) in only: yield (mid, manager) # set cache get_fiber_managers.cache = managers
def to_string(self): ret = "{" viz = gdb.default_visualizer(self.val['_storage']) vizRC = gdb.default_visualizer(self.val['_refCount']) for (name, val), (name2, val2) in zip(viz.children(), vizRC.children()): ret += str(val['fName']) + ": " + str(val2) + ", " return ret + "}"
def __init__(self, typename, value): self.typename = typename self.value = value prop = self.value['m_prop'] if prop: assert prop self.delegate = gdb.default_visualizer(prop.dereference()) else: vec = self.value['m_vec'] assert vec self.delegate = gdb.default_visualizer(vec.dereference())
def invoke(self, arg, from_tty): val = gdb.parse_and_eval(arg) vis = gdb.default_visualizer(val) if vis: print vis.to_string() else: print "Don't know how to pretty-print", val
def get_printer_result(self, c_variable_name): """Get pretty-printer output for C variable with a specified name :param c_variable_name: Name of a C variable :return: (string, [children], display_hint) """ value = gdb.parse_and_eval(c_variable_name) pretty_printer = gdb.default_visualizer(value) self.assertIsNotNone(pretty_printer, 'Pretty printer was not registred') string = pretty_printer.to_string() if string is not None: string = text_type(string) if hasattr(pretty_printer, 'children'): children = list(pretty_printer.children()) for child_text, _ in children: self.assertIsInstance(child_text, string_types) else: children = None if hasattr(pretty_printer, 'display_hint'): self.assertIsInstance(pretty_printer.display_hint(), string_types) display_hint = text_type(pretty_printer.display_hint()) else: display_hint = None return string, children, display_hint
def __init__(self, typename, value): self.typename = typename self.value = value pimpl = self.value['m_impl'] assert pimpl self.delegate = gdb.default_visualizer(pimpl.dereference()['m_vector'])
def __init__(self, typename, value): self.typename = typename self.value = value pimpl = self.value["m_impl"] assert pimpl self.delegate = gdb.default_visualizer(pimpl.dereference()["m_map"])
def lookup(val): type = untypedef(val.type) if type.code == gdb.TYPE_CODE_ARRAY: return ArrayPrinter(val, type) if type.code == gdb.TYPE_CODE_PTR: target_type = untypedef(type.target()) if (target_type.code != gdb.TYPE_CODE_VOID and target_type.code != gdb.TYPE_CODE_CHAR and target_type.code != gdb.TYPE_CODE_INT and target_type.code != gdb.TYPE_CODE_PTR and target_type.code != gdb.TYPE_CODE_ARRAY): try: dereferenced = val.dereference() dereferenced.fetch_lazy() except gdb.error as e: pass else: delegate = gdb.default_visualizer(dereferenced) if delegate is not None: return PointerPrinter(val, delegate) return None
def __init__(self, typename: str, value: gdb.Value) -> None: """ """ self._typename = typename self._value = value self._value_visualizer = gdb.default_visualizer(value['value']) self.value = value['value']
def display_hint(self) -> str: """ """ visualizer = gdb.default_visualizer(self.value) if visualizer is not None: return visualizer.display_hint() else: return None
def __init__(self, typename, value): self.typename = typename self.value = value pimpl = self.value["m_binaryDataImpl"] assert pimpl ptr = pimpl.dereference()["m_ptr"]["px"] assert ptr self.delegate = gdb.default_visualizer(ptr.dereference()["m_buf"])
def __init__(self, typename, value): self.typename = typename self.value = value pimpl = self.value['m_binaryDataImpl'] assert pimpl ptr = pimpl.dereference()['m_ptr']['px'] assert ptr self.delegate = gdb.default_visualizer(ptr.dereference()['m_buf'])
def to_string(self): try: val = self.strval if isinstance(val,str): return val else: return gdb.default_visualizer(self.strval).to_string() except Exception: return None
def __init__(self, typename, ptr): self.ptr = ptr self.val = None self.visualizer = None if self.ptr != 0: self.val = self.ptr.dereference() # Dereference base type with visualizer, if it exists. # Also, inherit iteratability, if that is a word. self.visualizer = gdb.default_visualizer(self.val) if ((self.visualizer is not None) and hasattr(self.visualizer, 'children')): self.children = self._children
def invoke(self, cont, idx=0): assert isinstance(cont, gdb.Value) p = gdb.default_visualizer(cont) assert p, 'no printer for type [' + str(cont.type) + ']' assert hasattr(p, 'children'), 'printer for type [' + str(cont.type) + '] has no children() function' it = iter(p.children()) i = idx while i > 0: next(it) i -= 1 _, val = next(it) return str(val)
def json_lookup_function(val): if re.search("^nlohmann::basic_json<.*>$", val.type.strip_typedefs().name): t = str(val['m_type']) if t.startswith("nlohmann::detail::value_t::"): try: union_val = val['m_value'][t[27:]] if union_val.type.code == gdb.TYPE_CODE_PTR: return gdb.default_visualizer(union_val.dereference()) else: return JsonValuePrinter(union_val) except: return JsonValuePrinter(val['m_type'])
def fetchfields(value): trace('fetchfields)') if value == None: return [] ppobj = gdb.default_visualizer(value) if ppobj == None: return [] # For arrays we want to prevent this (the list could get huge) if ppobj.__class__.__name__ == 'SVMPPArray': return [] trace('fetchfields for %s returned children' % ppobj.to_string()) return ppobj.children()
def invoke(self, cont, idx=0): assert isinstance(cont, gdb.Value) p = gdb.default_visualizer(cont) assert p, 'no printer for type [' + str(cont.type) + ']' assert hasattr(p, 'children'), 'printer for type [' + str( cont.type) + '] has no children() function' it = iter(p.children()) i = idx while i > 0: next(it) i -= 1 _, val = next(it) return str(val)
def __call__(self, v): if not self.enabled: return None if hasattr(self.Printer, 'supports') and not self.Printer.supports(v): return None if hasattr(self.Printer, 'transform') and callable(self.Printer.transform): tv = self.Printer.transform(v) if type(tv) == gdb.Value: p = gdb.default_visualizer(tv) if p: return p return self.Printer(tv) else: return self.Printer(v)
def dump(self, expr): o = None try: o = obj(expr) except: print("Failed to evaluate '%s'" % expr) return print(str(o)) if not o.isBytes(): for name, value in o.children(): pp = gdb.default_visualizer(value) if pp == None: print(" %-15s: %s" % (name, value)) else: print(" %-15s: %s" % (name, pp.to_string()))
def __call__(self, v): if not self.enabled: return None if hasattr(self.Printer, 'supports') and not self.Printer.supports(v): return None if hasattr(self.Printer, 'transform') and callable( self.Printer.transform): tv = self.Printer.transform(v) if type(tv) == gdb.Value: p = gdb.default_visualizer(tv) if p: return p return self.Printer(tv) else: return self.Printer(v)
def getelem(value, indices): if len(indices) == 0: return value try: for index in indices: if value == None: return value valuepp = gdb.default_visualizer(value) value = None if valuepp == None: return None trace('<getelem for index %d fetch children of: %s>' % (index, valuepp.__class__.__name__)) children = valuepp.children() for (elemname, elemvalue) in children: trace('<getelem at child: %s>' % elemname) if index == 0: value = elemvalue break index -= 1 except Exception as e: trace('<getelem exception: %s>' % e) value = None return value
def deref_printer(val): "Look-up and return a pretty-printer that can print val." try: val_ = val type_ = gdb.types.get_basic_type(val_.type) if not isinstance(type_, gdb.Type): return None if type_.code != gdb.TYPE_CODE_PTR: return None while type_.code == gdb.TYPE_CODE_PTR: if val_ == 0: return None if type_.target().code == gdb.TYPE_CODE_VOID: return None try: val_ = val_.dereference() except Exception: return None type_ = gdb.types.get_basic_type(val_.type) return gdb.default_visualizer(val_) except Exception: gdb.write(traceback.format_exc()) return None
def _inspect(self, val, explicit_type=None): '''explicit_type is currently the "displayMode" from when we normally do "fieldName: true". It's being introduced to support bitflag mappings for what are just uint32_t's as far as the source is concerned. We use the explicit type to key like it was a normal type. For bitflags thus far, this could be a separate namespace, and since we wouldn't want all extra definitions like this to be inline, it does make sense to just have it be a name that calls out. We'll see. This all wants to be cleaner anyways. Let's just finish exploring the feature space. ''' vtype = val.type #pout("!!vtype: %s %s %s %s", vtype, type(vtype), vtype.tag, type(vtype.tag)) # pierce pointers. Note that our caller may themselves have invoked # maybe_deref, so this could get weird. val = maybe_deref(val) vtype = val.type #pout("!vtype: %s %s %s %s", vtype, type(vtype), vtype.tag, type(vtype.tag)) vtype = None if explicit_type is not None: tname = explicit_type rule = self.mapping.get(explicit_type) else: # figure out the type; we want to use RTTI if available to downcast all # the way. vtype = val.dynamic_type # that may have given us a better type, let's re-cast the value too. try: val = val.cast(vtype) except: pass # we may be a pointer type or other simple type. In particular, we may # be a char*-type thing. punt to gdb. for now. if vtype.name is None: # XXX gdb presents strings as `0xNNNN "foo bar"` in a single string # which breaks our pretty schema. pout("{n}%s", str(val)) return #pout("vtype: %s %s %s %s", vtype, type(vtype), vtype.tag, type(vtype.tag)) tmatch = RE_TEMPLATE_NAME.match(vtype.name) if tmatch: # it was a template! tname = tmatch.group(1) else: tname = vtype.name # check if we have a configuration mapping for the type #pout("looking up %s in...", tname) #pout("%s", repr(self.mapping)) rule = self.mapping.get(tname) if rule: # if this was an alias, pierce itgdbvis if isinstance(rule, str): rule = self.mapping.get(rule) #pout("Found mapping with kind %s", rule.get("kind", "default")) if "traverse" in rule: self._traverse(val, rule, tname) elif "iterate" in rule: self._iterate(val, rule, tname) elif "bitflags" in rule: self._bitflags(val, rule, tname) elif "terse" in rule: self._print_terse(val, rule, tname) elif "simple" in rule: self._print_simple(val, rule, tname) elif "groups" in rule: self._print_groups(val, rule, tname) else: pout("{e}Don't understand rule {n}%s {e}for type {n}%s", repr(rule), tname) # Handled or errored appropriately, no need to fall through to the # default visualizer. return # check for heuristic stuff if vtype: # handle enums if vtype.code == gdb.TYPE_CODE_ENUM: self._print_enum(val, vtype, tname) return # just print simple types without complaining about mappings. if is_simple_type(vtype): pout("{n}%s", str(val)) return pout.v("{s}Falling back to default visualizer for type %s", tname) vis = gdb.default_visualizer(val) if vis and hasattr(vis, 'children'): if hasattr(vis, 'display_hint'): vis_type = vis.display_hint() else: # std::set doesn't implement display_hint vis_type = "array" if vis_type == "array": self._gdbvis_array(val, vis, vis.to_string() or tname) return elif vis_type == "map": self._gdbvis_map(val, vis, vis.to_string() or tname) return elif vis: # the string case is effectively equivalent to just handing off to # gdb, so leave it up to the fall-through case. pass else: pout("{s}No mapping or pretty-printer for {n}%s{s}, switching to gdb print.", tname) # TODO implement our own form of fallback iteration over fields using # heuristics here. # gdb will do its standard thing here. pout("{n}%s", str(val))
def complete(self, text, word): with SVMCommandPrettyPrint.lookup_scope(): trace('text="%s"' % text) if text.rfind('[') > text.rfind('.'): try: # trace('array index completion') (field_access_str, _, after) = text.rpartition('[') if ']' in after: return [] value = self.resolve(field_access_str) if value == None: return [] ppobj = gdb.default_visualizer(value) if ppobj.__class__.__name__ == 'SVMPPArray': candidates = [] arrlen = ppobj.length for arrindex in range(arrlen): if arrindex > 2: candidates.append('%d]' % (arrlen - 1)) break candidates.append('%d]' % arrindex) return [c for c in candidates if c.startswith(after)] except Exception as e: trace('<arrayindex completion exception: %s>' % e) return [] if not '.' in text: gdb.flush() candidates = [] use_pp_bak = SVMUtil.use_pp SVMUtil.use_pp = False output = gdb.execute('info locals', False, True) output += gdb.execute('info args', False, True) SVMUtil.use_pp = use_pp_bak output_skiplist = [ '<optimized out>', 'No locals.', 'No arguments.' ] for line in output.split('\n'): if any([blentry in line for blentry in output_skiplist]): continue words = line.split('=') if len(words) > 0: first = words[0] first = first.strip() if len(first) > 0: candidates.append(first) candidates = [x for x in candidates if x.startswith(text)] candidates += self.svar_complete(text, candidates) return candidates if text.endswith('.'): field_access_str = text.rstrip('.') candidates = [ fieldname for (fieldname, _) in SVMCommandPrettyPrint.fetchfields( self.resolve(field_access_str)) ] candidates += self.svar_complete(text, candidates) return candidates if '.' in text: (before, _, after) = text.rpartition('.') fields = SVMCommandPrettyPrint.fetchfields( self.resolve(before)) candidates = [ fieldname for (fieldname, _) in fields if fieldname.startswith(after) ] candidates += self.svar_complete(text, candidates) return candidates return []
def _find_delegate(self): if compatibility.has_dynamic_type: dtype = self.value.dynamic_type if dtype != self.value.type: self.delegate = gdb.default_visualizer(self.value.cast(dtype))
def resolve(obj): if obj is None: return None return gdb.default_visualizer(obj)
def __init__(self,string,val): self.string = string self.printer = gdb.default_visualizer(val)
def __init__(self, val): self.val = val self.nviz = gdb.default_visualizer(val["n"])
def __init__(self, val): self.val = val self.viz = gdb.default_visualizer(self.val['_list'])
def __init__ (self, typename, val): self.typename = typename self.visualizer = gdb.default_visualizer(val['c'])
def __init__(self, val, type_): self.val = val self.type_ = type_ self.frames_ = self.val['frames_'] self.frames_vis = gdb.default_visualizer(self.frames_)
def __init__(self, typename, val): self.typename = typename self.visualizer = gdb.default_visualizer(val['c']) if hasattr(self.visualizer, 'children'): self.children = self._children
def __getitem__(self, key): item = self.obj[key] ppitem = gdb.default_visualizer(item) return item if ppitem is None else ppitem