Prevent PLT (procedure linkage table) breakpoints in GDB

后端 未结 4 1168
悲哀的现实
悲哀的现实 2021-02-04 06:00

In recent versions of GDB, setting a breakpoint on a library function call results in multiple actual breakpoints:

  1. Call into the procedure linkage table (PLT)
相关标签:
4条回答
  • 2021-02-04 06:11

    add these lines to your ~/.gdbinit file and call disaplts to disable all @plt breakpoints:

    define disaplts
      python
    import gdb
    from StringIO import StringIO
    lines=gdb.execute("info break", True, True)
    for l in StringIO(lines).readlines():
      if "@plt" in l:
        bp=l.split()[0]
        gdb.execute("disa {0}".format(bp))
        print("disabling {0}".format(bp))
      end
    end
    # disable on library load
    catch load mylibrarywithplt disaplt
    

    Note: mind the spacing in python code. I recommend you use cat to paste the content. EDIT: added "execute on library load" per @WallStProg

    0 讨论(0)
  • 2021-02-04 06:12

    Yup, it can be done.

    To simply place breakpoints on all functions, use command:

    1. rbreak .*

    So, this will place breakpoints on all the functions including PLT.

    Now type:

    1. save breakpoints filename

    This will save a list of all breakpoints in a file called as filename.

    1. Now open the file in normal text editor like gedit, and remove all the PLT lines given at the end of the file. And then save the file with only the required functions on which you want to place breakpoints.

    or

    1. Remove all the @plt from the function names using the command:

    sed 's/@plt//g' filename > newfilename

    1. After this, exit gdb (to unlink gdb from useless PLT breakpoints, added before) and execute gdb again.

    Now type command:

    1. source filename

    or

    1. source newfilename (in case you used sed command)

    At this point, gdb will put breakpoints only on the functions mentioned in the file called as "filename" or "newfilename" (if used sed).

    Note: To filter functions more in the file "filename", one can use grep also according to the requirements. :)

    0 讨论(0)
  • 2021-02-04 06:26

    Here's a command, rdelete, that is like delete in the same way that rbreak is like break - it deletes breakpoints based on a regexp argument.

    $ cat rdelete.py
    import gdb
    import re
    
    class RDelete(gdb.Command):
      """Delete breakpoints for all locations matching REGEXP."""
    
      def __init__(self):
        super (RDelete, self).__init__ ("rdelete", gdb.COMMAND_BREAKPOINTS, gdb.COMPLETE_LOCATION)
    
      def invoke(self, argstr, from_tty):
        bppat = re.compile(argstr)
        for bp in gdb.breakpoints():
          if bppat.search(bp.location):
            print("Deleting breakpoint {} at {}".format(bp.number, bp.location))
            bp.delete()
    
    RDelete()
    
    
    $ gdb -q hoist
    (gdb) rbreak .*
    ...
    (gdb) i b
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   0x0000000000000580 in main at hoist.c:6
    2       breakpoint     keep y   0x00000000000007a0 in x at hoist.c:4
    3       breakpoint     keep y   0x0000000000000530 <_init>
    4       breakpoint     keep y   0x0000000000000560 <printf@plt>
    5       breakpoint     keep y   0x00000000000007b0 <__libc_csu_init>
    6       breakpoint     keep y   0x0000000000000820 <__libc_csu_fini>
    7       breakpoint     keep y   0x0000000000000824 <_fini>
    (gdb) source rdelete.py
    (gdb) rdelete @plt
    Deleting breakpoint 4 at printf@plt
    
    0 讨论(0)
  • 2021-02-04 06:27

    I think I found a solution for this problem. You can use the

    break *address
    

    syntax of break, but instead of specifying a hex address, you give the name of the function (which evaluates to the function's address). Something like

    break *myfunction
    

    That sets a breakpoint only on the main function, and not any of the PLT versions.

    0 讨论(0)
提交回复
热议问题