歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> 更多Linux >> GNU C 庫----調試系統問題並進行修訂

GNU C 庫----調試系統問題並進行修訂

日期:2017/2/27 9:27:15   编辑:更多Linux
  一種調試 glibc 函數的好方法是用您自己的版本覆蓋所關注的函數。在沒有 root 許可權和不必重新編譯 libc 源代碼的情況下就可以完成這個任務。想象一下編寫您自己的 open() 版本該有多激動啊!    如果您沒有應用程序的源代碼並且由於 C 的 GNU 庫(glibc)函數正將某些錯誤信息返回給該應用程序而使它失敗,那麼您該怎麼辦?因為 glibc 是開放源碼,所以您當然可以獲得其源代碼、對它進行更改、重新構建和安裝。然而,這不適合那些膽怯的人,因為雖然 API 有很好的文檔說明,但 GNU C 庫的內部組織卻沒有。查找正確的函數原型只是眾多挑戰中的第一個。它還是一個很大的包,所以第一次編譯時,它將花一些時間(glibc 2.2.2 有 8552 個文件和 1775440 行代碼,包括注釋)。    更好的方法  比重新構建 glibc 更好的方法是選擇性地覆蓋一個函數。許多現代的 Unix 都支持預裝入用戶定義庫這一概念。這些庫可以是完整的替代(即,glibc 的專用版本)也可以是子集 — 甚至是一個函數。首先,通過設置 LD_LIBRARY_PATH 來包含庫的專用版本,您可以使用 glibc 的專用版本。可通過使用 LD_PRELOAD 環境值來使用您編寫的庫例程的子集。LD_LIBRARY_PATH 和 LD_PRELOAD 都是由動態 ELF 鏈接器/裝入器控制的。它使用第一個匹配來滿足任何符號名。通過預裝入您自己的庫或函數版本,您“短路”了正常路徑,這樣就允許您覆蓋它。    這裡是一個示例 makefile,它覆蓋 glibc 函數 setresgid():    覆蓋 setresgid() 的 Makefile   #   # Makefile    #     all: libs setresgid-tester     #   # Make a shared Library   #   libs: libfuncs.c       gcc -shared -Wl,-soname,libfuncs.so.1 -o libfuncs.so.1.0 libfuncs.c        ln -s libfuncs.so.1.0 libfuncs.so.1       ln -s libfuncs.so.1 libfuncs.so     #   # Here is a program that calls setresgid() for testing   #   setresgid-tester: setresgid-tester.c       gcc -o setresgid-tester setresgid-tester.c  文件 libfuncs.c 包含我的 setresgid() 專用版本。實現它以支持與原始 setresgid() 相同的參數數目時要小心,並在其它方面完成與原始 setresgid() 相同的操作,盡管我的版本欺騙該應用程序並始終返回 0。    關注的第二個文件是 setresgid-tester.c。它通過調用 setresgid() 試驗新函數。    這是動態庫的源代碼:    替換庫   /*   Put all the functions you want to override here   */   #include    #include    #include      int errno;     int    setresgid(rgid, egid, sgid)       gid_t rgid,egid,sgid;   {    errno=1;     printf("It me the shim, Hi there!\n");    return(0);     }    您還需要一個簡單方法來測試您的 setresgid() 專用版本。可以使用 strace 或 ltrace 來監視進程運行。這是普通測試示例的源代碼:    普通測試示例   /*     setresgid() system/library call tester    */   #include    #include    main(){    setresgid(0,0,0);   }    現在,編譯該庫,設置 LD_PRELOAD shell 變量,然後運行測試應用程序。您可能還需要設置 LD_LIBRARY_PATH。    運行測試應用程序  eXPort LD_PRELOAD=libfuncs.so  export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH  ./setresgid-tester  It's me the shim, Hi there!    還可以通過使用 ldd 列出動態鏈接庫來確認是否正在使用專用庫:    確認專用庫的使用  [jay@prion ld_preload]$ ldd setresgid-tester      libfuncs.so => libfuncs.so (0x40018000)      libc.so.6 => /lib/libc.so.6 (0x40022000)      /lib/ld-Linux.so.2 => /lib/ld-linux.so.2 (0x40000000)  結束語  編寫 GNU C 庫函數的專用版本是調試系統問題或進行快速修正的好方法。使用 LD_PRELOAD shell 變量,可以選擇性地用您自己的專用版本來覆蓋系統 C 庫函數。這種技術可用於 Linux 和 Solaris 環境。




Copyright © Linux教程網 All Rights Reserved