防止GDB中的PLT(过程链接表)断点

时间:2015-01-30 19:51:45

标签: c++ c debugging gdb breakpoints

在最新版本的GDB中,在库函数调用上设置断点会导致多个实际断点:

  1. 调入程序链接表(PLT)
  2. 实际函数调用
  3. 这意味着当调用库函数时,我们每次最终会经历两次中断。在之前的GDB版本中,只会创建#2,因此您只能获得一次中断。

    所以问题是:可以创建一个没有相应PLT断点的库函数调用断点吗?我知道你可以创建一个常规断点,然后明确禁用PLT,但这真的很乏味。

4 个答案:

答案 0 :(得分:7)

我想我找到了解决这个问题的方法。

可以使用

break *address

break的语法,但不是指定十六进制地址,而是给出函数的名称(它计算函数的地址)。像

这样的东西
break *myfunction

仅在主函数上设置断点,而不是任何PLT版本。

答案 1 :(得分:2)

是的,可以做到。

要简单地在所有函数上放置断点,请使用命令:

  1. rbreak。*
  2. 因此,这将在所有功能上设置断点,包括PLT。

    现在输入:

    1. 保存断点文件名
    2. 这将保存名为 filename 的文件中所有断点的列表。

      1. 现在在普通文本编辑器中打开文件,例如 gedit ,然后删除文件末尾给出的所有 PLT 行。然后使用您想要放置断点的所需函数保存文件。
        1. 使用以下命令从函数名称中删除所有 @plt
        2. sed's / @ plt // g'filename> newfilename

          1. 此后,退出gdb (将gdb与无用的PLT断点取消链接,之前添加)和再次执行gdb
          2. 现在输入命令:

            1. 源文件名
              1. source newfilename (如果您使用了sed命令)
              2. 此时,gdb仅将断点放在文件中提到的名为“ filename ”或“ newfilename ”的函数中(如果使用sed)。

                注意:要在文件“filename”中过滤更多功能,可以根据要求使用grep。 :)

答案 2 :(得分:2)

将这些行添加到~/.gdbinit文件中并致电disaplts以停用所有@plt个断点:

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

注意:注意python代码中的间距。我建议您使用cat粘贴内容。 编辑:添加"执行库加载"每@WallStProg

答案 3 :(得分:0)

这里的命令rdelete类似于delete,就像rbreak类似于break一样-它基于正则表达式参数删除断点。

$ 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