def invoke(self, arg, from_tty): hrtimer_bases = gdb.parse_and_eval("&hrtimer_bases") max_clock_bases = gdb.parse_and_eval("HRTIMER_MAX_CLOCK_BASES") text = "Timer List Version: gdb scripts\n" text += "HRTIMER_MAX_CLOCK_BASES: {}\n".format(max_clock_bases) text += "now at {} nsecs\n".format(ktime_get()) for cpu in cpus.each_online_cpu(): text += print_cpu(hrtimer_bases, cpu, max_clock_bases) if constants.LX_CONFIG_GENERIC_CLOCKEVENTS: if constants.LX_CONFIG_GENERIC_CLOCKEVENTS_BROADCAST: bc_dev = gdb.parse_and_eval("&tick_broadcast_device") text += print_tickdevice(bc_dev, -1) text += "\n" mask = gdb.parse_and_eval("tick_broadcast_mask") mask = pr_cpumask(mask) text += "tick_broadcast_mask: {}\n".format(mask) if constants.LX_CONFIG_TICK_ONESHOT: mask = gdb.parse_and_eval("tick_broadcast_oneshot_mask") mask = pr_cpumask(mask) text += "tick_broadcast_oneshot_mask: {}\n".format(mask) text += "\n" tick_cpu_devices = gdb.parse_and_eval("&tick_cpu_device") for cpu in cpus.each_online_cpu(): tick_dev = cpus.per_cpu(tick_cpu_devices, cpu) text += print_tickdevice(tick_dev, cpu) text += "\n" gdb.write(text)
def invoke(self, arg, from_tty): # Format for x command is: <repcount> oxdutfaicsz bhwg # but print command is only 1oxdutfaicsz # ...but /r also exists; it skips pretty printers. # We add # v = verbose # and augment # r = raw # to skip label substitutions. fmt, arg = util.split_command_arg(arg) verbose = 'v' in fmt raw = 'r' in fmt fmt = fmt.replace('v', '') fmtStr = "/" + fmt if fmt else '' for e in self.enumerateExprs(arg): try: v = gdb.parse_and_eval(e) except gdb.error as exc: gdb.write(str(exc) + "\n") return gdb.set_convenience_variable('__expr', v) output = gdb.execute("print" + fmtStr + " $__expr", from_tty, to_string=True) if not raw: output = labels.apply(output, verbose) gdb.write(output)
def invoke(self, arg, from_tty): arg = gdb.string_to_argv(arg) if len(arg) != 2: raise gdb.GdbError("Usage: sol_flow print options <node> <options>") type = get_node_type_from_exp(arg[0]) options = gdb.parse_and_eval(arg[1]) gdb.write(get_type_options_string(type, options))
def invoke(self, arg, from_tty): cpu_mem = gdb.parse_and_eval('memory::cpu_mem') small_pools = cpu_mem['small_pools'] nr = small_pools['nr_small_pools'] page_size = int(gdb.parse_and_eval('memory::page_size')) gdb.write('{objsize:>5} {span_size:>6} {use_count:>10} {memory:>12} {wasted_percent:>5}\n' .format(objsize='objsz', span_size='spansz', use_count='usedobj', memory='memory', wasted_percent='wst%')) for i in range(int(nr)): sp = small_pools['_u']['a'][i] object_size = int(sp['_object_size']) span_size = int(sp['_span_size']) * page_size free_count = int(sp['_free_count']) spans_in_use = int(sp['_spans_in_use']) memory = spans_in_use * span_size use_count = spans_in_use * int(span_size / object_size) - free_count wasted = free_count * object_size wasted_percent = wasted * 100.0 / memory if memory else 0 gdb.write('{objsize:5} {span_size:6} {use_count:10} {memory:12} {wasted_percent:5.1f}\n' .format(objsize=object_size, span_size=span_size, use_count=use_count, memory=memory, wasted_percent=wasted_percent)) gdb.write('Page spans:\n') gdb.write('{index:5} {size:>13} {total}\n'.format(index="index", size="size [B]", total="free [B]")) for index in range(int(cpu_mem['nr_span_lists'])): span_list = cpu_mem['fsu']['free_spans'][index] front = int(span_list['_front']) pages = cpu_mem['pages'] total = 0 while front: span = pages[front] total += int(span['span_size']) front = int(span['link']['_next']) gdb.write('{index:5} {size:13} {total}\n'.format(index=index, size=(1<<index)*page_size, total=total*page_size))
def load_all_symbols(self): gdb.write("loading vmlinux\n") # Dropping symbols will disable all breakpoints. So save their states # and restore them afterward. saved_states = [] if hasattr(gdb, 'breakpoints') and not gdb.breakpoints() is None: for bp in gdb.breakpoints(): saved_states.append({'breakpoint': bp, 'enabled': bp.enabled}) # drop all current symbols and reload vmlinux orig_vmlinux = 'vmlinux' for obj in gdb.objfiles(): if obj.filename.endswith('vmlinux'): orig_vmlinux = obj.filename gdb.execute("symbol-file", to_string=True) gdb.execute("symbol-file {0}".format(orig_vmlinux)) self.loaded_modules = [] module_list = modules.module_list() if not module_list: gdb.write("no modules found\n") else: [self.load_module_symbols(module) for module in module_list] for saved_state in saved_states: saved_state['breakpoint'].enabled = saved_state['enabled']
def print_item(self, ptr, offset=gdb.Value(0), level=0): self.seen.add(int(ptr)) addr = ptr["addr"] addr += offset size = int128(ptr["size"]) alias = ptr["alias"] klass = "" if not isnull(alias): klass = " (alias)" elif not isnull(ptr["ops"]): klass = " (I/O)" elif bool(ptr["ram"]): klass = " (RAM)" gdb.write( "%s%016x-%016x %s%s (@ %s)\n" % (" " * level, int(addr), int(addr + (size - 1)), ptr["name"].string(), klass, ptr), gdb.STDOUT, ) if not isnull(alias): gdb.write( "%s alias: %s@%016x (@ %s)\n" % (" " * level, alias["name"].string(), ptr["alias_offset"], alias), gdb.STDOUT, ) self.queue.append(alias) subregion = ptr["subregions"]["tqh_first"] level += 1 while not isnull(subregion): self.print_item(subregion, addr, level) subregion = subregion["subregions_link"]["tqe_next"]
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)
def print_disassembly(self): ''' Attempts to print some disassembled instructions from the function containing $pc to GDB's STDOUT. If GDB is unable to print the disassembled instructions, an error message will be printed. If GDB's version is less than 7.3, the entire disassembled function will be printed (if possible). Otherwise only a subset of the function will be printed. This behavior is due to a bug in the Python API of earlier versions of GDB. In these versions, the results of the 'disassemble' command are always printed directly to GDB's STDOUT rather than optionally being suppressed and passed as a return value via the Python API. ''' if gdb_ver() < "7.3": try: gdb.execute("disas $pc", False, True) except RuntimeError as e: warnings.warn(e) return try: disas = gdb.execute("disas $pc", False, True).splitlines() except RuntimeError as e: warnings.warn(e) pos = 0 for line in disas: if self._re_gdb_pc.match(line): break pos += 1 gdb.write("\n".join(disas[max(pos-5, 0):pos+5]))
def stop(self): global currentbufoffset currentbufoffset = 0 if retint('type') >= 105: gdb.write(str(gdb.execute("p p.buf")), gdb.STDOUT) return True return False
def stop(self): module = gdb.parse_and_eval("mod") module_name = module['name'].string() cmd = self.gdb_command # enforce update if object file is not found cmd.module_files_updated = False # Disable pagination while reporting symbol (re-)loading. # The console input is blocked in this context so that we would # get stuck waiting for the user to acknowledge paged output. show_pagination = gdb.execute("show pagination", to_string=True) pagination = show_pagination.endswith("on.\n") gdb.execute("set pagination off") if module_name in cmd.loaded_modules: gdb.write("refreshing all symbols to reload module " "'{0}'\n".format(module_name)) cmd.load_all_symbols() else: cmd.load_module_symbols(module) # restore pagination state gdb.execute("set pagination %s" % ("on" if pagination else "off")) return False
def print_usage(self): gdb.write("""Missing argument. Usage: scylla thread <seastar::thread_context pointer> - switches to given seastar thread scylla thread apply all <cmd> - executes cmd in the context of each seastar thread """)
def invoke(self, args, from_tty): argv = gdb.string_to_argv(args) redmagic_info = gdb.execute('info shared redmagic', to_string=True).split('\n')[-2].split() redmagic_start = int(redmagic_info[0], 16) redmagic_end = int(redmagic_info[1], 16) search = argv[0] verbose = False gdb.execute('break red_asm_resume_eval_block') while True: rip = int(gdb.parse_and_eval('$rip')) if redmagic_start < rip < redmagic_end: li = gdb.execute('x/i {}'.format(rip), to_string=True) if 'red_asm_resume_eval_block' in li: gdb.execute('si', to_string=True) else: gdb.execute('n', to_string=True) else: regs_info = gdb.execute('info all-registers', to_string=True) if search in regs_info: stack = gdb.execute('bt', to_string=True) # filter out methods that are called from the tracer such as memcpy etc if 'red_asm_begin_block' not in stack: sr = '\n\t'.join([r for r in regs_info.split('\n') if search in r]) gdb.write('search pattern found in: \n\t{}'.format(sr)) return gdb.execute('si', to_string=True)
def print_box(number, f, sal, context, arguments): filename = "N/A" color = "" if sal.symtab != None: filename = sal.symtab.filename else: color = "\033[90m" line = sal.line firstColLen = len(str(number))+2 # The header buf = get_frame_header(firstColLen, f, sal, color) # Info line fileinfo, fileinfo_len = get_fileinfo(filename, line) buf += "│ "+str(number)+" │\033[39;0m" + fileinfo + get_endline(columns-fileinfo_len-firstColLen-4,color) # Display the frame arguments if arguments == True: buf += get_flat_frame_arguments(firstColLen, f, color) # Display some code if context > 0 and sal.symtab != None: srcline = get_code_lines(firstColLen, filename , line, context-1, color) buf += get_new_row(firstColLen) + srcline # Footer buf += "└"+ get_hline(firstColLen) +'┴'+ get_hline(int(columns)-3-firstColLen)+'┘\033[39;0m\n' gdb.write(buf)
def _describe(self, x): try: if (x["index"][1] != 'None'): Oracle.network.add_node(x["index"]) Oracle.described.append(x) except gdb.MemoryError: gdb.write("debug: encountered invalid memory\n")
def openlog(self, filename, quiet=False): if self.LogFile: self.LogFile.close() self.LogFile = SharedFile(filename) if not quiet: gdb.write("Logging to %s\n" % (self.LogFile.name,)) labels.clear() self.LogFile.seek(0) for lineno, line in enumerate(self.LogFile): if not line.startswith("! "): continue rest = line[2:].rstrip() cmd = rest.split(" ", 1)[0] rest = rest[len(cmd)+1:] if cmd == "replace": k, v, t = rest.split(" ", 2) labels.label(k, v, t) continue gdb.write("Unhandled log command: {}\n".format(line)) self.LogFile.record_end()
def invoke(self, arg, for_tty): c = str(gdb.lookup_global_symbol('callouts::_callouts').value()) callouts = re.findall('\[([0-9]+)\] = (0x[0-9a-zA-Z]+)', c) gdb.write("%-5s%-40s%-40s%-30s%-10s\n" % ("id", "addr", "function", "abs time (ns)", "flags")) # We have a valid callout frame for desc in callouts: id = int(desc[0]) addr = desc[1] callout = gdb.parse_and_eval('(struct callout *)' + addr) fname = callout['c_fn'] # time t = int(callout['c_to_ns']) # flags CALLOUT_ACTIVE = 0x0002 CALLOUT_PENDING = 0x0004 CALLOUT_COMPLETED = 0x0020 f = int(callout['c_flags']) flags = ("0x%04x " % f) + \ ("A" if (callout['c_flags'] & CALLOUT_ACTIVE) else "") + \ ("P" if (callout['c_flags'] & CALLOUT_PENDING) else "") + \ ("C" if (callout['c_flags'] & CALLOUT_COMPLETED) else "") # dispatch time ns ticks callout function gdb.write("%-5d%-40s%-40s%-30s%-10s\n" % (id, callout, fname, t, flags))
def to_string(self): try: m = self.pattern.match(str(self.val.type)) nti = gdb.parse_and_eval("NTI_" + m.group(2) + "_").address return self.reprEnum(self.val, nti) except Exception as e: gdb.write("reprEnum exception: " + str(e) + "\n", gdb.STDERR)
def __call__(self, pending_frame): if self.recurse_level > 0: gdb.write("TestUnwinder: Recursion detected - returning early.\n") return None self.recurse_level += 1 TestUnwinder.inc_count() if TestUnwinder.test == 'check_user_reg_pc' : pc = pending_frame.read_register('pc') pc_as_int = int(pc.cast(gdb.lookup_type('int'))) # gdb.write("In unwinder: pc=%x\n" % pc_as_int) elif TestUnwinder.test == 'check_pae_pc' : pc = gdb.parse_and_eval('$pc') pc_as_int = int(pc.cast(gdb.lookup_type('int'))) # gdb.write("In unwinder: pc=%x\n" % pc_as_int) elif TestUnwinder.test == 'check_undefined_symbol' : try: val = gdb.parse_and_eval("undefined_symbol") except Exception as arg: pass self.recurse_level -= 1 return None
def invoke(self, arg, from_tty): argv = gdb.string_to_argv(arg) if len(argv) != 1: gdb.write('usage: qemu coroutine <coroutine-pointer>\n') return bt_jmpbuf(coroutine_to_jmpbuf(gdb.parse_and_eval(argv[0])))
def invoke(self, argument, from_tty): filename = argument if filename == '': raise Exception("need a filename as argument") mappings = MappingsParser().maps for mapping in mappings: gdb.write('start: {}\n'.format(mapping.start_addr))
def invoke(self, arg, from_tty): if not arg: gdb.write('Missing argument. Usage: osv trace save <filename>\n') return gdb.write('Saving traces to %s ...\n' % arg) save_traces_to_file(arg)
def print_instruction_at(self,addr,stack_percentage): gdb.write(str(round(stack_percentage,2))+":") str_to_eval = "info line *"+hex(addr) #gdb.execute(str_to_eval) res = gdb.execute(str_to_eval,to_string = True) # get information from results string: words = res.split() valid = False if words[0] == 'No': #no line info... pass else: valid = True line = int(words[1]) idx = words[3].rfind("/"); #find first backslash if idx>0: name = words[3][idx+1:]; path = words[3][:idx]; else: name = words[3]; path = ""; block = gdb.block_for_pc(addr) func = block.function if str(func) == "None": func = block.superblock.function if valid: print("Line: ",line," in ",path,"/",name,"in ",func) return name,path,line,func
def invoke(self, arg, from_tty): global execution_state global old_execution_state if "*sac(" in arg: blocks = saclib.extract_sacblocks(arg) if not variable_stack: current_variables = list() else: current_variables = variable_stack gdb_string = saclib.replace_sacblocks(arg, blocks, current_variables) if gdb_string: gdb.execute(gdb_string) else: gdb.write("Error with contents of a *sac() block\n") else: if arg.strip() == "run": old_execution_state = execution_state execution_state = 2 gdb.execute("run", False) if arg.strip() == "continue": old_execution_state = execution_state execution_state = 2 gdb.execute("continue", False) elif arg.strip() == "stop": old_execution_state = execution_state execution_state = 0 gdb.execute("stop", False) elif arg.strip() == "step": old_execution_state = execution_state execution_state = 1 gdb.execute("step", False)
def __exit__(self, *_): if self.new_regs: self.gdb_thread.switch() self.restore_regs(self.old_regs) self.old_gdb_thread.switch() self.old_frame.select() gdb.write('Switched to thread %d\n' % self.old_gdb_thread.num)
def stop(self): if self.banner: if callable(self.banner): self.banner(self.matches, self.values) else: gdb.write(self.banner) return True
def dumpFrag(fragPtr, indent = 0): count = 0 while fragPtr != 0 and count < 1500: count+=1 obj = fragPtr.dereference() gdb.write(" "*indent + str(fragPtr) + ": " + str(obj) + "\n") fragPtr = obj["nextFragment"]
def banner(matches, values): gdb.write("""\ Break before closing node: FUNCTION: %s NODE....: %s (filter: %s) """ % (method, node, matches["node_id"].__doc__))
def invoke(self, arg, from_tty): # delete all breakpoints gdb.execute("d") gdb.execute("break free") # loop iterations only in free() gdb.execute("continue") max = 1 << 24 i = 0 initial = self.memory() for i in range(max): try: mem = gdb.selected_frame().read_var("mem") current = self.mallocUsableSize(mem) except gdb.error: break bt = gdb.execute("bt", False, True) # 5 % if (current > initial*0.05): gdb.write("Current: %lu bytes, initial %lu bytes (%i iteration)\n" % (current, initial, i)) gdb.write("Backtrace before current free():\n%s\n" % (bt)) return if ((i % 100000) == 0): gdb.write("Iteration %i backtrace:\n%s\n" % (i, bt)) gdb.execute("continue", False, True) gdb.write("Finished with %i iterations\n" % (i)) gdb.write("Last backtrace:\n%s\n" % (bt))
def on_exit(self, event): if len(self.function_names) >= 2: if self.direct_connection_found: gdb.write("Direct connection found.\n") else: gdb.write("No direct connection between functions.\n") self.dg.save(OUTFILE)
def field_list(self, peripheral, register): try: periph = svd_file.peripherals[peripheral] reg = periph.registers[register] return list(reg.fields.iterkeys()) except: gdb.write("Register {} doesn't exist on {}\n".format(register, peripheral)) return []
def decorate(self, frame): if self.method_bci_stack == None: return [ frame ] else: try: decorators = [] pairs = self.method_bci_stack # debug_write("converting method_bci_stack = %s\n" % self.method_bci_stack) l = len(pairs) for i in range(l): pair = pairs[i] # debug_write("decorating pair %s\n" % pair) decorator = self.make_decorator(frame, pair, i == (l - 1)) decorators.append(decorator) return decorators except Exception as arg: gdb.write("!!! decorate oops %s !!!\n" % arg) return [ frame ]
def __call__(self, pending_frame): if self.recurse_level > 0: gdb.write("TestUnwinder: Recursion detected - returning early.\n") return None self.recurse_level += 1 TestUnwinder.inc_count() try: val = gdb.parse_and_eval("undefined_symbol") except Exception as arg: pass self.recurse_level -= 1 return None
def invoke(self, arg, from_tty): addr = gdb.parse_and_eval(arg) addr = ulong(addr) ptep = ulong(gdb.lookup_symbol('mmu::page_table_root')[0].value().address) level = 4 while level >= 0: ptep1 = phys_cast(ptep, ulong_type) pte = ulong(ptep1.dereference()) gdb.write('%016x %016x\n' % (ptep, pte)) if not pte & 1: break if level > 0 and pte & 0x80: break if level > 0: pte &= ~ulong(0x80) pte &= ~ulong(0x8000000000000fff) level -= 1 ptep = pte + pt_index(addr, level) * 8
def invoke(self, arg, for_tty): exit_thread_context() state = vmstate() for t in state.thread_list: with thread_context(t, state): cpu = t['_cpu'] tid = t['_id'] fr = gdb.selected_frame() # Non-running threads have always, by definition, just called # a reschedule, and the stack trace is filled with reschedule # related functions (switch_to, schedule, wait_until, etc.). # Here we try to skip such functions and instead show a more # interesting caller which initiated the wait. fname = '??' sal = fr.find_sal() while sal.symtab: fname = sal.symtab.filename b = os.path.basename(fname); if b in ["arch-switch.hh", "sched.cc", "sched.hh", "mutex.hh", "mutex.cc", "mutex.c", "mutex.h"]: fr = fr.older(); sal = fr.find_sal(); else: if fname[:6] == "../../": fname = fname[6:] break; if fr.function(): function = fr.function().name else: function = '??' status = str(t['_status']['_M_i']).replace('sched::thread::', '') gdb.write('%4d (0x%x) cpu%s %-10s %s at %s:%s vruntime %12d\n' % (tid, ulong(t.address), cpu['arch']['acpi_id'], status, function, fname, sal.line, t['_vruntime'], ) ) show_thread_timers(t)
def edit(self, paths): gdb.write("Building... ", gdb.STDERR) path = build(paths, self.builds, self.default_build) if not path: gdb.write("Failed\n", gdb.STDERR) return False gdb.write("Done\n") if not patch_objfile(path, self.patches, self.families): gdb.write("Failed to change {0}\n".format(path), gdb.STDERR) return True
def show_virtio_driver(v): gdb.write('%s at %s\n' % (v.dereference().dynamic_type, v)) vb = v.cast(virtio_driver_type.pointer()) for qidx in range(0, vb['_num_queues']): q = vb['_queues'][qidx] gdb.write(' queue %d at %s\n' % (qidx, q)) avail_guest_idx = q['_avail']['_idx']['_M_i'] avail_host_idx = q['_avail_event']['_M_i'] gdb.write(' avail g=0x%x h=0x%x (%d)\n' % (avail_host_idx, avail_guest_idx, avail_guest_idx - avail_host_idx)) used_host_idx = q['_used']['_idx']['_M_i'] used_guest_idx = q['_used_event']['_M_i'] gdb.write( ' used h=0x%x g=0x%x (%d)\n' % (used_host_idx, used_guest_idx, used_host_idx - used_guest_idx)) used_flags = q['_used']['_flags']['_M_i'] gdb.write(' used notifications: %s\n' % ('disabled' if used_flags & 1 else 'enabled', ))
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()
def invoke(self, argument, from_tty): parser = self.NoexitArgumentParser(prog=self._command, description=self.__doc__) parser.add_argument('limit', metavar='limit', type=int, nargs='?', default=sys.maxsize, help='Only consider [limit] stack frames') parser.add_argument('--skip', metavar='N', nargs='?', type=int, default=0, help='Skip first [N] stack frames') parser.add_argument( '--ignore-pc', action='store_true', default=False, help='Ignore program counter for frame equivalence') parser.add_argument( '--show-source', action='store_true', default=False, help='Show source file and line info, if available') args = parser.parse_args(gdb.string_to_argv(argument)) traces = [] for thread in gdb.inferiors()[0].threads(): traces.append( stacks.StackTrace(thread, args.skip, args.limit, args.ignore_pc, args.show_source)) uniq = {} for stack in traces: uniq.setdefault(stack, []).append(stack.gdb_thread_id) sorter = lambda d: sorted( d.items(), key=lambda item: len(item[1]), reverse=True) gdb.write( "\n== Printing {} unique stack(s) from {} thread(s)\n\n".format( len(uniq), len(traces))) for k, v in sorter(uniq): gdb.write( "Stack common for {} thread(s); Thread id(s): {}\n".format( len(v), sorted(v))) gdb.write(str(k)) gdb.write("\n\n") gdb.flush()
def invoke(self, args, from_tty): args = gdb.string_to_argv(args) argc = len(args) if argc == 1: gdb.write("Loading SVD file {}...\n".format(args[0])) f = args[0] elif argc == 2: gdb.write("Loading SVD file {}/{}...\n".format(args[0], args[1])) f = pkg_resources.resource_filename( "cmsis_svd", "data/{}/{}".format(args[0], args[1])) else: raise gdb.GdbError( "Usage: svd_load <vendor> <device.svd> or svd_load <path/to/filename.svd>\n" ) try: SVD(SVDFile(f)) except Exception as e: raise gdb.GdbError("Could not load SVD file {} : {}...\n".format( f, e))
def invoke(self, arg, from_tty): self.module_paths = arg.split() self.module_paths.append(os.getcwd()) # enforce update self.module_files = [] self.module_files_updated = False self.load_all_symbols() if hasattr(gdb, 'Breakpoint'): if self.breakpoint is not None: self.breakpoint.delete() self.breakpoint = None self.breakpoint = LoadModuleBreakpoint( "kernel/module.c:do_init_module", self) else: gdb.write("Note: symbol update on module loading not supported " "with this gdb version\n")
def _debugbreak_step(): global temp_breakpoint_num try: frame = gdb.selected_frame() except gdb.error as e: # 'No frame is currently selected.' gdb.write(e.args[0] + '\n', gdb.STDERR) return instn_len = _next_instn_jump_len(frame) if instn_len is None: gdb.execute('stepi') else: loc = '*($pc + %d)' % (instn_len, ) bp = gdb.Breakpoint(loc, gdb.BP_BREAKPOINT, internal=True) bp.silent = True temp_breakpoint_num = bp.number gdb.events.stop.connect(on_stop_event) gdb.execute('jump ' + loc)
def invoke (self, arg, from_tty): ignoreFiles = set(['system/jlib/jlzw.cpp', 'system/jlib/jlog.cpp', 'system/jlib/jencrypt.cpp', 'system/jlib/jcrc.cpp', 'system/security/zcrypt/aes.cpp', 'common/workunit/wuattr.cpp', 'ecl/hql/reservedwords.cpp']) ignoreVars = set(['statsMetaData', 'roAttributes', 'roAttributeValues', 'RandomMain']) ignorematch = re.compile(" StatisticsMapping ") varmatch = re.compile("[^a-zA-Z_0-9:]([a-zA-Z_][a-z0-9_A-Z:]*)(\\[.*])?;$") goodfilematch = re.compile("^File /hpcc-dev/HPCC-Platform/(.*[.]cpp):$") filematch = re.compile("^File (.*):$") infile = None file_written = False allvars = gdb.execute("info variables", False, True) for line in allvars.splitlines(): m = goodfilematch.search(line) if m: infile = m.group(1) file_written = False if infile in ignoreFiles: infile = None elif filematch.search(line): infile = None elif infile: if (ignorematch.search(line)): continue m = varmatch.search(line) if m: varname = m.group(1) if varname in ignoreVars: continue sym = gdb.lookup_global_symbol(varname) if not sym: sym = gdb.lookup_static_symbol(varname) if sym and not sym.is_constant: if not file_written: gdb.write('\n' + infile + ':\n') file_written = True gdb.write(' {} = {}\n'.format(sym.name, sym.value(gdb.newest_frame()))) # There are some variables that gdb generates names incorrectly - e.g. if type is const char *const... # We don't care about them... But uncomment the next two lines if you want to see them or if other things seem to be missing # if not sym: # gdb.write(line + ' ' + varname+' not resolved\n') elif line: pass
def on_break(cls): should_continue = False # get the current frame and inferior frame = gdb.selected_frame() inf = gdb.selected_inferior() # retrieve instruction ins = frame.architecture().disassemble(frame.pc())[0] m = re.match(r'^bkpt\s+((?:0x)?[0-9a-f]+)$', ins['asm'].lower()) if m: raw = m.group(1) # we've matched a breakpoint, decode the immediate bkpt_n = int(raw, 16 if raw.startswith('0x') else 10) # breakpoint 0xab indicates a semi-hosting call if bkpt_n == 0xAB: # retrieve the call type and obj registers # note: we would like to use `Frame.read_registers()` # for this, but its only available on gdb 7.8 or # newer r0 = gdb.parse_and_eval('$r0') r1 = gdb.parse_and_eval('$r1') call_type = int(r0) arg_addr = int(r1) if call_type == 0x05: cls.handle_write(inf, arg_addr) should_continue = True else: raise NotImplementedError( 'Call type 0x{:X} not implemented'.format(call_type)) else: gdb.write("***Breakpoint received***\n") else: raise ValueError('no bkpt instruction') if should_continue: gdb.execute('set $do_continue = 1') else: gdb.execute('set $do_continue = 0')
def invoke(self, args, from_tty): try: f = str(args).split(" ")[0] gdb.write("Loading SVD file {}...\n".format(f)) except: gdb.write("Please provide a filename (svd_load [filename])\n") return try: svd_file = SVDFile(f) SVD(svd_file) gdb.write("Done!\n") except: gdb.write("Error loading file {}\n".format(f))
def get_trace_buffer(): inf = gdb.selected_inferior() try: trace_buff = gdb.parse_and_eval('uk_trace_buffer') trace_buff_size = trace_buff.type.sizeof trace_buff_addr = int(trace_buff.address) trace_buff_writep = int(gdb.parse_and_eval('uk_trace_buffer_writep')) except gdb.error: gdb.write("Error getting the trace buffer. Is tracing enabled?\n") raise gdb.error if (trace_buff_writep == 0): # This can happen as effect of compile optimization if none of # tracepoints were called used = 0 else: used = trace_buff_writep - trace_buff_addr return bytes(inf.read_memory(trace_buff_addr, used))
def get_ptrs(): frame = saved_frame = gdb.selected_frame() ptrs = [] # UGH generators please while True: try: block = frame.block() for sym in block: typ = sym.type if typ.code == gdb.TYPE_CODE_PTR: value = frame.read_var(sym) if not value.is_optimized_out and not (value == 0): ptrs.append(value) # XXX: structs except RuntimeError, msg: gdb.write("Exception: %s\n" % msg) frame = frame.older() if frame is None: break gdb.execute("up-silently")
def stop(self): try: global in_heap_func if in_heap_func: return False in_heap_func = True args = [get_args[i]() for i in range(self._arg_cnt)] gdb.write('{}({})'.format( self._fn_name, ', '.join('0x{:x}'.format(arg) for arg in args))) if self._finish_bp is not None: self._finish_bp.delete() self._finish_bp = HeapFinishBreakpoint(self._fn_name, retaddr=get_retaddr()) return False except: traceback.print_exc() raise
def invoke(self, arg, from_tty): param = gdb.parse_and_eval(arg) strValue = DollarPrintFunction.invoke_static(param) if strValue: gdb.write( NimStringPrinter(strValue).to_string() + "\n", gdb.STDOUT) # could not find a suitable dollar overload. This here is the # fallback to get sensible output of basic types anyway. elif param.type.code == gdb.TYPE_CODE_ARRAY and param.type.target( ).name == "char": gdb.write(param.string("utf-8", "ignore") + "\n", gdb.STDOUT) elif param.type.code == gdb.TYPE_CODE_INT: gdb.write(str(int(param)) + "\n", gdb.STDOUT) elif param.type.name == "NIM_BOOL": if int(param) != 0: gdb.write("true\n", gdb.STDOUT) else: gdb.write("false\n", gdb.STDOUT)
def switch_to_thread(self, thread, tries): old_thread = sys_info.get_current_thread_ptr() utils.disable_all_bp() bp = utils.conf_curr_thread_watchpoint() tmp_tries = tries if thread is None: utils.gdb_continue() else: while sys_info.get_current_thread_ptr() != thread and tmp_tries > 0: utils.gdb_continue() tmp_tries -= 1 if tmp_tries == 0 and thread is not None: gdb.write(f"The thread was not scheduled in last {tries} context" f" switches, we are still on {hex(old_thread)}\n") else: gdb.write(f"Current thread is: " f"{hex(sys_info.get_current_thread_ptr())} " f"old: {hex(old_thread)}\n") utils.delete_bp(bp) utils.enable_all_bp()
def eval(arg): parse_tree = parser.parse(arg) #from arpeggio.export import PTDOTExporter #PTDOTExporter().exportFile(tree, "tree.dot") #import pprint #pprint.PrettyPrinter(indent=4).pprint(parse_tree) expr.scopes = list() expr.underscores = list() expr_tree = visit_parse_tree(parse_tree, DuelVisitor(debug=False)) assert len(expr.scopes) == 0 assert len(expr.underscores) == 0 for name, val in expr_tree.eval(): val = expr.val2str(val) if name == val: gdb.write('= {0}\n'.format(val)) else: gdb.write('{0} = {1}\n'.format(name, val))
def invoke(self, arg, from_tty): gdb.write("Thread, BQL (iothread_mutex), Replay, Blocked?\n") for thread in gdb.inferiors()[0].threads(): thread.switch() iothread = gdb.parse_and_eval("iothread_locked") replay = gdb.parse_and_eval("replay_locked") frame = gdb.selected_frame() if frame.name() == "__lll_lock_wait": frame.older().select() mutex = gdb.parse_and_eval("mutex") owner = gdb.parse_and_eval("mutex->__data.__owner") blocked = ("__lll_lock_wait waiting on %s from %d" % (mutex, owner)) else: blocked = "not blocked" gdb.write("%d/%d, %s, %s, %s\n" % (thread.num, thread.ptid[1], iothread, replay, blocked))
def invoke(self, arg, from_tty): # arg: quick name filter function_names = self.extract_function_names() if arg: function_names = [ n for n in function_names if n.find(arg) >= 0 ] count = 0 verbose = (len(function_names) > 1000) for name in function_names: FunctionEnterBreakpoint(name) count += 1 if verbose and count % 128 == 0: gdb.write( '\r%d / %d breakpoints set' % (count, len(function_names)), gdb.STDERR) if verbose: gdb.write( '\r%(n)d / %(n)d breakpoints set\n' % {'n': len(function_names)}, gdb.STDERR)
def stop(self): is_right_process = False if self.proc_cmd in get_current_proc_comm(): is_right_process = True if not is_right_process: return False gdb.write( "{entry}_{exit}(exit)\n".format( entry=self.entry_symbol, exit=self.exit_symbol ) ) # call the entry callback if self.exit_callback: self.exit_callback(self.parameter) return self.break_at_exit
def get_cvmat_info(val): flags = val['flags'] depth = flags & 7 channels = 1 + (flags >> 3) & 63 if depth == 0: cv_type_name = 'CV_8U' data_symbol = 'B' elif depth == 1: cv_type_name = 'CV_8S' data_symbol = 'b' elif depth == 2: cv_type_name = 'CV_16U' data_symbol = 'H' elif depth == 3: cv_type_name = 'CV_16S' data_symbol = 'h' elif depth == 4: cv_type_name = 'CV_32S' data_symbol = 'i' elif depth == 5: cv_type_name = 'CV_32F' data_symbol = 'f' elif depth == 6: cv_type_name = 'CV_64F' data_symbol = 'd' else: gdb.write('Unsupported cv::Mat depth\n', gdb.STDERR) return rows = val['rows'] cols = val['cols'] line_step = val['step']['p'][0] gdb.write(cv_type_name + ' with ' + str(channels) + ' channels, ' + str(rows) + ' rows and ' + str(cols) + ' cols\n') data_address = _to_string(val['data']).split()[0] data_address = int(data_address, 16) return (cols, rows, channels, line_step, data_address, data_symbol)
def invoke(self, arg, from_tty): if Ether is None: print("ERROR: This command requires scapy to be installed.") return arg_list = gdb.string_to_argv(arg) if len(arg_list) == 0: print("Usage: ovs_dump_packets <struct dp_packet_batch|" "dp_packet> [tcpdump options]") return symb_name = arg_list[0] tcpdump_args = arg_list[1:] if not tcpdump_args: # Add a sane default tcpdump_args = ["-n"] val = gdb.parse_and_eval(symb_name) while val.type.code == gdb.TYPE_CODE_PTR: val = val.dereference() pkt_list = [] if str(val.type).startswith("struct dp_packet_batch"): for idx in range(val['count']): pkt_struct = val['packets'][idx].dereference() pkt = self.extract_pkt(pkt_struct) if pkt is None: continue pkt_list.append(pkt) elif str(val.type) == "struct dp_packet": pkt = self.extract_pkt(val) if pkt is None: return pkt_list.append(pkt) else: print("Error, unsupported argument type: {}".format(str(val.type))) return stdout = tcpdump(pkt_list, args=tcpdump_args, getfd=True, quiet=True) gdb.write(stdout.read().decode("utf8", "replace"))
def invoke(self, ptr, kls_name): ptr = ptr.cast(null_eo_object_ptr.type) # Cast to correct type if int(ptr) == 0: gdb.write('Object is not a valid pointer (NULL).\n') return null_void_ptr kls_name = kls_name.string() extns = ptr['klass']['mro'] kls = None i = 0 while int(extns[i]) != 0: if extns[i]['desc']['name'].string() == kls_name: kls = extns[i] i += 1 if kls is None: gdb.write( 'Class "{}" not found in the object mro.\n'.format(kls_name)) return null_void_ptr # Check if not mixin if int(kls['desc']['type'].cast(zero_uintptr_t.type)) != 3: return gdb.parse_and_eval('(void *) (((char *) {}) + {})'.format( ptr, kls['data_offset'])) else: extn_off = ptr['klass']['extn_data_off'] if int(extn_off) == 0: return null_void_ptr i = 0 while int(extn_off[i]['klass']) != 0: kls = extn_off[i]['klass'] if kls['desc']['name'].string() == kls_name: return gdb.parse_and_eval( '(void *) (((char *) {}) + {})'.format( ptr, kls['data_offset'])) i += 1 return null_void_ptr
def stop(self): # dump symbols out to disk uintptr_t = gdb.lookup_type('uintptr_t') ssize_t = gdb.lookup_type('ssize_t') mem_loc = int(gdb.parse_and_eval('symmem').cast(uintptr_t)) mem_sz = int(gdb.parse_and_eval('symsz').cast(ssize_t)) memvw = gdb.selected_inferior().read_memory(mem_loc, mem_sz) # work out where new library is loaded base_addr = int(gdb.parse_and_eval('dso->base').cast(uintptr_t)) fn = None with tempfile.NamedTemporaryFile(suffix='.so', delete=False) as f: f.write(memvw) fn = f.name gdb.write('Loading symbols at base 0x%x...\n' % (int(base_addr))) add_symbol_file(fn, int(base_addr)) atexit.register(os.unlink, fn) return False
def __init__(self, typecache): super(SpiderMonkeyUnwinder, self).__init__("SpiderMonkey") self.typecache = typecache self.unwinder_state = None # Disabled by default until we figure out issues in gdb. self.enabled = False gdb.write("SpiderMonkey unwinder is disabled by default, to enable it type:\n" + "\tenable unwinder .* SpiderMonkey\n") # Some versions of gdb did not flush the internal frame cache # when enabling or disabling an unwinder. This was fixed in # the same release of gdb that added the breakpoint_created # event. if not hasattr(gdb.events, "breakpoint_created"): gdb.write("\tflushregs\n") # We need to invalidate the unwinder state whenever the # inferior starts executing. This avoids having a stale # cache. gdb.events.cont.connect(self.invalidate_unwinder_state) assert self.test_sentinels()
def __init__(self, blob, sp, pc, bp, bcp, name, codetype): # t("OpenJDKUnwinderCacheEntry.__init__") self.blob = blob self.sp = sp self.pc = pc self.bp = bp self.codetype = codetype try: if codetype == "compiled": self.method_info = CompiledMethodInfo(self) elif codetype == "native": self.method_info = NativeMethodInfo(self) elif codetype == "interpreted": self.method_info = InterpretedMethodInfo(self, bcp) elif codetype == "stub": self.method_info = StubMethodInfo(self, name) else: self.method_info = None except Exception as arg: gdb.write("!!! failed to cache info for %s frame [pc: 0x%x sp:0x%x bp 0x%x] !!!\n!!! %s !!!\n" % (codetype, pc, sp, bp, arg)) self.method_info = None
def load_module_symbols(self, module): module_name = module['name'].string() module_addr = str(module['module_core']).split()[0] module_file = self._get_module_file(module_name) if not module_file and not self.module_files_updated: self._update_module_files() module_file = self._get_module_file(module_name) if module_file: gdb.write("loading @{addr}: {filename}\n".format( addr=module_addr, filename=module_file)) cmdline = "add-symbol-file {filename} {addr}{sections}".format( filename=module_file, addr=module_addr, sections=self._section_arguments(module)) gdb.execute(cmdline, to_string=True) if module_name not in self.loaded_modules: self.loaded_modules.append(module_name) else: gdb.write("no module object found for '{0}'\n".format(module_name))