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

ist*_*rus 14 c c++ debugging gdb breakpoints

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

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

这意味着当调用库函数时,我们每次最终会经历两次中断.在之前的GDB版本中,只会创建#2,因此您只能获得一次中断.

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

SCF*_*nch 7

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

break *address
Run Code Online (Sandbox Code Playgroud)

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

break *myfunction
Run Code Online (Sandbox Code Playgroud)

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


Fel*_*ema 5

将这些行添加到您的~/.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
Run Code Online (Sandbox Code Playgroud)

注意:注意 python 代码中的空格。我建议您使用cat粘贴内容。编辑:根据 @WallStProg 添加“在库加载时执行”


Ruc*_*rya 3

是的,这是可以做到的。

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

  1. 打破.*

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

现在输入:

  1. 保存断点文件名

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

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

或者

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

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

  1. 之后,退出gdb(以取消gdb与之前添加的无用PLT断点的链接)并再次执行gdb

现在输入命令:

  1. 源文件名

或者

  1. source newfilename(如果您使用 sed 命令)

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

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