Reputation: 2086
Before combining both of these objectives, I first tried to define a command that will print all arguments to the gdb console:
define printall
set $n = 0
while $n < $argc
eval "print $arg%d", $n
set $n = $n + 1
end
end
But even this is not behaving as expected, printing the following when called with 3 variables (C99) of different type (1 float primitive, 2 structs):
(gdb) printall abs_tol point_a interval
$1 = void
$2 = void
$3 = void
(gdb)
Once this is functioning, I would like to define another user-defined command that will evaluate a gdb command and print its output to a log file, similar to:
define logcmd
if $argc >= 2
set logging on
set logging file $arg0 # <-- does this guy need to be quoted?
set logging overwrite on
set logging redirect on
set $n = 1
while $n < $argc
eval "$arg%d", $n
set $n = $n + 1
end
set logging off
end
end
With these two functions defined, I anticipate being able to write an expression:
logcmd values.log "printall abs_tol point_a interval"
But I seem to be missing something fundamental here (with eval
maybe?), what gives?
Upvotes: 2
Views: 2812
Reputation: 10271
Gdb expands arguments in user-defined CLI commands by simple textual substitution. Each occurrence of $arg0
, ..., $arg9
, and $argc
is replaced in each line, before the line is executed1.
Substitution occurs even within double quoted strings, so eval "x/$arg1xg $arg0"
does what the user expects2, and printf "$argc is %d\n", $argc
will display something like 3 is 3
.
Gdb won't recognize $arg%d
as something to substitute, though.
But it works better in gdb 8.0 (or gdb 7.12.50 on Ubuntu). Although gdb still won't substitute any args in eval "print $arg%d", $n
during its pass through the user-defined command, it adds an additional substitution pass for all eval
commands, after the internal printf
has been done, before the generated command is executed.
So, the short answer is, your code will work in gdb 8.0.
Your other question was:
set logging file $arg0 # <-- does this guy need to be quoted?
The string after set logging file
, through the end of the line, will be used as the filename. You can even have embedded spaces. Do not add quotes! That will give you filenames with quotes in them.
[1]Gdb 8.0 allows an arbitrary number of args, not just 10. This is also the case with the gdb 7.12.50 snapshot that's included with Ubuntu 17.04.
[2]It's probably better to write this as eval "x/%dxg $arg0", $arg1
Upvotes: 3