I run gdb
with a .gdbinit
file, which has some convenience variables that just won't expand.
I wrote the following .gdbinit
file to flash an executable to a microcontroller through a blackmagic probe (see 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
The blackmagic probe attaches itself to a COM-port, which can be different on one computer vs another. Therefore, I don't want to hardcode that in the .gdbinit
file. A GDB convenience variable looked like the most elegant solution:
https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_59.html
So I use the convenience variable $com
in the .gdbinit
file and I define it on the commandline when I invoke GDB:
arm-none-eabi-gdb -x .gdbinit -ex "set $com = \"COM9\""
GDB starts but throws an error message:
.gdbinit:6: Error in sourced command file:
$com: No such file or directory.
It looks like GDB doesn't recognize the $com
convenience variable. So I check if GDB actually stored the variable:
(gdb) show convenience
$com = "COM9"
$trace_file = void
$trace_func = void
$trace_line = -1
$tracepoint = -1
$trace_frame = -1
$_inferior = 1
...
This proves that GDB correctly stored it as "COM9"
. The problem is therefore a failure to expand it.
As I observed the failure to expand $com
while executing .gdbinit
, I thought it might work to issue the commands directly in 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.
But the error persists.
Do you know a way to make the convenience variables in GDB work? Or do you know of another mechanism to reach the same goal?
Thank you @Mark Plotnick for your answer! As you suggested, I gave my .gdbinit
file the following content:
define flash-remote
target extended-remote $arg0
monitor version
monitor swdp_scan
attach 1
file mcu_application.elf
load
start
detach
quit
end
However, I had to remove the quotes around the argument COM9
when invoking GDB. So instead of:
arm-none-eabi-gdb -x .gdbinit -ex "flash-remote \"COM9\""
I invoke GDB this way:
arm-none-eabi-gdb -x .gdbinit -ex "flash-remote COM9"
Now it works! You saved my day!
Convenience variables are only expanded in certain contexts - mostly expressions - such as the arguments to print
, x
, eval
, set
, and if
.
You could use eval
to do what you want:
eval "target extended-remote %s", $com
But - and this is a big but - until recently, when evaluating expressions, gdb would store string values in the address space of the target, which requires a running process. So on older gdbs, you may get the error message evaluation of this expression requires the target program to be active.
Gdb does have a more general macro facility: user-defined commands.
One possibility is to put this in .gdbinit:
define flash-remote
target extended-remote $arg0
monitor version
monitor swdp_scan
attach 1
file mcu_application.elf
load
start
detach
quit
end
And invoke gdb like this:
arm-none-eabi-gdb -ex "flash-remote \"COM9\""