Multiple commands in gdb separated by some sort of delimiter ';'?
DebuggingGdbDebugging Problem Overview
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?
Debugging Solutions
Solution 1 - Debugging
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 - Debugging
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 - Debugging
GDB has no such command separator character. I looked briefly, in case it would be easy to add one, but unfortunately no....
Solution 4 - Debugging
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 - Debugging
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.
Solution 6 - Debugging
i ran across another way to do multiple commands in GDB using a Bash HERE document.
example:
cat << EOF | gdb
print "command_1"
print "..."
print "command_n"
EOF
this has limited value/usability IMO because GDB quits after executing the list of commands.
Solution 7 - Debugging
This link describes gdb "User-defined commands" and contains the solutions mentioned above.