示例#1
0
文件: ls.py 项目: jjjj222/setup
    def invoke (self, argv, from_tty):
        try:
            pc = gdb.selected_frame().pc()
        except:
            print "No code"
            return

        print argv
        print pc
        print gdb.block_for_pc(pc).function
        print gdb.find_pc_line(pc).symtab.fullname()
        print gdb.find_pc_line(pc).symtab.filename
        print gdb.find_pc_line(pc).line
def reprG(ptr):
	if long(ptr) == 0:
		return "o G:null"
	obj = ptr.dereference()
	vp = gdb.lookup_type('void').pointer()

	pc = ptr['sched']['pc'].cast(vp)
	# python2 will not cast pc (type void*) to an int cleanly
	# instead python2 and python3 work with the hex string representation
	# of the void pointer which we can parse back into an int.
	# int(pc) will not work.
	try:
		#python3 / newer versions of gdb
		pc = int(pc)
	except gdb.error:
		pc = int(str(pc), 16)
	blk = gdb.block_for_pc(pc)

	attrs = {
		"flg": '*' if ptr['m'] else 'o',
		"goid": obj["goid"],
		"status": sts[int(obj["status"])],
		"func": blk.function,
		"m": reprM(obj["m"], short=True)
	}
	return "%(flg)s G:%(goid)s %(status)s %(func)s m=<%(m)s>" % attrs
示例#3
0
	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
示例#4
0
		def setup(fn_name):
			fn_full_name = self.prefix + fn_name
			print 'setting up breakpoint for', fn_full_name
			on_enter_instance = on_enter(fn_name, fn_full_name)

			# free() does not need a finishing breakpoint, because it returns a void
			# without this the leak detector is unstable, because
			# on some systems je_free() has a bunch of cross jumps somewhere:
			# anight@dura3:~/projects/test> gdb --batch -ex 'disassemble je_free' ./a.out  | grep jmpq | grep -v je_free
			#   0x000000000040554c <+428>:   jmpq   0x42aaa0 <je_tcache_event_hard>
			#   0x00000000004055a3 <+515>:   jmpq   0x40f0a0 <je_arena_dalloc_small>
			#   0x000000000040564e <+686>:   jmpq   0x421240 <je_huge_dalloc>
			#   0x000000000040566a <+714>:   jmpq   0x425aa0 <je_quarantine>
			#   0x00000000004056cb <+811>:   jmpq   0x40f2b0 <je_arena_dalloc_large>
			#
			# Luckily, this does not apply to all other memory functions

			if fn_name == 'free':
				return

			arch = gdb.selected_frame().architecture()
			sym = gdb.lookup_global_symbol(fn_full_name, gdb.SYMBOL_FUNCTIONS_DOMAIN)
			block = gdb.block_for_pc(long(sym.value().address))
			ptr = block.start
			while ptr < block.end:
				da = arch.disassemble(ptr)[0]
				if da['asm'].rstrip().endswith('retq'):
					print 'setting up finish breakpoint for', da
					on_result_ready_instance = on_result_ready(on_enter_instance, '*0x%lx' % da['addr'])
				ptr += da['length']
    def __call__(self, pending_frame):
        pc_desc = pending_frame.architecture().registers().find("pc")
        pc = pending_frame.read_register(pc_desc)

        sp_desc = pending_frame.architecture().registers().find("sp")
        sp = pending_frame.read_register(sp_desc)

        block = gdb.block_for_pc(int(pc))
        if block is None:
            return None
        func = block.function
        if func is None:
            return None
        if str(func) != "bar":
            return None

        fid = FrameId(pc, sp)
        unwinder = pending_frame.create_unwind_info(fid)
        if self._use_descriptors:
            unwinder.add_saved_register(pc_desc, pc)
            unwinder.add_saved_register(sp_desc, sp)
        else:
            unwinder.add_saved_register("pc", pc)
            unwinder.add_saved_register("sp", sp)
        return unwinder
示例#6
0
        def setup(fn_name):
            fn_full_name = self.prefix + fn_name
            print 'setting up breakpoint for', fn_full_name
            on_enter_instance = on_enter(fn_name, fn_full_name)

            # free() does not need a finishing breakpoint, because it returns a void
            # without this the leak detector is unstable, because
            # on some systems je_free() has a bunch of cross jumps somewhere:
            # anight@dura3:~/projects/test> gdb --batch -ex 'disassemble je_free' ./a.out  | grep jmpq | grep -v je_free
            #   0x000000000040554c <+428>:   jmpq   0x42aaa0 <je_tcache_event_hard>
            #   0x00000000004055a3 <+515>:   jmpq   0x40f0a0 <je_arena_dalloc_small>
            #   0x000000000040564e <+686>:   jmpq   0x421240 <je_huge_dalloc>
            #   0x000000000040566a <+714>:   jmpq   0x425aa0 <je_quarantine>
            #   0x00000000004056cb <+811>:   jmpq   0x40f2b0 <je_arena_dalloc_large>
            #
            # Luckily, this does not apply to all other memory functions

            if fn_name == 'free':
                return

            arch = gdb.selected_frame().architecture()
            sym = gdb.lookup_global_symbol(fn_full_name,
                                           gdb.SYMBOL_FUNCTIONS_DOMAIN)
            block = gdb.block_for_pc(long(sym.value().address))
            ptr = block.start
            while ptr < block.end:
                da = arch.disassemble(ptr)[0]
                if da['asm'].rstrip().endswith('retq'):
                    print 'setting up finish breakpoint for', da
                    on_result_ready_instance = on_result_ready(
                        on_enter_instance, '*0x%lx' % da['addr'])
                ptr += da['length']
