Nicolas Kowalski wrote:

> J'ai finalement trouv� une solution � ce probl�me. Elle concerne la
> taille et nombre des blocs allou�s. J'ai utilis� le programme
> pr�c�dent pour faire quelques statitistiques :
> 
> - `chunk' est la taille demand�e pour chaque malloc
> - `total' est le nombre total d'octets allou�s
> - le dernier nombre indique le nombre de malloc ayant r�ussi.
> 
> failure, chunk = 1024, total=576799744
> Number of malloc: 563282
...
> failure, chunk = 1048576, total=1654652928
> Number of malloc: 1579
> 
> ...
> A partir de l� les machines s'�croulent, j'ai alors laiss� tomber.
> 
> 
> Bref, pour ne pas �tre ennuy�s, les d�veloppeurs du labo vont devoir
> repondre eux-m�mes la gestion de la m�moire :-|.
> Je subodore un bug de la glibc...

Il faut savoir que la glibc utilise 2 m�thodes diff�rents pour r�pondre
� un malloc() et ceux suivant la taille demand�e.  Je ne sais plus de
m�moire quel est la barri�re mais ce n'est pas important.

Pour les petites allocations, c'est r�aliser sur le tas avec du sbrk()
ou �quivalent.

Pour les grosses allocations, c'est du mmap() anonyme de /dev/zero.

Voici le r�sulta du source attach�

stack  0xbffff918
main   0x8048580
sbrk   0x80498f8
malloc 0x8049900
malloc 0x806d8b8
sbrk   0x806e000
mmap   0x400f6000
malloc 0x40116008
sysmem cat /proc/25007/maps
08048000-08049000 r-xp 00000000 00:09 64569      /misc/people3/egp/tmp/x
08049000-0804a000 rw-p 00000000 00:09 64569      /misc/people3/egp/tmp/x
0804a000-0806e000 rwxp 00000000 00:00 0
40000000-40012000 r-xp 00000000 08:06 6184       /lib/ld-2.1.3.so
40012000-40014000 rw-p 00011000 08:06 6184       /lib/ld-2.1.3.so
40014000-40015000 rw-p 00000000 00:00 0
40019000-400ee000 r-xp 00000000 08:06 6195       /lib/libc-2.1.3.so
400ee000-400f2000 rw-p 000d4000 08:06 6195       /lib/libc-2.1.3.so
400f2000-400f6000 rw-p 00000000 00:00 0
400f6000-40116000 rw-p 00000000 08:06 72599      /dev/zero
40116000-40137000 rw-p 00000000 00:00 0
bfffe000-c0000000 rwxp fffff000 00:00 0


Les petits malloc() seront r�alis�s entre le premier sbrk (qui commence
� 0x08049000) et le premier mmap (aka 0x40000000).  Sans oublier les
ent�tes de gestion de chaque zone mapp�.

Les gros malloc() entre le dernier mmap et la stack.

L'espace virtuel diponnible est alors en gros 0x08049000 - 0x40000000
pour les petits mallocs (� noter le d�but du tas d�pends du programme)
et 0x400f6000 - 0xbfffe000 pour les gros malloc() en sachant que la
stack peux grossir vers le bas (sur Intel) et doc prendre sur la zone
mmap.

Voila, ulimit -m unlimited m'est me veux pas dire utilise toute la
m�moire.
-- 
Edouard G. Parmelan
http://egp.free.fr
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

int main()
{
    int i;
    char *p;
    int fd;
    char cmd[128];

    printf ("stack  %p\n", cmd);
    printf ("main   %p\n", &main);
    printf ("sbrk   %p\n", sbrk(0));

    p = malloc (64);
    printf ("malloc %p\n", p);
    for (i = 64; i < 128 * 1024; i += 64)
	p = malloc (64);
    printf ("malloc %p\n", p);
    printf ("sbrk   %p\n", sbrk(0));

    fd = open ("/dev/zero", O_RDWR);
    p = mmap (NULL, 128 * 1024, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); 
    close (fd);

    printf ("mmap   %p\n", p);

    p = malloc (128 * 1024);
    printf ("malloc %p\n", p);

    sprintf (cmd, "cat /proc/%d/maps", getpid());
    printf ("sysmem %s\n", cmd);
    system (cmd);
}

Répondre à