최소 실행 가능 예
brk () 시스템 호출은 무엇을합니까?
커널에게 힙이라는 연속 된 메모리 덩어리를 읽고 쓸 수 있도록 요청합니다.
요청하지 않으면 segfault가 될 수 있습니다.
없이 brk
:
#define _GNU_SOURCE
#include <unistd.h>
int main(void) {
/* Get the first address beyond the end of the heap. */
void *b = sbrk(0);
int *p = (int *)b;
/* May segfault because it is outside of the heap. */
*p = 1;
return 0;
}
로 brk
:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
void *b = sbrk(0);
int *p = (int *)b;
/* Move it 2 ints forward */
brk(p + 2);
/* Use the ints. */
*p = 1;
*(p + 1) = 2;
assert(*p == 1);
assert(*(p + 1) == 2);
/* Deallocate back. */
brk(b);
return 0;
}
GitHub의 상류 .
위의 내용은 새로운 페이지에 도달 brk
하지 않고 brk
.
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
void *b;
char *p, *end;
b = sbrk(0);
p = (char *)b;
end = p + 0x1000000;
brk(end);
while (p < end) {
*(p++) = 1;
}
brk(b);
return 0;
}
우분투 18.04에서 테스트되었습니다.
가상 주소 공간 시각화
전 brk
:
+------+ <-- Heap Start == Heap End
후 brk(p + 2)
:
+------+ <-- Heap Start + 2 * sizof(int) == Heap End
| |
| You can now write your ints
| in this memory area.
| |
+------+ <-- Heap Start
후 brk(b)
:
+------+ <-- Heap Start == Heap End
주소 공간을 더 잘 이해하려면 페이징에 익숙해 져야합니다. x86 페이징은 어떻게 작동합니까? .
우리는 왜 필요 둘 다 않습니다 brk
및 sbrk
?
brk
물론 구현 될 수 sbrk
+는 편의를 위해 양국을 계산 오프셋.
백엔드에서 Linux 커널 v5.0에는 https://github.com/torvalds/linux/blob/v5.0/arch/x86/entry/syscalls/syscall_64brk
를 구현하는 데 사용되는 단일 시스템 호출 이 있습니다. tbl # L23
12 common brk __x64_sys_brk
가 brk
POSIX는?
brk
POSIX 였지만 POSIX 2001에서 제거되었으므로 _GNU_SOURCE
glibc 래퍼에 액세스 해야합니다 .
소개 mmap
는 다중 범위를 할당하고 더 많은 할당 옵션을 허용하는 수퍼 셋 으로 인해 제거 될 수 있습니다.
나는 당신이 지금 또는 brk
대신에 사용해야하는 유효한 경우가 없다고 생각합니다 .malloc
mmap
brk
vs malloc
brk
구현의 하나의 오래된 가능성입니다 malloc
.
mmap
모든 POSIX 시스템이 현재 구현하는 데 사용하는 최신의보다 강력한 메커니즘입니다 malloc
. 다음은 실행 가능한 최소 mmap
메모리 할당 예 입니다.
섞고 brk
malloc 할 수 있습니까 ?
malloc
로 구현 된 경우 단일 범위의 메모리 만 관리하기 brk
때문에 어떻게 그렇게 할 수 없을지 모르겠습니다 brk
.
그러나 glibc 문서에서 그것에 대해 아무것도 찾을 수 없었습니다.
내가 mmap
사용 된 것 같아서 물건이 거기에서 효과 가있을 것입니다 malloc
.
또한보십시오:
더 많은 정보
내부적으로 커널은 프로세스가 많은 메모리를 가질 수 있는지 결정 하고 해당 사용법에 대한 메모리 페이지 를 표시합니다.
스택과 힙을 비교하는 방법을 설명합니다. x86 어셈블리의 레지스터에 사용되는 푸시 / 팝 명령어의 기능은 무엇입니까?