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