우리 모두 알고 있듯이 실행 중인 모든 실행 파일은 RAM에 로드됩니다.
또한 정적 링크 라이브러리와 동적 링크 라이브러리라는 두 가지 종류의 라이브러리가 있습니다.
필요할 때 두 라이브러리 모두 RAM에 로드되어야 합니다.
내가 아는 한, 동적 라이브러리를 로드하는 방법에는 두 가지가 있습니다.
- 예를 들어 컴파일할 때 연결하세요.
g++ -lsofile
- 코드에서 동적으로 로드하려면 다음을 수행해야 합니다
dlopen
.
나는 이미 게시했다이 문제하지만 여전히 모든 lib 파일을 나열할 수 있다고 확신할 수는 없습니다. 위의 첫 번째 경우에는 을 사용 ldd
하거나 확인하여 연결된 파일을 얻을 수 있다고 생각합니다 /proc/{PID}/maps
. 그러나 두 번째 경우에는 링크된 파일을 얻을 수 있는 방법이 있는지 궁금합니다. 예는 다음과 같습니다.
void SomeModule()
{
//dlopen here to link mysofile
}
int main()
{
if (user_enter == 'a')
{
printf("hello world");
}
else
{
SomeModule();
}
}
이 예에서 실행하고 Always 를 입력하면 호출되지 않으므로 연결되지 않습니다 a
. 즉, RAM에 로드되지 않습니다. 내가 맞나요?dlopen
mysofile
mysofile
그렇다면 소스 코드를 읽는 것 외에 실행 파일에 필요한 lib 파일을 어떻게 얻을 수 있습니까?
답변1
우리 모두 알고 있듯이 실행 중인 모든 실행 파일은 RAM에 로드됩니다.
잘못된!
하나실행 가능 파일파일이 다음에 매핑됩니다.가상 주소 공간~의프로세스그것을 실행가상 메모리커널의 하위 시스템입니다. 물리적 RAM은 커널에 의해서만 관리됩니다. 읽다운영 체제: 세 가지 간단한 부분더 알아보기.
전부는 아니다코드 조각실행 파일페이징(로드되지 않았습니다!) RAM에. 특히, 전혀 사용되지 않는 큰 코드 섹션(예를 들어 호출되지 않는 큰 함수가 포함되어 있기 때문에)은 RAM에 들어 가지 않습니다. 읽다페이징그리고페이지 캐시.
때로는 필요한 모든 페이지를 편리하게 처리할 만큼 물리적 RAM이 충분하지 않은 경우도 있습니다. 그 경우에 당신은 관찰이기다.
동적 링커(참조ld-리눅스(8)) 그리고드로펜(3)사용매핑(2)메모리는 공유 라이브러리의 일부 세그먼트를 매핑합니다. 따라서 플러그인의 모든 코드 조각을 RAM에 로드하지 않습니다. Drepper의 글도 읽어보세요.공유 라이브러리를 작성하는 방법종이.
이를 실행하고 항상 a를 입력하면 dlopen은 호출되지 않으므로 mysofile은 링크되지 않습니다. 이는 mysofile이 RAM에 로드되지 않음을 의미합니다.
가지다전적으로절대일반적으로 말하면향후 어떤 공유 라이브러리가 사용될지 예측그리고 dlopen
-ed. 다음 두 가지 시나리오를 고려해보세요.
영구 프로그램(아마도 브라우저)은 사용자에게 공유 라이브러리(아마도 웹에서 다운로드)를 가져오라고 요청한 다음
dlopen
이를 수행합니다.프로세스는 임시 파일에 일부 C 코드를 생성하고
/tmp/emittedcode.c
해당 파일을 임시 플러그인으로 컴파일하고(fork
일부 파일과 함께 적절한 프로세스를 실행 하여) 임시 플러그인을 -s (물론 나중에 거기에 적절한 기호를 추가합니다).gcc -O -Wall -fPIC /tmp/emittedcode.c -shared -o /tmp/emittedcode.so
/tmp/emittedcode.so
dlopen
dlsym
나는 두 번째 접근 방식을 정말 좋아합니다. 참고하세요C로 컴파일좋은 습관이에요. 현재 컴파일러는 일부 REPL 상호 작용을 통해서도 이를 달성할 수 있을 만큼 충분히 빠릅니다.
그런데 Linux 데스크톱에서는 프로세스가dlopen
많은 공유 객체즉, 플러그인(최소 수십만, 아마도 수백만)입니다. 날 봐manydl.c
예(임시 파일에 "임의" C 코드를 생성하고 반복).
추신. 또한 참고다운타임 문제dlopen
, 모든 미래 경로를 예측하는 이론적 가능성과 관련이 있습니다.
답변2
맞습니다. dlopen
대상 라이브러리는 호출되지 않으면 (프로세스의) 메모리에 로드되지 않습니다.
소스 코드를 읽지 않고 필요한 라이브러리를 결정하는 것은 중지 문제의 변형처럼 느껴집니다. 몇 가지 경험적 방법을 사용할 수 있습니다. 프로그램이 에 연결되어 있지 않으면 libdl
사용할 수 없습니다 dlopen
. 그렇다면 사용할 수 있습니다 strace
(참조).런타임에 어떤 동적 라이브러리 실행 파일이 로드되는지 확인하는 방법은 무엇입니까?dlopen
) 또는 정적 분석 사용에 대한 주장을 알아내려고 노력하십시오 . 그러나 프로그램은 libdl
직접적으로 포함될 수 있습니다(정적 링크를 통해 또는 빌드 코드를 통해). 동적 링커는 마술적이지 않으므로 프로그램 자체를 다시 구현하는 것을 막을 수 있는 방법이 없습니다.전적으로이러한 경험적 방법을 사용하여 필요한 모든 라이브러리를 찾았는지 확인하세요. 어쩌면 일부 프로그램은 자신이 추적되고 있음을 발견하고 라이브러리 로딩을 건너뛸 수도 있습니다.
필요한 모든 라이브러리를 나열하는 신뢰할 수 있는 유일한 방법은 소스 코드를 읽는 것입니다.