ロードされた共有ライブラリの場所を見つける

ロードされた共有ライブラリの場所を見つける

私はOracleクライアントライブラリを使用するCプログラムを管理しています。ほとんどの場合、これらのライブラリはORACLE_HOME環境変数が設定されることを期待しており、環境変数なしでは機能しません。

putenv(3)私たちの場合、変数の値は常に共有ライブラリ自体の場所で発生し、Cコードで設定(を使用して)を実装しようとしています。

ただし、これを行うには、プログラムが使用する特定の共有ライブラリがどこにロードされているかを知る必要があります。したがって、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でのみ動作するだけで十分です。

答え1

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);
}

答え2

ライブラリを取得するには、コマンドを使用してリンクされた特定のバイナリを見つけることができますldd。たとえば、

$ldd /bin/cp
    linux-vdso.so.1 =>  (0x00007fffaf3ff000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
    librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
    libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
    libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
    libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)

ここでOracleライブラリをフィルタリングし、適切なORACLE_HOME変数を設定できます。これはすべて、設定された変数を使用してプログラムを実行するスクリプトで実行できます。

関連情報