如何使用GDB获取指令的长度?

时间:2013-05-07 01:27:22

标签: gdb

我想解决的问题是我想动态计算给定其地址的指令的长度(来自GDB内)和set该长度作为变量值的长度。挑战在于我不希望在控制台上打印任何无关的输出(例如反汇编指令等)。

我的正常做法是x/2i ADDR,然后减去这两个地址。我想自动实现同样的事情;但是,我不想在控制台上打印任何东西。如果我可以禁用控制台输出,那么我可以通过x/2i ADDR执行此操作,然后执行$_ - ADDR

我还没有找到一种方法来禁用GDB中的命令输出。如果你知道这样的话请告诉我!但是,我发现了interpreter-exec和GDB / MI。快速测试表明,x/2i可以在GDB / MI上运行,并且由MI解释器计算的$_的值与控制台解释器共享。不幸的是,这种方法也会产生很多输出。

有没有人知道如何计算指令的长度而不显示任何内容,或者如何禁用interpreter-exec的输出,从而让我实现目标?谢谢。

2 个答案:

答案 0 :(得分:5)

我会给出一个可以说更清洁,更具可扩展性的解决方案,而不是真的更短。它实现$instn_length()作为新的GDB便利功能。

将此保存到 instn-length.py

import gdb

def instn_length(addr_expr):
    t = gdb.execute('x/2i ' + addr_expr, to_string=True)
    return long(gdb.parse_and_eval('$_')) - long(gdb.parse_and_eval(addr_expr))

class InstnLength(gdb.Function):
    def __init__(self):
        super(InstnLength, self).__init__('instn_length')

    def invoke(self, addr):
        return instn_length(str(long(addr)))

InstnLength()

然后运行

$ gdb -q -x instn-length.py /bin/true
Reading symbols from /usr/bin/true...Reading symbols from /usr/lib/debug/usr/bin/true.debug...done.
done.
(gdb) start
Temporary breakpoint 1 at 0x4014c0: file true.c, line 59.
Starting program: /usr/bin/true 

Temporary breakpoint 1, main (argc=1, argv=0x7fffffffde28) at true.c:59
59    if (argc == 2)
(gdb) p $instn_length($pc)
$1 = 3
(gdb) disassemble /r $pc, $pc + 4
Dump of assembler code from 0x4014c0 to 0x4014c4:

instn_length()的另一种实现是在GDB 7.6 +中使用 gdb.Architecture.disassemble()方法:

def instn_length(addr_expr):
    addr = long(gdb.parse_and_eval(addr_expr))
    arch = gdb.selected_frame().architecture()
    return arch.disassemble(addr)[0]['length']

答案 1 :(得分:1)

我找到了合适的解决方案;但是,较短的解决方案将是优选的。此解决方案将日志记录文件设置为/dev/null,如果存在则设置为覆盖,然后暂时将控制台输出重定向到日志文件。

define get-in-length
  set logging file /dev/null
  set logging overwrite on
  set logging redirect on
  set logging on
  x/2i $arg0
  set logging off
  set logging redirect off
  set logging overwrite off
  set $_in_length = ((unsigned long) $_) - ((unsigned long) $arg0)
end

此解决方案受到另一个问题答案的启发:How to get my program name in GDB when writting a "define" script?