Multiple commands in gdb separated by some sort of delimiter ';'?
I am trying to execute two commands at once in gdb:
finish; next
I tried using the ';' to separate the commands but gdb did not let me do both at once.
Is it possible to do multiple commands in gdb similar to bash commands separated by ';' delimiter?
Solution 1:
I don't believe so (but I may be wrong). You can do something like this:
(gdb) define fn > finish > next > end
And then just type:
(gdb) fn
You can put this in your ~/.gdbinit
file as well so it is always available.
Solution 2:
If you are running gdb from command line you can pass multiple commands with the -ex parameter like:
$ gdb ./prog -ex 'b srcfile.c:90' -ex 'b somefunc' -ex 'r -p arg1 -q arg2'
This coupled with display and other commands makes running gdb less cumbersome.
Solution 3:
GDB has no such command separator character. I looked briefly, in case it would be easy to add one, but unfortunately no....
Solution 4:
You can do this using the python integration in gdb
.
It would be nice if s ; bt
stepped and then printed a backtrace, but it doesn't.
You can accomplish the same thing by calling into the Python interpreter.
python import gdb ; print(gdb.execute("s")) ; print(gdb.execute("bt"))
It's possible to wrap this up into a dedicated command, here called "cmds", backed by a python definition.
Here's an example .gdbinit
extended with a function to run multiple commands.
# multiple commands
python
from __future__ import print_function
import gdb
class Cmds(gdb.Command):
"""run multiple commands separated by ';'"""
def __init__(self):
gdb.Command.__init__(
self,
"cmds",
gdb.COMMAND_DATA,
gdb.COMPLETE_SYMBOL,
True,
)
def invoke(self, arg, from_tty):
for fragment in arg.split(';'):
# from_tty is passed in from invoke.
# These commands should be considered interactive if the command
# that invoked them is interactive.
# to_string is false. We just want to write the output of the commands, not capture it.
gdb.execute(fragment, from_tty=from_tty, to_string=False)
print()
Cmds()
end
example invocation:
$ gdb
(gdb) cmds echo hi ; echo bye
hi
bye
Solution 5:
Certainly it is possible. Given, for example, C code
int a = 3;
double b = 4.4;
short c = 555;
, say we want to ask GDB what is the type of each of those variables. The following sequence of GDB commands will allow us to enter 3 whatis
requests all on a single line:
-
set prompt #gdb#
- Any prompt whose first non-whitespace character is
#
will work: it just so happens that#
starts a comment in GDB command scripts.
- Any prompt whose first non-whitespace character is
-
set logging overwrite on
- By default, GDB appends to a log file; choosing to instead overwrite will let us easily deploy this trick again later, with different commands.
-
set logging redirect on
- Meaning, save output of typed commands to log file only: do not also show it at the terminal. (Not absolutely required for our purposes, but keeps the clutter down.)
-
set logging on
- This causes GDB to start actually logging; by default, the log file is called
gdb.txt
.
- This causes GDB to start actually logging; by default, the log file is called
-
printf "\nwhatis a\nwhatis b\nwhatis c\n"
- Our 3
whatis
requests, entered on a single line as promised! Separating the commands, before the first, and after the last is\n
.
- Our 3
-
set logging off
- Done writing to
gdb.txt
; that file now contains a valid GDB command script:
- Done writing to
#gdb# whatis a whatis b whatis c #gdb#
-
source gdb.txt
- GDB now executes commands in the script which it just generated, producing the expected results:
type = int
type = double
type = short
Notes
- Should you wish to deploy this trick again in the same GDB session, just perform steps 4-7.
- Generating a command script with
shell
would be less cumbersome, and may well be possible; the above method, however, is platform-agnostic.