显示在gdb中执行的每个汇编指令

问题描述 投票:9回答:3

我目前有一个棘手的错误,发生在我无法访问源或符号的地方,即我可以看到发生崩溃的指令及其地址,但这就是它。我想做的是让gdb运行而不需要交互并显示每条指令,但我还没有找到办法。

我希望实现的是这样的:

(gdb) /* some command */
0x2818a7c0: push   %ebp
0x2818a7c1: mov    %esp,%ebp
0x2818a7c3: push   %ebx
0x2818a7c4: sub    $0x4,%esp
...
0x28563622: mov    %esi,0x0(%eax)
Program received signal SIGSEGV, Segmentation fault.

我一直在做的是为程序计数器设置一个显示,如下所示:

(gdb) display/i $pc

然后使用stepi运行代码:

(gdb) stepi
1: x/i $pc  0x2818a7c0: push   %ebp

然而,崩溃是数百或数千条指令,我想要一种方法来看每一个(一起,如果可取的话),而不必多次点击“输入”。另外,如果我手动完成,我会在每条指令之间看到一个(gdb)提示符,这是不太理想的。

我简要介绍的一条路线是scripting,但我唯一的想法是设置在main(),让它显示和另一个中断(对于下一条指令),然后继续,但后来我不能在commands块中使用commands ,所以它不会像我想象的那样工作。

如果它很重要,我正在使用FreeBSD。

debugging assembly gdb freebsd
3个回答
15
投票

以下内容应该符合您的要求:

# not strictly required, but you'll likely want the log anyway
(gdb) set logging on

# ask gdb to not stop every screen-full
(gdb) set height 0

(gdb) while 1
 > x/i $pc
 > stepi
 > end

但是,这种调试方法可能会徒劳无功:即使在大多数琐碎的程序中也只执行了太多的指令。

更好的方法可能是运行程序直到崩溃,尝试了解当前函数正在做什么以及谁调用它,并适当地设置断点。

在x86上,您甚至可以在完全剥离的可执行文件中推断出函数边界。

你要看的另一件事是strace/truss输出,所以你可以看到崩溃点之前的系统调用。


1
投票

Python脚本

这将提供比GDB脚本更多的灵活性,以实现您的疯狂想法。

与GDB脚本一样,这里的主要问题是,对于没有目标硬件支持的大多数应用程序来说,这可能会太慢,例如:只有18k指令,C hello world需要1分钟。

GDB.朋友

class TraceAsm(gdb.Command):
    def __init__(self):
        super().__init__(
            'trace-asm',
            gdb.COMMAND_BREAKPOINTS,
            gdb.COMPLETE_NONE,
            False
        )
    def invoke(self, argument, from_tty):
        argv = gdb.string_to_argv(argument)
        if argv:
            gdb.write('Does not take any arguments.\n')
        else:
            done = False
            thread = gdb.inferiors()[0].threads()[0]
            last_path = None
            last_line = None
            with open('trace.tmp', 'w') as f:
                while thread.is_valid():
                    frame = gdb.selected_frame()
                    sal = frame.find_sal()
                    symtab = sal.symtab
                    if symtab:
                        path = symtab.fullname()
                        line = sal.line
                    else:
                        path = None
                        line = None
                    if path != last_path:
                        f.write("path {}{}".format(path, os.linesep))
                        last_path = path
                    if line != last_line:
                        f.write("line {}{}".format(line, os.linesep))
                        last_line = line
                    pc = frame.pc()
                    f.write("{} {} {}".format(hex(pc), frame.architecture().disassemble(pc)[0]['asm'], os.linesep))
                    gdb.execute('si', to_string=True)
TraceAsm()

GitHub upstream

电源

global _start
_start:
    ; Write.
    mov rax, 1
    mov rdi, 1
    mov rsi, hello_world
    mov rdx, hello_world_len
    syscall

    ; Exit.
    mov rax, 60
    mov rdi, 0
    syscall

hello_world db "hello world", 10
hello_world_len equ $ - hello_world

GitHub upstream

组装并运行:

as -o main.o main.S
ld -o main.out main.o
gdb -nh -batch -ex 'source ~/test/gdb.py' -ex 'starti' -ex 'trace-asm' ./main.out
cat trace.tmp

输出:

0x401000 mov    $0x1,%rax 
0x401007 mov    $0x1,%rdi 
0x40100e mov    $0x402000,%rsi 
0x401015 mov    $0xc,%rdx 
0x40101c syscall  
0x40101e mov    $0x3c,%rax 
0x401025 mov    $0x0,%rdi 
0x40102c syscall

QEMU仿真

这比GDB python解决方案执行得快得多,C hello工作即时运行!但是,日志只有10k指令长而不是相同的可执行文件上的18k,所以它必须跳过通常运行TODO理解的东西。

例如。在用户模式模拟中:

qemu-x86_64 -d in_asm ./main.out

输出:

warning: TCG doesn't support requested feature: CPUID.01H:ECX.vmx [bit 5]
----------------
IN: 
0x0000000000401000:  mov    $0x1,%rax
0x0000000000401007:  mov    $0x1,%rdi
0x000000000040100e:  mov    $0x402000,%rsi
0x0000000000401015:  mov    $0xc,%rdx
0x000000000040101c:  syscall 

hello world
----------------
IN: 
0x000000000040101e:  mov    $0x3c,%rax
0x0000000000401025:  mov    $0x0,%rdi
0x000000000040102c:  syscall

See also

在Ubuntu 18.10,GDB 8.2,QEMU 2.12.0中测试。


0
投票
  1. 单独反汇编二进制文件(例如使用objdump)并在调试时查阅列表
  2. 使用IDA及其调试器。更好的体验IMO。

(免责声明:我为Hex-Rays工作)

© www.soinside.com 2019 - 2024. All rights reserved.