示例#7
0
def get_block_from_pc(pc):
    '''
    :param pc: frame's resume address
    :type pc: gdb.Frame.pc()
    :returns: a gdb.Block object or None
    '''
    return gdb.block_for_pc(pc)
示例#8
0
文件: Nuttx.py 项目: wlf1136/Firmware
    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
示例#9
0
 def functionptr_to_chunks(self, value, name, path, **kwargs):
     chunks = []
     type_code = value.type.strip_typedefs().code
     if type_code == gdb.TYPE_CODE_METHOD:
         #Workaround: get address of class method
         s = unicode(value)
         idx = re.search('0x[0-9A-Fa-f]+', s).regs[0]
         func_addr = long(s[int(idx[0]):int(idx[1])], 0)
     else:
         func_addr = self.ptrval_to_ulong(value)
     function = None
     try:
         block = gdb.block_for_pc(func_addr)
     except RuntimeError:
         block = None
     while block:
         if block.function:
             function = block.function
             break
         block = block.superblock
     if function:
         func_name = function.name
     else:
         func_name = 'unknown'
     chunks += self.chunks_type_name(value, name, **kwargs)
     valuetype = self.stringify_type(value.type)
     chunks += self.changable_strvalue_to_chunks(str(func_addr), path,
                                                 valuetype, **kwargs)
     chunks.append({'str': ' '})
     chunks.append({'str': '<{}>'.format(func_name)})
     return chunks
 def _search_frame(self, frame, vertex, enclosingFrame=None):
     sal = frame.find_sal()
     try:
         block = gdb.block_for_pc(sal.pc)
     except RuntimeError as e:
         return
     for symbol in block:
         self._enqueue(symbol, parentVertex=vertex, frame=frame)
示例#11
0
def funcName(pc):
    try:
        return str(gdb.block_for_pc(pc).function)
    except RuntimeError:
        # block_for_pc is supposed to return None if it failed,
        # but actually throws RuntimeError("Cannot location object
        # file for block.")
        return "%#x" % pc
示例#12
0
 def trace_function(indent, annotation, data):
     fn, caller = data
     try:
         block = gdb.block_for_pc(long(fn))
         fn_name = block.function.print_name
     except:
         fn_name = "???"
     out_func("0x%016x %2d %19s %s %s %s\n" % (thread, cpu, format_time(time), indent, annotation, fn_name))
示例#13
0
 def __get_current_block_start_address():
     pc = int(pwngef.arch.CURRENT_ARCH.pc)
     try:
         block_start = gdb.block_for_pc(pc).start
     except RuntimeError:
         # if stripped, let's roll back 5 instructions
         block_start = disass.gdb_get_nth_previous_instruction_address(
             pc, 5)
     return block_start
示例#14
0
def func_and_offset(addr):
    '''Return the function and offset into that function of `addr`.

    If failed to find the function at the given address, return (None, None).

    '''
    # If given @plt addresses (or other problematic functions) just ignore
    # them and return an error message -- (better than raising an error?)
    try:
        block = gdb.block_for_pc(addr)
    except RuntimeError as e:
        # If this is an exception we don't know about, raise.
        if e.args != ('Cannot locate object file for block.',):
            raise

        # Attempt to work with symbols that don't have debugging information.
        retval = gdb.execute('info symbol {}'.format(addr),
                            False, True)
        # Checking for section ".text" removes @plt stubs and variables.
        if 'in section .text' not in retval:
            print('{} is not a .text location'.format(addr))
            return (None, None)

        # At the moment I believe that all awkward output (i.e. of the form
        # funcname(function, argument, types) in section .text of /home/matthew/temp_dir/gdb/gdb/gdb
        # are avoided because when there is debug info we've used the alternate
        # method. Hence, the output should be of the form
        # <funcname> + <offset> in section .text of <objfile>
        # If this isn't the case, alert user so I know there's a problem and
        # can investigate what I've missed.
        #
        # NOTE: I believe that digits are always printed in decimal -- can't
        # find any way to change this, so I believe there isn't one.
        # If this isn't the case, then I hopefully will notice the problem when
        # this function fails.
        sym_match = re.match('(\S+)( \+ (\d+))? in section .text', retval)
        if not sym_match:
            print('Cannot parse output from command `info symbol {}`.'.format(
                addr))
            return (None, None)

        offset = int(sym_match.group(3)) if sym_match.group(3) else 0
        return (sym_match.group(1), offset)

    while block.function is None:
        if block.superblock:
            block = block.superblock
        else:
            raise gdb.GdbError('Could not find enclosing function of '
                                '{} ({})'.format(addr, arg))

    offset = addr - block.start
    return (block.function.name, offset)
