Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

debugging

gdb

People also ask

What's the difference between gdb commands step and Stepi?

When the instruction contains a function call, the stepi command steps into the function being called. For multithreaded applications, use the stepi command to step the current thread one machine instruction while putting all other threads on hold.

How do you add a break point in gdb?

You can also set breakpoints on function names. To do this, just type "break [functionname]". gdb will stop your program just before that function is called. Breakpoints stay set when your program ends, so you do not have to reset them unless you quit gdb and restart it.

What is batch mode in gdb?

According to GDB documentation : Batch mode disables pagination, sets unlimited terminal width and height see Screen Size, and acts as if set confirm off were in effect (see Messages/Warnings).

How do I remove a breakpoint in gdb?

With the clear command you can delete breakpoints according to where they are in your program. With the delete command you can delete individual breakpoints, watchpoints, or catchpoints by specifying their breakpoint numbers. It is not necessary to delete a breakpoint to proceed past it.


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.


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.


GDB has no such command separator character. I looked briefly, in case it would be easy to add one, but unfortunately no....


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

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.