GDB。具有可变参数数的用户定义命令

2024-06-13 08:33:12 发布

您现在位置:Python中文网/ 问答频道 /正文

GDB版本:GNU GDB(Ubuntu 8.1.1-0ubuntu1)8.1.1

我无法在gdb中定义具有任意数量参数的命令

我找到了一些解决方法,例如一个最多支持三个参数的命令:

define test_1

if $argc == 1
    python args = "$arg0"
end
if $argc == 2
    python args = "$arg0 $arg1"
end
if $argc == 3
    python args = "$arg0 $arg1 $arg2"
end

python print(gdb.execute(args, to_string=True))

end

用法

test_1 info breakpoints

我尝试了另一种方法,但它不起作用,因为gdb在python执行之前解析$arg<n>参数,所以args变量中的"$arg0 $arg1 $arg2"不会被它们的值替换:

define test_1

python args = ' '.join(f"$arg{i}" for i in range($argc))
python print(gdb.execute(args, to_string=True))

end

问题:如何正确操作Python不是强制性的,其他解决方案(如纯gdb脚本)是允许的


Tags: 方法test命令参数ifargsendprint
1条回答
网友
1楼 · 发布于 2024-06-13 08:33:12

实现这一点最简单、最健壮的方法是使用GDB的Python扩展。生成gdb.Command的子类将使您能够访问unsplit参数字符串,作为invoke的第二个参数。在您的示例用例中,这个字符串可以按原样传递给gdb.execute

还可以使用gdb.string_to_argv将其拆分为参数。如果要将参数字符串的一部分传递给gdb.execute,可以使用string.split,如本例所示:

class Repeat(gdb.Command):
  """repeat count command - run the given command count times"""

  def __init__(self):
    super (Repeat, self).__init__ ("repeat", gdb.COMMAND_USER, gdb.COMPLETE_COMMAND)

  def invoke(self, argstr, from_tty):
      try:
        (count, command) = argstr.split(maxsplit = 1)
      except ValueError:
        raise Exception("Usage: repeat count command")
      if not count.isdigit():
        raise Exception("missing or garbled repeat count: " + count)
      for _ in range(0, int(count)):
        gdb.execute(command, from_tty = False)

Repeat()

例如:

(gdb) repeat 3 run $(expr $RANDOM % 20)
16! = 20922789888000
[Inferior 1 (process 259) exited normally]
9! = 362880
[Inferior 1 (process 262) exited normally]
13! = 6227020800
[Inferior 1 (process 265) exited normally]

如果您不能使用Python,用户定义的命令仍然可以使用eval连接其参数,但它的健壮性不如Python(请参见最后的注释)

(这需要GDB9.1或更高版本;它的类C表达式计算器将连接相邻的字符串文本。 )

define repeat
  if $argc < 2
    printf "Usage: repeat count command\n"
  else
    # first arg goes in $count, rest are concatenated and put in $command
    set $count=$arg0
    set $i=1
    set $command=""
    while $i < $argc
      eval "set $command = \"%s\" \"$arg%d\"", $command, $i
      # add one blank space after every arg except for the last
      if $i < $argc - 1
        eval "set $command = \"%s\" \" \"", $command
      end
      set $i++
    end
    printf "About to run `%s' %d times.\n", $command, $count
    set $i=0
    while $i < $count
      eval "%s", $command
      set $i++
    end
  end
end

但是,当字符串包含双引号时,使用eval将字符串用双引号括起来是有问题的

(gdb) repeat 3 set $a="foo"
A syntax error in expression, near `foo""'.

相关问题 更多 >