Tenir compte du programme suivant:malloc errno réglage EAGAIN
#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);
}
Lors de l'exécution en tant qu'utilisateur normal je reçois:
~ ./a.out
~ echo $?
11
De /usr/include/asm-generic/errno-base.h
:
#define EAGAIN 11 /* Try again */
Lors de l'exécution comme root ou au passage MCL_FUTURE | MCL_CURRENT
il fonctionne avec succès. J'ai supposé que les permissions étaient insuffisantes ou que les drapeaux étaient faux, mais ni EPERM ni EINVAL n'ont été retournés.
Cette erreur n'est pas spécifiée dans la page de manuel des fonctions ni dans la spécification POSIX pour mlockall. Placer un printf après mlockall révèle que c'est malloc qui définit errno.
Et semble encore plus étrange, malloc ne pas définir EAGAIN (ou je suis à la recherche dans le mauvais endroit):
/usr/src/glibc/glibc-2.19/malloc grep -r . -e EAGAIN
Alors quel est le problème?
~ 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
Vous définissez 'errno' sur 0, en appelant * deux * fonctions, puis en vérifiant la valeur de' errno'. Vous ne pouvez pas dire si elle a été définie par 'mlockall' ou par' malloc'. Vous mentionnez d'ajouter un appel 'printf', mais ce n'est pas dans le code que vous avez posté. Vous devriez mettre 'errno' à 0 avant chaque appel et le vérifier immédiatement après chaque appel. –
Quel répertoire se trouve 'a.out'? –
De la page de manuel _If MCL_FUTURE a été spécifié, un appel système ultérieur (par exemple mmap (2), sbrk (2), malloc (3)) peut échouer si le nombre d'octets verrouillés dépasse le nombre autorisé maximum (voir ci-dessous).Dans les mêmes circonstances, la croissance de la pile peut également échouer: le noyau refusera l'expansion de la pile et délivrera un signal SIGSEGV au processus. – alvits