로드된 공유 라이브러리의 위치 찾기

로드된 공유 라이브러리의 위치 찾기

저는 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변수를 설정할 수 있습니다. 이 모든 작업은 설정된 변수를 사용하여 프로그램을 실행하는 스크립트에서 수행할 수 있습니다.

관련 정보