示例#15
0
 def _update_frame(self):
   # We used to do set_cpu_regs() here and then get a gdb.Frame, but that's
   # really slow.  We don't care too much about the detail here, so just
   # lookup the function name.
   try:
     self.block = gdb.block_for_pc(self.regs[15])
   except:
     class FakeBlock(object): pass
     self.block = FakeBlock()
     self.block.function = "??"
   while self.block.function is None:
     self.block = self.block.superblock
   self.frame_str = "0x%X in %s ()" % (self.regs[15], self.block.function)
示例#16
0
	def resolve_file_line_func(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()
		if words[0] != 'No':
			line = int(words[1])
			block = gdb.block_for_pc(addr)
			func = block.function
			if str(func) == "None":
				func = block.superblock.function
			return words[3].strip('"'), line, func
示例#17
0
 def resolve_file_line_func(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()
     if words[0] != 'No':
         line = int(words[1])
         block = gdb.block_for_pc(addr)
         func = block.function
         if str(func) == "None":
             func = block.superblock.function
         return words[3].strip('"'), line, func
示例#18
0
def fileLine(pc):
    # UGH. Iterating over a line table crashes hard in GDB 7.9.
    try:
        block = gdb.block_for_pc(pc)
    except RuntimeError:
        return "%#x" % pc
    lt = block.function.symtab.linetable()
    pcent = None
    for ltent in lt:
        if ltent.pc > pc:
            break
        pcent = ltent
    if pcent == None:
        return "%#x" % pc
    return "%s:%d" % (block.function.symtab.filename, pcent.line)
示例#19
0
 def trace_function(indent, annotation, data):
     fn, caller = data
     try:
         block = gdb.block_for_pc(long(fn))
         fn_name = block.function.print_name
     except:
         fn_name = '???'
     out_func('0x%016x %2d %19s %s %s %s\n' % (
         thread,
         cpu,
         format_time(time),
         indent,
         annotation,
         fn_name,
     ))
示例#20
0
def find_symbol(addr: Ptr) -> Optional[gdb.Symbol]:
    """
    Find the top-level Symbol associated with an address.
    Due to limitations of the GDB Python bindings this will only find
    symbols with debug information (not what gdb calls "minimal symbols").
    """
    try:
        block = gdb.block_for_pc(addr.addr())
    except RuntimeError:
        return None

    while block is not None and not block.function:
        block = block.superblock

    return block.function if block is not None else None
示例#21
0
文件: loader.py 项目: avikivity/osv
 def trace_function(indent, annotation, data):
     fn, caller = data
     try:
         block = gdb.block_for_pc(to_int(fn))
         fn_name = block.function.print_name
     except:
         fn_name = '???'
     out_func('0x%016x %2d %19s %s %s %s\n'
               % (thread,
                  cpu,
                  format_time(time),
                  indent,
                  annotation,
                  fn_name,
                  ))
    def __call__(self, pending_frame):
        pc_desc = pending_frame.architecture().registers().find("pc")
        pc = pending_frame.read_register(pc_desc)

        block = gdb.block_for_pc(int(pc))
        if block is None:
            return None
        func = block.function
        if func is None:
            return None

        print("Func %s, Level %d" % (str(func), pending_frame.level()))

        # This unwinder never claims any frames.
        return None
示例#23
0
 def invoke(self, _arg, _from_tty):
     # args = gdb.string_to_argv(arg)
     vp = gdb.lookup_type('void').pointer()
     for ptr in SliceValue(gdb.parse_and_eval("'runtime.allgs'")):
         if ptr['atomicstatus'] == G_DEAD:
             continue
         s = ' '
         if ptr['m']:
             s = '*'
         pc = ptr['sched']['pc'].cast(vp)
         pc = pc_to_int(pc)
         blk = gdb.block_for_pc(pc)
         status = int(ptr['atomicstatus'])
         st = sts.get(status, "unknown(%d)" % status)
         print(s, ptr['goid'], "{0:8s}".format(st), blk.function)
示例#24
0
def get_symbol_name(addr):
    try:
        block = gdb.block_for_pc(int(addr))
    except:
        try:
            return gdb.execute('info symbol ' + hex(addr), False, True).split(' ')[0]
        except:
            return '<unknown>'

    while block and not block.function:
        block = block.superblock

    if block is None:
        return '<unknown>'

    return block.function.print_name
示例#25
0
文件: loader.py 项目: alexcmd/osv
 def trace_function(indent, annotation, data):
     fn, caller = data
     try:
         block = gdb.block_for_pc(long(fn))
         fn_name = block.function.print_name
     except:
         fn_name = '???'
     out_func('0x%016x %2d %12d.%06d %s %s %s\n' 
               % (thread,
                  cpu,
                  time / 1000000000,
                  (time % 1000000000) / 1000,
                  indent,
                  annotation,
                  fn_name,
                  ))
示例#26
0
 def trace_function(indent, annotation, data):
     fn, caller = data
     try:
         block = gdb.block_for_pc(long(fn))
         fn_name = block.function.print_name
     except:
         fn_name = '???'
     out_func('0x%016x %2d %12d.%06d %s %s %s\n' 
               % (thread,
                  cpu,
                  time / 1000000000,
                  (time % 1000000000) / 1000,
                  indent,
                  annotation,
                  fn_name,
                  ))
示例#27
0
    def _func_get_address_range(self, gdbsym_specified):
        """
        gdb.Symbol が表す symbol の専有アドレス範囲を返す
        不明な gdb.Symbol が指定された場合は、(None, None) を返す
        """

        tpl_range = (None, None)

        if (gdbsym_specified.is_variable or # variable
            gdbsym_specified.is_argument or # 引数
            gdbsym_specified.is_constant
        ):
            
            gdbval_specified = gdbsym_specified.value(gdb.selected_frame())
            int_first_address = int(gdbval_specified.address.cast(self._gdbtyp_address_length_uint))
            int_last_address =  int_first_address + gdbval_specified.type.sizeof - 1

            tpl_range = (int_first_address, int_last_address)

        elif (gdbsym_specified.is_function): # function
            gdbval_func_adr = gdbsym_specified.value(gdb.selected_frame())
            int_func_adr = int(gdbval_func_adr.cast(self._gdbtyp_address_length_uint)) # function を表す symbol の場合は、
                                                                                    # .value() で返ってくる gdb.Value に対して
                                                                                    # 直接 int へ cast できない。(理由は不明)
            # gdbblk_target = gdb.block_for_pc(int_func_adr) # 関数が配置されている アドレスの block を取得
            gdbblk_target = gdb.block_for_pc(int_func_adr)
            int_first_address = gdbblk_target.start
            int_last_address = gdbblk_target.end

            tpl_range = (int_first_address, int_last_address)

        else: # unkown なシンボルの場合
            
            insobj_curframe_b_back = inspect.currentframe().f_back
            sys.stderr.write(
                "[error] Cannot calculate address range Because of" + "\n" +
                "[error] specified gdb.Symbol object has unkown type." + "\n" +
                "[error] Which is not variable, argment, constant, nor function." + "\n" +
                "[error] str(gdb.Symbol):" + str(gdbsym_specified) + "\n" +
                "[error] The corresponding code part is" + "\n" +
                "[error] File:" + insobj_curframe_b_back.f_code.co_filename + "\n" +
                "[error] Function:" + insobj_curframe_b_back.f_code.co_name + "\n" +
                "[error] Line no:" + str(insobj_curframe_b_back.f_lineno) + "\n"
            )

        return tpl_range
示例#28
0
    def __call__(self, pending_frame):
        pc_desc = pending_frame.architecture().registers().find("pc")
        pc = pending_frame.read_register(pc_desc)

        sp_desc = pending_frame.architecture().registers().find("sp")
        sp = pending_frame.read_register(sp_desc)

        block = gdb.block_for_pc(int(pc))
        if block == None:
            return None
        func = block.function
        if func == None:
            return None
        if str(func) != "break_bt_here":
            return None
        fid = FrameId(pc, sp)
        return pending_frame.create_unwind_info(fid)
示例#29
0
def show_lines(sal, indent=0):
    curline = sal.line
    fname = sal.symtab.filename
    function = gdb.block_for_pc(sal.pc).function
    gdb.write("file: {} function: {}\n".format(
        colorize('col_file', fname), colorize('col_function', function)))
    lines = gdb.execute("list {}:{}".format(fname, curline), False, True)
    found = False
    for l in lines.splitlines():
        if not found:
            w = l.split()
            if len(w) > 0 and int(w[0]) == curline:
                gdb.write(" " * indent +
                          colorize('col_curline', l.expandtabs()) + "\n")
                found = True
                continue
        gdb.write(" " * indent + l + "\n")
示例#30
0
    def _update_frame(self):
        # We don't care too much about the detail here, so just
        # lookup the function name.
        #print("r13 %08x lr %08x pc %08x" % (self.regs[13], self.regs[14], self.regs[15]))
        try:
            self.block = gdb.block_for_pc(int(self.regs[15]))
        except Exception as e:

            class FakeBlock(object):
                pass

            self.block = FakeBlock()
            self.block.function = "??"
            print(e)
        while self.block.function is None:
            self.block = self.block.superblock
        self.frame_str = "0x%x in %s ()" % (self.regs[15], self.block.function)
示例#31
0
    def invoke(self, *_):
        pos = eval_int('$pc')
        line = gdb.find_pc_line(pos)
        if not line.symtab:
            return

        try:
            block = gdb.block_for_pc(pos)
        except RuntimeError as e:
            if e.args == ('Cannot locate object file for block.', ):
                return
            raise

        if block.function is None:
            print('First found block no function', pos)
            return
        while block.function.name is None:
            if block.superblock:
                block = block.superblock
            else:
                print('No superblock at', pos)
                return
            if block.function is None:
                print('Function iterated to None in', pos)
                return

        offset = pos - block.start
        offset_str = '+{}'.format(offset) if offset else ''

        entering = self.update_fp_stack()

        if entering:
            curindent = self.indent
            self.indent += 4
            direction_string = '-->'
        else:
            self.indent -= 4
            curindent = self.indent
            direction_string = '<--'

        print_str = '{}{}{}{} {}:{}'.format(' ' * curindent, direction_string,
                                            block.function.name, offset_str,
                                            line.symtab.filename, line.line)

        print(print_str)
示例#32
0
	def log(prefix, event):
		timestamp = datetime.now().isoformat()
		thread = event.ptid

		sal = gdb.find_pc_line(event.address)
		block = gdb.block_for_pc(event.address)
		while block and not block.function:
			block = block.superblock

		if block:
			function = block.function.print_name
		else:
			function = "unknown function at %x" % event.address

		if sal.symtab:
			line = "%s:%d" % (sal.symtab.fullname(), sal.line)
		else:
			line = "unknown source"
		self.output.write("[%s] %s %s %s %s" % (timestamp, thread, prefix, function, line))
示例#33
0
def get_function_block(addr):
    '''Does gdb.block_for_pc(addr) but raises the same exception if object file
    can't be found as if the block found is None, static, or global.

    This is just for convenience.

    '''
    func_block = gdb.block_for_pc(addr)
    # Want the same thing to happen when gdb can't find the object file (and
    # hence raises an exception itself) as when it just can't find the block,
    # or found a static / global (i.e. file-sized) block instead of a function
    # block.
    # I've seen getting a static block when asking for the block at a
    # function address happen with je_extent_tree_szad_new() function when
    # debugging neovim.
    if func_block is None or func_block.is_static or func_block.is_global:
        raise RuntimeError('Cannot locate object file for block.')

    return func_block
示例#34
0
def lookup_pcs(inpath):
    inbase, inext = os.path.splitext(inpath)
    outpath = inbase + '-mapped' + inext
    fin = open(inpath, 'rt')
    pc_list = json.load(fin)
    fin.close()

    pc_map = {}
    for pc in pc_list:
        block = gdb.block_for_pc(pc)
        if block is None:
            continue
        func = block.function
        if block.function is None:
            continue
        pc_map[hex(pc)] = [func.symtab.filename, func.name]

    fout = open(outpath, 'wt')
    json.dump(pc_map, fout, indent=2)
    fout.close()
示例#35
0
def lookup_pcs(inpath):
    inbase, inext = os.path.splitext(inpath)
    outpath = inbase + '-mapped' + inext
    fin = open(inpath, 'rt')
    pc_list = json.load(fin)
    fin.close()

    pc_map = {}
    for pc in pc_list:
        block = gdb.block_for_pc(pc)
        if block is None:
            continue
        func = block.function
        if block.function is None:
            continue
        pc_map[hex(pc)] = [func.symtab.filename, func.name]

    fout = open(outpath, 'wt')
    json.dump(pc_map, fout, indent=2)
    fout.close()
示例#36
0
    def get_func_name(self):
        if self.pc is not None:
            try:
                block = gdb.block_for_pc(self.pc)
                if block is not None:
                    if block.function is not None:
                        return block.function.name
                    if block.superblock is not None and block.superblock.function is not None:
                        return block.superblock.function.name
            except RuntimeError:
                pass

        if self.is_js_frame():
            js_function_addr = self.topy(self.CALLEE)
            to_call = self.get_name_str % (self.addr, js_function_addr)
            #print "about to call " + to_call
            val = gdb.parse_and_eval(to_call)
            return "js: " + wtf_string_to_utf8(val)

        return "<unknown native func>"
示例#37
0
    def log(prefix, event):
        timestamp = datetime.now().isoformat()
        thread = event.ptid

        sal = gdb.find_pc_line(event.address)
        block = gdb.block_for_pc(event.address)
        while block and not block.function:
            block = block.superblock

        if block:
            function = block.function.print_name
        else:
            function = "unknown function at %x" % event.address

        if sal.symtab:
            line = "%s:%d" % (sal.symtab.fullname(), sal.line)
        else:
            line = "unknown source"
        self.output.write("[%s] %s %s %s %s" %
                          (timestamp, thread, prefix, function, line))
    def get_func_name(self):
        if self.pc is not None:
            try:
                block = gdb.block_for_pc(self.pc)
                if block is not None:
                    if block.function is not None:
                        return block.function.name
                    if block.superblock is not None and block.superblock.function is not None:
                        return block.superblock.function.name
            except RuntimeError:
                pass

        if self.is_js_frame():
            js_function_addr = self.topy(self.CALLEE)
            to_call = self.get_name_str % (self.addr, js_function_addr)
            #print "about to call " + to_call
            val = gdb.parse_and_eval(to_call)
            return "js: "+wtf_string_to_utf8(val)

        return "<unknown native func>"
示例#39
0
 def __str__(self):
     # adjust pc according to ARM/THUMB mode
     pc = self.pc & (~1) if self.is_thumb else self.pc & (~3)
     try:
         block = gdb.block_for_pc(pc)
     except RuntimeError:
         block = None
     if block and block.is_valid() and block.function:
         func = block.function.print_name
     else:
         func = gdb.execute('info symbol ' + hex(pc), True, True).strip()
         if func.startswith('No symbol'):
             func = '??'
     for sep in ['(', '+', 'in section']:
         if sep in func:
             func = func[:func.find(sep)].strip()
             break
     lib = gdb.solib_name(pc)
     lib = os.path.basename(lib) if lib else '??'
     return 'frame {0:#08x} in function {1} ({2:#08x}) from {3}'.format(
         self.sp, func, pc, lib)
示例#40
0
def backtrace_stack():
    i = 0
    frame = gdb.selected_frame()
    while frame != None and frame.is_valid() and frame.pc() > 0:
        pc = frame.pc()
        line = gdb.find_pc_line(pc)
        block = gdb.block_for_pc(pc)
        print("#{} 0x{:016x} in {}()+{} at {}:{}".format(
            i, pc, block.function, pc - block.start, line.symtab, line.line))
        i += 1
        frame = frame.older()

    if frame and frame.pc() > 0:
        print("Stopped because: {}".format(frame.unwind_stop_reason()))
    elif frame.pc() == 0:
        print("Stopped because pc = 0")
    elif frame == None:
        print("Stopped because frame = None")
    else:
        print("Stopped for unknown reason")
    print("")
示例#41
0
 def __str__(self):
     # adjust pc according to ARM/THUMB mode
     pc = self.pc & (~1) if self.is_thumb else self.pc & (~3)
     try:
         block = gdb.block_for_pc(pc)
     except RuntimeError:
         block = None
     if block and block.is_valid() and block.function:
         func = block.function.print_name
     else:
         func = gdb.execute('info symbol ' + hex(pc), True, True).strip()
         if func.startswith('No symbol'):
             func = '??'
     for sep in ['(', '+', 'in section']:
         if sep in func:
             func = func[: func.find(sep)].strip()
             break
     lib = gdb.solib_name(pc)
     lib = os.path.basename(lib) if lib else '??'
     return 'frame {0:#08x} in function {1} ({2:#08x}) from {3}'.format(
             self.sp, func, pc, lib)
示例#42
0
 def functionptr_to_chunks_argtypes(self, value, name, path, **kwargs):
     arg_types = [
         field.type
         for field in value.dereference().type.strip_typedefs().fields()
     ]
     return_type = value.dereference().type.strip_typedefs().target()
     func_addr = self.ptrval_to_ulong(value)
     func_name = 'unknown'
     try:
         block = gdb.block_for_pc(func_addr)
     except RuntimeError:
         block = None
     while block:
         if block.function:
             func_name = block.function.name
             break
         block = block.superblock
     chunks = []
     chunks.append({'str': '{'})
     chunks.append({'str': str(return_type), 'name': 'datatype'})
     chunks.append({'str': ' '})
     chunks.append({'str': '('})
     arg_chunks = [{
         'str': str(arg_type),
         'name': 'datatype'
     } for arg_type in arg_types]
     if len(arg_chunks) > 0:
         arg_chunks_commas = []
         arg_chunks_commas.append(arg_chunks[0])
         for arg_chunk in arg_chunks[1:]:
             arg_chunks_commas.append({'str': ','})
             arg_chunks_commas.append(arg_chunk)
         chunks += arg_chunks_commas
     chunks.append({'str': ')'})
     chunks.append({'str': '}'})
     chunks.append({'str': ' '})
     chunks.append({'str': hex(func_addr)[:-1]})
     chunks.append({'str': ' '})
     chunks.append({'str': '<{}>'.format(func_name)})
     return chunks
示例#43
0
    def get_pc_context_info(self, pc, line):
        try:
            current_block = gdb.block_for_pc(pc)
            if not current_block.is_valid():
                return ""
            m = collections.OrderedDict()
            while current_block and not current_block.is_static:
                for sym in current_block:
                    symbol = sym.name
                    if not sym.is_function and re.search(
                            r"\W{}\W".format(symbol), line):
                        val = gdb.parse_and_eval(symbol)
                        if val.type.code in (gdb.TYPE_CODE_PTR,
                                             gdb.TYPE_CODE_ARRAY):
                            addr = int(val.address)
                            addrs = pwngef.chain.examine_mem_value(addr)
                            if len(addrs) > 2:
                                addrs = [addrs[0], "[...]", addrs[-1]]

                            f = " {:s} ".format(config_arrow_right)
                            val = f.join(addrs)
                        elif val.type.code == gdb.TYPE_CODE_INT:
                            val = hex(int(val))
                        else:
                            continue

                        if symbol not in m:
                            m[symbol] = val
                current_block = current_block.superblock

            if m:
                return "// " + ", ".join([
                    "{}={}".format(Color.yellowify(a), b)
                    for a, b in m.items()
                ])
        except Exception:
            pass
        return ""
示例#44
0
    def invoke(self, arg, from_tty):
        args = gdb.string_to_argv(arg)

        frame = "$rbp"
        if len(args) > 0:
            frame = args[0]

        depth = 30
        if len(args) > 1:
            depth = int(args[1])

        for i in range(depth-1, -1, -1):
            ret = gdb.parse_and_eval(f"*(uint64_t*)({frame} + 8)")
            frame = gdb.parse_and_eval(f"*(uint64_t*)({frame})")

            name = ""
            block = gdb.block_for_pc(int(ret))
            if block:
                name = block.function or ""

            print("{:016x} {}".format(int(ret), name))

            if frame == 0 or ret == 0:
                return
示例#45
0
    def register_journal_buffer_io_sync(cls, sym):
        # ext3/ext4 and jbd/jbd2 share names but not implementations
        b = gdb.block_for_pc(long(sym.value().address))
        sym = get_symbol_value('journal_end_buffer_io_sync', b)

        register_buffer_head_decoder(sym, cls.decode_journal_buffer_io_sync)
示例#46
0
    def invoke(self, args, from_tty):
        argv = parse_argv(args)

        if len(argv) > 1:
            print('Usage: walkstk [fp]')
            return

        # Bail early if the custom unwinder has not been set up.
        if not unwind.try_unwinder_init():
            print('walkstk: Could not initialize the HHVM unwinder.')

        # Find the starting native frame.
        native_frame = gdb.newest_frame()
        if native_frame is None:
            print('walkstk: Cannot find any frames: corrupt stack?')
            return

        # Set fp = $rbp, rip = $rip.
        fp_type = T('uintptr_t').pointer()
        fp = native_frame.read_register('rbp').cast(fp_type)
        rip = native_frame.pc()

        if len(argv) == 1:
            # Start walking the stack from the user-provided `fp'.
            fp = argv[0].cast(fp_type)[0]
            rip = argv[0].cast(fp_type)[1]

            # Try to find a corresponding native frame.
            while (native_frame is not None and rip != native_frame.pc()):
                native_frame = native_frame.older()

        i = 0

        # Make a fake frame for our `fp' and `rip'.  This lets us pop a frame
        # at the top of the loop, which makes it easier to include the final
        # frame.
        fp = (fp, rip)

        while fp:
            rip = fp[1]
            fp = fp[0].cast(fp_type)

            # Try to get the PHP function name from the ActRec at `fp' if we're
            # executing in the TC.
            if frame.is_jitted(fp, rip):
                ar_type = T('HPHP::ActRec').pointer()
                try:
                    print(
                        frame.stringify(
                            frame.create_php(idx=i,
                                             ar=fp.cast(ar_type),
                                             rip=rip)))
                except gdb.MemoryError:
                    print(
                        frame.stringify(
                            frame.create_native(idx=i,
                                                fp=fp,
                                                rip=rip,
                                                native_frame=native_frame)))

                if native_frame is not None:
                    native_frame = native_frame.older()
                i += 1

            else:
                if native_frame is None:
                    # If we couldn't find a native frame, then `walkstk' was
                    # invoked with a non-native `fp' argument.  Now that we
                    # don't seem to be in the TC, try to find the corresponding
                    # native frame.
                    native_frame = gdb.newest_frame()
                    while (native_frame is not None
                           and rip != native_frame.pc()):
                        native_frame = native_frame.older()

                if native_frame is not None:
                    # Pop native frames until we hit our caller's rip.
                    frames = []

                    while (native_frame is not None
                           and (fp == 0x0 or fp[1] != native_frame.pc())):
                        frames.append(
                            frame.create_native(idx=i,
                                                fp='{inline frame}',
                                                rip=native_frame.pc(),
                                                native_frame=native_frame))

                        native_frame = native_frame.older()
                        i += 1

                    if frames:
                        # Associate the frame pointer with the un-inlined frame.
                        frames[-1]['fp'] = str(fp)

                    for f in frames:
                        print(frame.stringify(f))
                else:
                    # We only hit this case if gdb undercounted the TC's
                    # frames---which shouldn't happen unless the custom
                    # unwinder (or gdb's unwinder API) is malfunctioning.
                    #
                    # Just guess that the name of the frame is the same as the
                    # name of the block we're in.
                    try:
                        block = gdb.block_for_pc(int(rip))
                        name = block.function.name
                        print(
                            frame.stringify(
                                frame.create_native(idx=i,
                                                    fp=fp,
                                                    rip=rip,
                                                    name='? ' + name)))
                    except:
                        print(
                            frame.stringify(
                                frame.create_native(idx=i,
                                                    fp=fp,
                                                    rip=rip,
                                                    native_frame=None)))
                    i += 1
示例#47
0
def get_func_block(funcName):
    # this is a completely and utterly ridiculous thing to have to do...
    pc = gdb.decode_line(funcName)[1][0].pc
    return gdb.block_for_pc(pc)
示例#48
0
文件: stack.py 项目: DerPapst/hhvm
    def invoke(self, args, from_tty):
        argv = parse_argv(args)

        if len(argv) > 1:
            print('Usage: walkstk [fp]')
            return

        # Bail early if the custom unwinder has not been set up.
        if not unwind.try_unwinder_init():
            print('walkstk: Could not initialize the HHVM unwinder.')

        # Find the starting native frame.
        native_frame = gdb.newest_frame()
        if native_frame is None:
            print('walkstk: Cannot find any frames: corrupt stack?')
            return

        # Set fp = $rbp, rip = $rip.
        fp_type = T('uintptr_t').pointer()
        fp = native_frame.read_register('rbp').cast(fp_type)
        rip = native_frame.pc()

        if len(argv) == 1:
            # Start walking the stack from the user-provided `fp'.
            fp = argv[0].cast(fp_type)[0]
            rip = argv[0].cast(fp_type)[1]

            # Try to find a corresponding native frame.
            while (native_frame is not None
                   and rip != native_frame.pc()):
                native_frame = native_frame.older()

        i = 0

        # Make a fake frame for our `fp' and `rip'.  This lets us pop a frame
        # at the top of the loop, which makes it easier to include the final
        # frame.
        fp = (fp, rip)

        while fp:
            rip = fp[1]
            fp = fp[0].cast(fp_type)

            # Try to get the PHP function name from the ActRec at `fp' if we're
            # executing in the TC.
            if frame.is_jitted(fp, rip):
                ar_type = T('HPHP::ActRec').pointer()
                try:
                    print(frame.stringify(frame.create_php(
                        idx=i, ar=fp.cast(ar_type), rip=rip)))
                except gdb.MemoryError:
                    print(frame.stringify(frame.create_native(
                        idx=i, fp=fp, rip=rip, native_frame=native_frame)))

                if native_frame is not None:
                    native_frame = native_frame.older()
                i += 1

            else:
                if native_frame is None:
                    # If we couldn't find a native frame, then `walkstk' was
                    # invoked with a non-native `fp' argument.  Now that we
                    # don't seem to be in the TC, try to find the corresponding
                    # native frame.
                    native_frame = gdb.newest_frame()
                    while (native_frame is not None
                           and rip != native_frame.pc()):
                        native_frame = native_frame.older()

                if native_frame is not None:
                    # Pop native frames until we hit our caller's rip.
                    frames = []

                    while (native_frame is not None
                           and (fp == 0x0 or fp[1] != native_frame.pc())):
                        frames.append(frame.create_native(
                            idx=i,
                            fp='{inline frame}',
                            rip=native_frame.pc(),
                            native_frame=native_frame))

                        native_frame = native_frame.older()
                        i += 1

                    if frames:
                        # Associate the frame pointer with the un-inlined frame.
                        frames[-1]['fp'] = str(fp)

                    for f in frames:
                        print(frame.stringify(f))
                else:
                    # We only hit this case if gdb undercounted the TC's
                    # frames---which shouldn't happen unless the custom
                    # unwinder (or gdb's unwinder API) is malfunctioning.
                    #
                    # Just guess that the name of the frame is the same as the
                    # name of the block we're in.
                    try:
                        block = gdb.block_for_pc(int(rip))
                        name = block.function.name
                        print(frame.stringify(frame.create_native(
                            idx=i, fp=fp, rip=rip, name='? ' + name)))
                    except:
                        print(frame.stringify(frame.create_native(
                            idx=i, fp=fp, rip=rip, native_frame=None)))
                    i += 1
示例#49
0
def get_all_functions_from_pc(pc):
    block = gdb.block_for_pc(pc)
    for symb in block.global_block:
        if not symb.is_function: continue

        yield symb
 def _extract_all_blocks(self):
     for entry in self._linetable:
         block = gdb.block_for_pc(entry.pc)
         self._add_block_to_graph(block)