The easiest and most robust way to do this is to use GDB's Python extensions. Making a subclass of gdb.Command
will give you access to the unsplit argument string, as the 2nd argument to invoke
. In your example use case, this string can be passed as-is to gdb.execute
.
You can also split it into arguments using gdb.string_to_argv
. And if you’re going to pass just a part of the argument string to gdb.execute
, you can use string.split
, as in this example:
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()
Example:
(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]
If you can't use Python, a user-defined command can still concatenate its arguments, using eval
, but it's not nearly as robust (see note at the end.)
(This requires GDB 9.1 or later; its C-like expression evaluator will concatenate adjacent string literals.
)
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
Using eval
to surround strings in double quotes when those strings contain double quotes is problematic, though.
(gdb) repeat 3 set $a="foo"
A syntax error in expression, near `foo""'.