14

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,201
  • 4
  • 18
  • 26

4 Answers4

15

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,777
  • 1
  • 19
  • 17
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
  • 199,314
  • 34
  • 295
  • 362
  • @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
  • You can overwrite the gdb.txt if you don't want the logging history output :^) `(gdb) set logging overwrite on` `(gdb) set logging on` – QingJia Wang Feb 24 '23 at 03:27
6

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,933
  • 8
  • 63
  • 86
  • 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
  • That is pretty neat. By any chance, would you know a way to highlight the "grep"ped words. – Martian Jun 15 '22 at 15:50
0

I know this is an old post but since I found it looking to do the same thing I thought I would add to Hi-Angel's answer to say you can highlight the search term, in the python output, in a red colour by replacing the print line with the one below:

print(line.replace(args[1], "\033[91m"+args[1]+"\033[0m"))

This just uses ascii escape commands for the colour, so should work on Linux and Windows terminal, and you can easily change the colour.

Sorry, don't have enough rep to add this as a comment.

Brian
  • 11
  • 1