簡體   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