簡體   English   中英

如何在動態打開的共享庫入口處設置斷點?

[英]How to set breakpoint on entry of dynamically opened shared library?

在某些情況下,我正在檢查一個簡單的 C++ 程序,該程序使用實驗性事務 memory model,用 Z6264F87F5281EZEC7464 編譯。 我想知道register_tm_clones的確切調用位置(您可以通過 objdumping 一個簡單的程序來查看 fn)。 這個 function 即使在像int main() {}這樣的程序中也會被調用。

我想知道調用register_tm_clones的通用程序的整個 scope 的哪個位置。 我在 GDB 中設置了一個斷點並回溯:

Breakpoint 1, 0x00007ffff7c5e6e0 in register_tm_clones () from /usr/lib/libgcc_s.so.1
(gdb) bt
#0  0x00007ffff7c5e6e0 in register_tm_clones () from /usr/lib/libgcc_s.so.1
#1  0x00007ffff7fe209a in call_init.part () from /lib64/ld-linux-x86-64.so.2
#2  0x00007ffff7fe21a1 in _dl_init () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7fd313a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#4  0x0000000000000001 in ?? ()
#5  0x00007fffffffe390 in ?? ()
#6  0x0000000000000000 in ?? ()

ld-linux在程序中的某個位置打開libgcc時調用它。 我確保我們與libgcc相關聯。 是的:

❯ ldd main
    linux-vdso.so.1 (0x00007fff985e4000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f7eb82dc000)
    libm.so.6 => /usr/lib/libm.so.6 (0x00007f7eb8196000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f7eb817c000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007f7eb7fb6000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f7eb84ec000)

但是......我怎么知道什么時候被調用(它絕對不在main )? 我知道_start是C++程序的真正入口。 然后我們運行__libc_csu_init ,然后有一些步驟,我們進入 main。 我如何設置斷點以查看大圖以查看ld何時決定打開libgcc以及調用register_tm_clones的位置?

如何設置斷點以查看大圖以查看 ld 何時決定打開 libgcc,以及調用 register_tm_clones 的位置?

已經看到了。

我認為您的困惑在於不了解動態鏈接進程運行時會發生什么。 大致來說,步驟是:

  1. kernel 創建一個新進程“shell”並將可執行文件mmap到其中。

  2. mmap觀察到可執行文件具有PT_INTERP段,並且將那里引用的文件也映射到進程中。 在這里, PT_INTERP的內容是/lib64/ld-linux-x86-64.so.2 ,也就是動態加載程序,不要與/usr/bin/ld (又名 static 鏈接器)混淆。

    此外,由於存在程序解釋器,kernel 將控制權轉移給(而不是在主可執行文件中調用_start ),因為主可執行文件尚未准備好運行。

  3. ld-linux開始運行時,它首先重新定位自己,然后mmap主要可執行文件直接鏈接的所有庫。 您可以使用readelf -d a.out | grep NEEDED查看這些庫。 readelf -d a.out | grep NEEDED

    注意:由於這些庫中的每一個都可能直接依賴於其他庫,因此遞歸地重復此過程。

  4. 庫被初始化(通過調用它們的構造函數 function,它通常被稱為_init但也可以有不同的名稱)<== 這是libgcc_s.so.1被初始化的地方,它的register_tm_clones被調用。

  5. 一旦所有庫都加載並初始化, ld-linux最終會在主可執行文件中調用_start ,最終會調用main

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM