Prequisites
POSIX.1 2008 specifies the setrlimit()
and getrlimit()
functions. Various constants are provided for the resource
argument, some of which are reproduced below for easier understaning of my question.
The following resources are defined:
(...)
RLIMIT_DATA
This is the maximum size of a data segment of the process, in bytes. If this limit is exceeded, the malloc() function shall fail with errno set to [ENOMEM].
(...)
RLIMIT_STACK
This is the maximum size of the initial thread's stack, in bytes. The implementation does not automatically grow the stack beyond this limit. If this limit is exceeded, SIGSEGV shall be generated for the thread. If the thread is blocking SIGSEGV, or the process is ignoring or catching SIGSEGV and has not made arrangements to use an alternate stack, the disposition of SIGSEGV shall be set to SIG_DFL before it is generated.
RLIMIT_AS
This is the maximum size of total available memory of the process, in bytes. If this limit is exceeded, the malloc() and mmap() functions shall fail with errno set to [ENOMEM]. In addition, the automatic stack growth fails with the effects outlined above.
Furthermore, POSIX.1 2008 defines data segment like this:
3.125 Data Segment
Memory associated with a process, that can contain dynamically allocated data.
I understand that the RLMIT_DATA
resource was traditionally used to denote the maximum amount of memory that can be assigned to a process with the brk()
function. Recent editions of POSIX.1 do no longer specify this function and many operating systems (e.g. Mac OS X) do not support this function as a system call. Instead it is emulated with a variant of mmap()
which is not part of POSIX.1 2008.
Questions
I am a little bit confused about the semantic and use of the RLIMIT_DATA
resource. Here are the concrete questions I have:
Can the stack be part of the data segment according to this specification?
The standard says about
RLIMIT_DATA
: “If this limit is exceeded, the malloc() function shall fail with errno set to [ENOMEM].” Does this mean that memory allocated withmalloc()
must be part of the data segment?On Linux, memory allocated with
mmap()
does not count towards the data segment. Only memory allocated withbrk()
orsbrk()
is part of the data segment. Recent versions of the glibc use amalloc()
implementation that allocates all its memory withmmap()
. The value ofRLIMIT_DATA
thus has no effect on the amount of memory you can allocate with this implementation ofmalloc()
.Is this a violation of POSIX.1 2008?
Do other platforms exhibit similar behavior?
The standard says about
RLIMIT_AS
: "If this limit is exceeded, the malloc() and mmap() functions shall fail with errno set to [ENOMEM]." As the failure ofmmap()
is not specified forRLIMIT_DATA
, I conclude that memory obtained frommmap()
does not count towards the data segment.Is this assumption true? Does this only apply to non-POSIX variants of
mmap()
?