Multiple commands in gdb separated by some sort of delimiter ';'?

DebuggingGdb

Debugging 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:

  1. 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.
  2. 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.
  3. 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.)
  4. set logging on
    • This causes GDB to start actually logging; by default, the log file is called gdb.txt.
  5. 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.
  6. set logging off
    • Done writing to gdb.txt; that file now contains a valid GDB command script:

> #gdb# > whatis a > whatis b > whatis c > #gdb#

  1. 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTrevor Boyd SmithView Question on Stackoverflow
Solution 1 - DebuggingSean BrightView Answer on Stackoverflow
Solution 2 - DebuggingaleccoView Answer on Stackoverflow
Solution 3 - DebuggingMichael SnyderView Answer on Stackoverflow
Solution 4 - DebuggingGreg NisbetView Answer on Stackoverflow
Solution 5 - DebuggingVainstein KView Answer on Stackoverflow
Solution 6 - DebuggingTrevor Boyd SmithView Answer on Stackoverflow
Solution 7 - DebuggingmiguelraizView Answer on Stackoverflow