在结合这两个目标之前,我首先尝试定义一个命令,将所有参数打印到 gdb 控制台:
define printall
set $n = 0
while $n < $argc
eval "print $arg%d", $n
set $n = $n + 1
end
end
但即使这也没有按预期运行,在使用 3 个不同类型的变量 (C99)(1 个浮点基元,2 个结构)调用时打印以下内容:
(gdb) printall abs_tol point_a interval
$1 = void
$2 = void
$3 = void
(gdb)
一旦它起作用,我想定义另一个用户定义的命令,它将评估 gdb 命令并将其输出打印到日志文件,类似于:
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
定义这两个函数后,我预计能够编写一个表达式:
logcmd values.log "printall abs_tol point_a interval"
但我似乎在这里遗漏了一些基本的东西(也许有eval
?),什么给出了?
最佳答案
Gdb 通过简单的文本替换来扩展用户定义的 CLI 命令中的参数。每次出现 $arg0
, ..., $arg9
,和$argc
在执行该行之前,在每行中替换1。
即使在双引号字符串中也会发生替换,因此 eval "x/$arg1xg $arg0"
执行用户期望的操作2,并且 printf "$argc is %d\n", $argc
将显示类似 3 is 3
的内容.
Gdb 无法识别 $arg%d
不过,作为替代品。
但它在 gdb 8.0(或 Ubuntu 上的 gdb 7.12.50)中工作得更好。尽管 gdb 仍然不会替换 eval "print $arg%d", $n
中的任何参数在传递用户定义的命令期间,它为所有eval
添加了一个额外的替换传递。命令,在内部 printf
之后在执行生成的命令之前已经完成了。
所以,简短的回答是,您的代码可以在 gdb 8.0 中运行。
您的其他问题是:
set logging file $arg0 # <-- does this guy need to be quoted?
set logging file
之后的字符串,直到行尾,将用作文件名。您甚至可以嵌入空格。不要添加引号!这将为您提供带引号的文件名。
[1]Gdb 8.0 允许任意数量的参数,而不仅仅是 10 个。Ubuntu 17.04 中包含的 gdb 7.12.50 快照也是如此。
[2]最好将其写为 eval "x/%dxg $arg0", $arg1
关于logging - 创建用户定义的 gdb 命令以将所有参数的值打印到日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45021160/