Linux 시스템에서 공유 라이브러리를 로드할 때 공유 라이브러리의 메모리 레이아웃은 어떻게 됩니까?
예를 들어 원래 메모리 레이아웃은 다음과 같습니다.
+-----------+
|heap(ori) |
+-----------+
|stack(ori) |
+-----------+
|.data(ori) |
+-----------+
|.text(ori) |
+-----------+
dlopen 을 할 때 foo.so
메모리 레이아웃은 A인가요, 아니면 B인가요?
A
+-----------+
|heap(ori) |
+-----------+
|stack(ori) |
+-----------+
|.data(ori) |
+-----------+
|.text(ori) |
+-----------+
|heap(foo) |
+-----------+
|stack(foo) |
+-----------+
|.data(foo) |
+-----------+
|.text(foo) |
+-----------+
또는
B
+-----------+
|heap(ori) |
+-----------+
|heap(foo) |
+-----------+
|stack(foo) |
+-----------+
|stack(ori) |
+-----------+
|.data(foo) |
+-----------+
|.data(ori) |
+-----------+
|.text(foo) |
+-----------+
|.text(ori) |
+-----------+
아니면 A와 B 외에 다른 것이 있는 걸까요...?
답변1
대답은 "기타"입니다. 메모리 레이아웃을 이해하는 데 사용할 수 있습니다 cat /proc/self/maps
. 내 64비트 Arch 노트북에서:
00400000-0040c000 r-xp 00000000 08:02 1186758 /usr/bin/cat
0060b000-0060c000 r--p 0000b000 08:02 1186758 /usr/bin/cat
0060c000-0060d000 rw-p 0000c000 08:02 1186758 /usr/bin/cat
02598000-025b9000 rw-p 00000000 00:00 0 [heap]
7fe4b805c000-7fe4b81f5000 r-xp 00000000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b81f5000-7fe4b83f5000 ---p 00199000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b83f5000-7fe4b83f9000 r--p 00199000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b83f9000-7fe4b83fb000 rw-p 0019d000 08:02 1182914 /usr/lib/libc-2.21.so
7fe4b83fb000-7fe4b83ff000 rw-p 00000000 00:00 0
7fe4b83ff000-7fe4b8421000 r-xp 00000000 08:02 1183072 /usr/lib/ld-2.21.so
7fe4b85f9000-7fe4b85fc000 rw-p 00000000 00:00 0
7fe4b85fe000-7fe4b8620000 rw-p 00000000 00:00 0
7fe4b8620000-7fe4b8621000 r--p 00021000 08:02 1183072 /usr/lib/ld-2.21.so
7fe4b8621000-7fe4b8622000 rw-p 00022000 08:02 1183072 /usr/lib/ld-2.21.so
7fe4b8622000-7fe4b8623000 rw-p 00000000 00:00 0
7ffe430c4000-7ffe430e5000 rw-p 00000000 00:00 0 [stack]
7ffe431ed000-7ffe431ef000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
실행 파일이 낮은 메모리, 즉 .text 세그먼트, 읽기 전용 데이터 및 .bss에 로드되는 것을 볼 수 있습니다. 이것이 "힙"입니다. 더 높은 메모리에는 C 라이브러리와 "ELF 파일 인터프리터", "ld-so"가 로드됩니다. 그 다음에는 스택이 있습니다. 지정된 주소 공간에 대해 얼마나 많은 공유 라이브러리가 로드되더라도 스택과 힙은 하나만 있습니다. cat
C 라이브러리만 로드된 것 같습니다.
그렇게 하면 cat /proc/$$/maps
호출한 쉘의 메모리 맵을 얻을 수 있습니다 cat
. 모든 셸에는 동적으로 로드되는 많은 라이브러리가 있으며, 많은 수의 라이브러리가 로드 zsh
됩니다 bash
. "[힙]"과 "[스택]"이 하나만 있는 것을 볼 수 있습니다.
호출되면 dlopen()
공유 객체 파일은 보다 높은 주소의 주소 공간에 매핑됩니다 /usr/lib/libc-2.21.so
. mmap()
반환된 모든 주소가 표시되는 "구현에 따른" 메모리 맵 세그먼트가 있습니다 . 바라보다인메모리 프로그램 분석좋은 그래픽을 위해.
출처가 /usr/lib/ld-2.21.so
조금 까다롭기는 하지만 2등 시민은 아닙니다 dlopen()
.dlopen()
"vdso"와 "vsyscall"은 약간 신비롭지만이 Stackoverflow 질문좋은 설명이 있고 Wikipedia에도 설명이 있습니다.