繁体   English   中英

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

[英]Prevent PLT (procedure linkage table) breakpoints in GDB

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

  1. 调用过程链接表 (PLT)
  2. 实际的函数调用

这意味着当库函数被调用时,我们每次都会经历两次中断。 在以前的 GDB 版本中,只会创建 #2,因此您只能休息一次。

那么问题来了:能不能在没有对应的PLT断点的情况下创建库函数调用断点呢? 我知道您可以创建一个常规断点,然后显式禁用 PLT 断点,但这真的很乏味。

我想我找到了解决这个问题的方法。 您可以使用

break *address

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

break *myfunction

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

将这些行添加到您的~/.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 添加“在库加载时执行”

是的,它可以做到。

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

  1. rbreak .*

因此,这将在包括 PLT 在内的所有函数上放置断点。

现在输入:

  1. 保存断点文件名

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

  1. 现在在像gedit这样的普通文本编辑器中打开文件,并删除文件末尾给出的所有PLT行。 然后保存文件,其中仅包含要在其上放置断点的所需函数。

或者

  1. 使用以下命令从函数名称中删除所有@plt

sed 's/@plt//g' 文件名 > 新文件名

  1. 在此之后,退出 gdb (将 gdb 与无用的 PLT 断点断开,之前添加)并再次执行 gdb

现在输入命令:

  1. 源文件名

或者

  1. 源新文件名(如果您使用了 sed 命令)

此时,gdb 将仅在名为“ filename ”或“ newfilename ”(如果使用 sed)的文件中提到的函数上放置断点。

注意:要过滤更多文件“filename”中的函数,也可以根据需要使用grep。 :)

这是一个命令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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM