13

Is there a way to grep on the output of print command in gdb? In my case, I am debugging a core dump using gdb and the object I am debugging contains hell lots of elements. I am finding it difficult to look for a matching attribute i.e:

(gdb) print *this | grep <attribute>

Thanks.

Piyush Kansal
  • 1,161
  • 4
  • 17
  • 25

3 Answers3

12

You can use pipe command

>>> pipe maintenance info sections | grep .text
 [15]     0x5555555551c0->0x5555555554d5 at 0x000011c0: .text ...

>>> pipe maintenance info sections | grep .text | wc 
      1      10     100
mug896
  • 1,515
  • 1
  • 16
  • 16
9

(gdb) print *this | grep

The "standard" way to achieve this is to use Meta-X gdb in emacs.

An alternative:

(gdb) set logging on
(gdb) print *this
(gdb) set logging off
(gdb) shell grep attribute gdb.txt

The patch mentioned by cnicutar sure looks attractive compared to the above. I am guessing the reason it (or its equivalent) was never submitted is that most GDB maintainers use emacs, and so don't have this problem in the first place.

Employed Russian
  • 182,696
  • 29
  • 267
  • 329
  • @Employed Russian reason: http://sourceware.org/ml/gdb-patches/2011-07/msg00284.html – matt Apr 14 '13 at 10:27
  • What're you talking about? I am using Emacs, and just tried the `print $rax | grep 41`, it says «No symbol "grep"». If you does meant that emacs allows to search, it is surely not the native grep. The grep could be used in a script, i.e. to make a gdb watchpoint to not stop in a particular function *(that's what I am trying to achieve)*. – Hi-Angel Sep 18 '14 at 06:32
5

The simplest way is to exploit gdb python. One-liner:

gdb λ py ["attribute" in line and print(line) for line in gdb.execute("p *this", to_string=True).splitlines()]

Assuming you have enabled history of commands, you can type this just once, and later then press Ctrl+R b.exec to pull it out of history. Next simply change attribute and *this per your requirements.


You can also make this as simple as this:

gdb λ grep_cmd "p *this" attribute

For that just add the following to your .gdbinit file:

py
class GrepCmd (gdb.Command):
    """Execute command, but only show lines matching the pattern
    Usage: grep_cmd <cmd> <pattern> """

    def __init__ (_):
        super ().__init__ ("grep_cmd", gdb.COMMAND_STATUS)

    def invoke (_, args_raw, __):
        args = gdb.string_to_argv(args_raw)
        if len(args) != 2:
            print("Wrong parameters number. Usage: grep_cmd <cmd> <pattern>")
        else:
            for line in gdb.execute(args[0], to_string=True).splitlines():
                if args[1] in line:
                    print(line)

GrepCmd() # required to get it registered
end
Hi-Angel
  • 4,407
  • 8
  • 59
  • 81
  • 1
    +1 Adding GrepCmd to ~/.gdbinit works great for simple filtering like (gdb) grep_cmd 'help all' 'Print backtrace' – ken hicks Feb 09 '22 at 17:57