Malloc errno value for EAGAIN

Consider the following program:

#include <sys/mman.h>                                                           
#include <stdlib.h>                                                             
#include <errno.h>                                                              

int                                                                             
main()                                                                          
{                                                                              
  errno = 0;
  mlockall(MCL_FUTURE);                                           
  char *a = malloc(1);                                                      
  if (!a)                                                                       
    exit(errno);                                                                
  munlockall();                                                                 
  exit(0);                                                                      
}

When working as a regular user, I get:

~ ./a.out                                                             
~ echo $?                                                             
11

From /usr/include/asm-generic/errno-base.h:

#define EAGAIN    11  /* Try again */                                     

When run as root or during transfer MCL_FUTURE | MCL_CURRENT, it succeeds. I assumed that the permissions were insufficient or the flags were incorrect, but neither EPERM nor EINVAL were returned.

This error is not indicated on the manual page of any of the functions, nor in the POSIX specification for mlockall. Placing printf after mlockall indicates that malloc installs errno.

And even stranger, malloc doesn't seem to install EAGAIN (or I'm looking in the wrong place):

/usr/src/glibc/glibc-2.19/malloc grep -r . -e EAGAIN

So what is the deal?

~ uname -r                                                                                                                                                                                                 18:15:04 
3.16-2-486
~ gcc --version                                                                                                                                                                                            18:15:05 
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

~ ldd --version                                                                                                                                                                                            18:15:11 
ldd (Debian GLIBC 2.19-18+deb8u1) 2.19
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
~                                                                                                                                                                                                          18:15:15
+4
source share
3 answers

mlockall() . , . getrlimit(RLIMIT_MEMLOCK,...). 65536 .

, , strace(1), , , :

mlockall(MCL_FUTURE)                    = 0
brk(0)                                  = 0x2318000
brk(0x2339000)                          = 0x2318000
mmap(NULL, 1048576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 EAGAIN (Resource temporarily unavailable)
mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = -1 EAGAIN (Resource temporarily unavailable)
mmap(NULL, 67108864, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = -1 EAGAIN (Resource temporarily unavailable)
mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = -1 EAGAIN (Resource temporarily unavailable)
mmap(NULL, 67108864, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = -1 EAGAIN (Resource temporarily unavailable)
exit_group(11)                          = ?

, malloc brk, 135168 (0x2339000-0x2318000). , , brk " " ( ) . (. brk(2) C brk().)

malloc 1048576 , mmap. ( 65536 ), EAGAIN. mmap(2) , errno EAGAIN, " ", . malloc, , errno, , , EAGAIN - , , malloc.

( mmap PROT_NONE, , , . . malloc/arena.c glibc gory , .)

, , malloc , , . , , . , . EAGAIN - , mmap .

, malloc errno, , , errno . (, fprintf(3) write(2), errno ENOSPC, , fprintf(3).) .

mlockall(MCL_FUTURE), , , malloc(3). sbrk(2) mmap(2), , , . , , , root, , , mlock(2) .

+4
  • mlockall , . .
  • malloc() errno EAGAIN .

mlockall

malloc

0

mlockall()?

Per POSIX:

[EAGAIN]

, , .

On the Linux man page :

   EAGAIN Some or all of the specified address range could not be
          locked.
0
source

Source: https://habr.com/ru/post/1619102/


All Articles