【问题标题】:GDB convenience variable doesn't expand in .gdbinitGDB 便利变量不会在 .gdbinit 中展开
【发布时间】:2020-10-25 06:30:05
【问题描述】:

我使用.gdbinit 文件运行gdb,其中包含一些不会扩展的便利变量。

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"

现在可以了!你拯救了我的一天!

【问题讨论】:

    标签: debugging gdb arm-none-eabi-gcc


    【解决方案1】:

    便利变量仅在某些上下文中扩展 - 主要是表达式 - 例如 printxevalsetif 的参数。

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

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

    但是 - 这是一个很大的问题 - 直到最近,当评估表达式时,gdb 会将字符串值存储在目标的地址空间中,这需要一个正在运行的进程。因此,在较旧的 gdb 上,您可能会收到错误消息evaluation of this expression requires the target program to be active

    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\""
    

    【讨论】:

    • 谢谢@Mark Plotnick。它工作得很好!我会在这个问题上悬赏并奖励给你,以表达我对你的帮助的感谢。你拯救了我的一天(实际上是我的整个星期)。
    • 嗨@Mark Plotnick。我刚刚将赏金 +100 奖励给你以表达我的感激之情 :-)
    • @K.Mulier 谢谢。
    【解决方案2】:

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

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

    【讨论】:

    • 嗨@EmployedRussian,感谢您的回复。不幸的是,这不起作用。即使我根本不使用 .gdbinit 文件,而只是在 gdb 中手动键入命令,$com 变量也不会扩展(请参阅我的问题中的第 3 段)。
    • 嗨@EmployedRussian,感谢您的帮助。你的建议肯定会奏效。但是,我正在寻找的解决方案应该很适合我们用于微控制器的新 IDE(我在初创公司“Embeetle”中,正在为微控制器构建一个新的 IDE)。因此,对于想要自己编辑 .gdbinit 文件的用户来说,该解决方案必须立即显而易见(我们力求提供一个不会在幕后隐藏任何内容,但仅使用行业标准配置文件的 IDE,请参阅 embeetle.com/#comics/cfg_as_code)。
    【解决方案3】:

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

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

    我没有对此进行测试,但是我希望它可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-13
      • 1970-01-01
      • 2011-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-18
      相关资源
      最近更新 更多