[英]Prevent PLT (procedure linkage table) breakpoints in GDB
In recent versions of GDB, setting a breakpoint on a library function call results in multiple actual breakpoints:在最新版本的 GDB 中,在库函数调用上设置断点会导致多个实际断点:
This means that when the library function is called, we end up going through two breaks each time.这意味着当库函数被调用时,我们每次都会经历两次中断。 In previous GDB versions, only #2 would be created and hence you only get one break.
在以前的 GDB 版本中,只会创建 #2,因此您只能休息一次。
So the question is: can one can create a library function call breakpoint without the corresponding PLT breakpoint?那么问题来了:能不能在没有对应的PLT断点的情况下创建库函数调用断点呢? I am aware that you can create a regular breakpoint and then explicitly disable the PLT one, but this is really tedious.
我知道您可以创建一个常规断点,然后显式禁用 PLT 断点,但这真的很乏味。
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). break 的语法,但不是指定十六进制地址,而是给出函数的名称(计算结果为函数的地址)。 Something like
就像是
break *myfunction
That sets a breakpoint only on the main function, and not any of the PLT versions.这仅在主函数上设置断点,而不是任何 PLT 版本。
add these lines to your ~/.gdbinit
file and call disaplts
to disable all @plt
breakpoints:将这些行添加到您的
~/.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
Note: mind the spacing in python code.注意:注意python代码中的间距。 I recommend you use
cat
to paste the content.我建议您使用
cat
粘贴内容。 EDIT: added "execute on library load" per @WallStProg编辑:根据@WallStProg 添加“在库加载时执行”
Yup, it can be done.是的,它可以做到。
To simply place breakpoints on all functions, use command:要简单地在所有函数上放置断点,请使用命令:
So, this will place breakpoints on all the functions including PLT.因此,这将在包括 PLT 在内的所有函数上放置断点。
Now type:现在输入:
This will save a list of all breakpoints in a file called as filename .这将在名为filename的文件中保存所有断点的列表。
or或者
sed 's/@plt//g' filename > newfilename sed 's/@plt//g' 文件名 > 新文件名
Now type command:现在输入命令:
or或者
At this point, gdb will put breakpoints only on the functions mentioned in the file called as " filename " or " newfilename " (if used sed).此时,gdb 将仅在名为“ filename ”或“ newfilename ”(如果使用 sed)的文件中提到的函数上放置断点。
Note: To filter functions more in the file "filename" , one can use grep also according to the requirements.注意:要过滤更多文件“filename”中的函数,也可以根据需要使用grep。 :)
:)
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.这是一个命令
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.