My question is as tilte says, accroding to my text book
int brk(void *end_data_segment);
The brk() system call sets the program break to the location specified by end_data_segment. Since virtual memory is allocated in units of pages, end_data_segment is effectively rounded up to the next page boundary.
and since on Linux, sbrk() is implemented as a library function that uses the brk() system call, so I expect that both function will round program break to the next page boundary. but when I test on a x86_64 Linux machine(ubuntu), it turns out both functions move the program break to the exact position as requested(I tried using brk, result is the same).
int main(int argc, char *argv[])
{
void *ori = sbrk(100);
printf("original program break at %p\n", ori);
void *now = sbrk(0);
printf("program break now at %p\n", now);
return 0;
}
this is the output
original program break at 0x56491e28f000
program break now at 0x56491e28f064
so what's going on here?
brkallocates/deallocates pages. That implementation detail based on the fact that the smallest unit of data for memory management in a virtual memory operating system is a page is transparent to the caller, however.In the Linux kernel,
brksaves the unaligned value and uses the aligned value to determine if pages need to be allocated/deallocated:As for
sbrk: glibc callsbrkand maintains the (unaligned) value of the current program break (__curbrk) in userspace:Consequently, the return value of
sbrkdoes not reflect the page alignment that happens in the Linux kernel.