logging - 创建用户定义的 gdb 命令以将所有参数的值打印到日志文件

标签 logging gdb eval

在结合这两个目标之前,我首先尝试定义一个命令,将所有参数打印到 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/

相关文章:

python - Sentry django 配置 - 记录器

java - 库上的 log4j.properties

c++ - Eclipse CDT Kepler 不允许 "Display as array..."

debugging - 让 GDB 在返回提示符时打印堆栈跟踪

Javascript - 修改函数或从字符串计算函数

java - 无法在 Java 中锁定 .log 文件

java - Android 应用程序的自定义日志记录

cocoa - "EXC_BREAKPOINT (SIGTRAP)"异常是否是调试断点导致的?

.net - ASP .NET - Eval() 背后发生了什么?

javascript - JavaScript eval 的这种使用是否可以接受?