C

找出載入的共享庫的位置

  • July 17, 2022

我正在維護一個使用 Oracle 客戶端庫的 C 程序。庫希望設置ORACLE_HOME環境變數,沒有它就無法工作——在很多情況下。

在我們的情況下,變數的值總是從共享庫本身的位置派生出來的——我想從 C 程式碼中實現設置它(使用putenv(3))。

但是,為此,我需要知道程序使用的特定共享庫是從哪裡載入的。因此,如果ldd應用於執行檔時,會輸出:

libc.so.7 => /lib/libc.so.7 (0x1021000)
libmeow.so.1 => /opt/meow/lib/libmeow.so.1

正在執行的程序本身如何發現libmeow.so它正在使用的 是從 載入的/opt/meow/lib

答案不必是普遍可移植的——只適用於 Linux 和 BSD 的東西就足夠了。

對於 Linux,您可以讀取和搜尋偽文件/proc/<pid>/maps,其中<pid>self來自查看自身的程序。它有每個記憶體映射項的行,應該包括每個共享庫,例如

7f63c2c23000-7f63c2dd0000 r-xp 00000000 08:01 136321  /usr/lib64/libc-2.26.so

詳情請參閱man proc


還有一個 C api 供程序遍歷它正在使用的共享對象列表。見man dl_iterate_phdr。它提供了一個使用範例。對於您的案例,它就像這樣簡單:

#define _GNU_SOURCE
#include <link.h>
#include <stdlib.h>
#include <stdio.h>
static int callback(struct dl_phdr_info *info, size_t size, void *data){
   if(info->dlpi_name[0]!='\0')printf("%s\n", info->dlpi_name);
   return 0;
}
int main(int argc, char *argv[]) {
   dl_iterate_phdr(callback, NULL);
   exit(EXIT_SUCCESS);
}

引用自:https://unix.stackexchange.com/questions/710102