GDB 便利变量不会在 .gdbinit 中展开

GDB convenience variable doesn't expand in .gdbinit

我 运行 gdb 有一个 .gdbinit 文件,它有一些方便的变量,只是不会扩展。

1。我的设置

我编写了以下 .gdbinit 文件以通过 blackmagic 探针将可执行文件闪存到微控制器(参见 https://github.com/blacksphere/blackmagic/wiki):

# .gdbinit file:
# ------------------------------------------- #
#              GDB commands                   #
#              FOR STM32F767ZI                #
# ------------------------------------------- #
target extended-remote $com
monitor version
monitor swdp_scan
attach 1
file mcu_application.elf
load
start
detach
quit

blackmagic 探针将自身连接到 COM 端口,这在一台计算机上与另一台计算机上可能不同。因此,我不想在 .gdbinit 文件中对其进行硬编码。 GDB 便利变量看起来是最优雅的解决方案:

https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_59.html

所以我在 .gdbinit 文件中使用了方便的变量 $com 并在调用 GDB 时在命令行上定义它:

arm-none-eabi-gdb -x .gdbinit -ex "set $com = \"COM9\""

2。错误

GDB 启动但抛出错误消息:

.gdbinit:6: Error in sourced command file:
$com: No such file or directory.

看起来 GDB 无法识别 $com 便利变量。所以我检查 GDB 是否实际存储了变量:

(gdb) show convenience
$com = "COM9"
$trace_file = void
$trace_func = void
$trace_line = -1
$tracepoint = -1
$trace_frame = -1
$_inferior = 1
...

这证明GDB正确存储为"COM9"。因此问题是扩展失败。

3。更多的尝试

当我观察到在执行 .gdbinit 时无法扩展 $com,我认为直接在 GDB 中发出命令可能会起作用:

(gdb) set $com = "COM9"

(gdb) show convenience
$com = "COM9"
$trace_file = void
$trace_func = void
...

(gdb) target extended-remote $com
$com: No such file or directory.

但错误仍然存​​在。

4。问题

你知道让 GDB 中的便利变量起作用的方法吗?或者您知道达到相同目标的另一种机制吗?


5。解决方案

谢谢@Mark Plotnick 的回答!按照你的建议,我给了我的 .gdbinit 文件以下内容:

define flash-remote
  target extended-remote $arg0
  monitor version
  monitor swdp_scan
  attach 1
  file mcu_application.elf
  load
  start
  detach
  quit
end

但是,在调用 GDB 时,我不得不删除参数 COM9 周围的引号。所以代替:

arm-none-eabi-gdb -x .gdbinit -ex "flash-remote \"COM9\""

我这样调用 GDB:

arm-none-eabi-gdb -x .gdbinit -ex "flash-remote COM9"

现在可以了!你救了我的命!

GDB manual 清楚地记录了 .gdbinit 在任何 -ex 命令之前被求值。

您可以编写一个简单的 shell 包装器来创建一个具有适当替换的临时 /tmp/.gdbinit.$unique_suffix,调用 gdb -x /tmp/.gdbinit....,并在 GDB 退出后删除该临时文件。

在Windows上选择COM端口的格式是“//./COM9”,所以你在GDB中的测试应该使用:

$com = COM9
target extended-remote //.$com

我还没有测试过这个,但我希望它能工作。

便利变量仅在某些上下文中扩展 - 主要是表达式 - 例如 printxevalset 和 [=17] 的参数=].

您可以使用 eval 做您想做的事:

eval "target extended-remote %s", $com

但是 - 这是一个很大的但是 - 直到最近,在计算表达式时,gdb 会将字符串值存储在目标的地址 space 中,这需要一个 运行 过程。因此,在较旧的 gdb 上,您可能会收到错误消息 此表达式的计算要求目标程序处于活动状态

Gdb 确实有一个更通用的宏工具:user-defined commands.

一种可能是将其放入 .gdbinit:

define flash-remote
  target extended-remote $arg0
  monitor version
  monitor swdp_scan
  attach 1
  file mcu_application.elf
  load
  start
  detach
  quit
end

并像这样调用 gdb:

arm-none-eabi-gdb -ex "flash-remote \"COM9\""