Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Pourquoi ce programme ne plante-t-il pas sur Mac ?

17 réponses
Avatar
thomas
Il est censé, non ? (allocation mémoire impossible car limitée avec
setrlimit).

En tout cas sous Linux il plante...

#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
struct rlimit lim;
int i;

if(getrlimit(RLIMIT_AS, &lim) == -1) return 1;
printf("%d\n", lim.rlim_cur);

lim.rlim_cur = lim.rlim_max = 100 * 1024;
if(setrlimit(RLIMIT_AS, &lim) == -1) return 2;

if(getrlimit(RLIMIT_AS, &lim) == -1) return 1;
printf("%d\n", lim.rlim_cur);

char *v = malloc(100000000);
for (i=1;i<1000000;i++)
v[i]=(v[i-1]+3)%200; // pour pas que le malloc se fasse optimiser,
//on sait jamais
printf("%d\n",42);

}

--
Thomas Deniau

10 réponses

1 2
Avatar
Vincent Lefevre
Dans l'article <1ibkpyg.gyzfwaaqtnhcN%,
Thomas Deniau écrit:

[...]
char *v = malloc(100000000);
for (i=1;i<1000000;i++)
v[i]=(v[i-1]+3)%200; // pour pas que le malloc se fasse optimiser,
//on sait jamais
printf("%dn",42);

}


Les valeurs de v[i] n'ont "aucun" effet sur le programme, donc
l'optimisation est valide. De plus, ton programme a un comportement
indéfini... Si tu veux voir si la mémoire a pu être allouée, il faut
tester si v est nul avant la boucle. C'est la première chose à faire.
De plus, je pense que tu veux initialiser v[0] et afficher v[999999]
pour être à peu près sûr qu'il n'y aura pas d'optimisation.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
thomas
Vincent Lefevre <vincent+ wrote:

Les valeurs de v[i] n'ont "aucun" effet sur le programme, donc
l'optimisation est valide. De plus, ton programme a un comportement
indéfini... Si tu veux voir si la mémoire a pu être allouée, il faut
tester si v est nul avant la boucle. C'est la première chose à faire.
De plus, je pense que tu veux initialiser v[0] et afficher v[999999]
pour être à peu près sûr qu'il n'y aura pas d'optimisation.


Je ne pense pas que ce soit un problème d'optimisation, même avec -O0
j'ai le problème. J'ai plutôt l'impression, d'après ce que je lis dans
le man et sur le net, que la gestion des limites d'OS X est bizarre et
qu'il laisse le programme allouer ce qu'il veut, en se réservant le
droit de le killer le jour où l'OS aura besoin de RAM, si jamais il a
dépassé sa limite.

J'essaie donc d'intercepter malloc() et de savoir combien de mémoire
utilise mon programme via la fonction task_info(), mais pour récupérer
la tâche courante, il semble qu'il faille utiliser :

task_for_pid (current_task(), getpid(), &task)

et ce truc là, au lieu de me renvoyer KERN_SUCCESS, me fait "os/kern
failure".

Quelqu'un a une idée ?

Avatar
Eric Levenez
Le 31/01/08 12:59, dans <1ibkzxr.11z65ht12l6wy2N%,
« Thomas Deniau » a écrit :

Je ne pense pas que ce soit un problème d'optimisation, même avec -O0
j'ai le problème. J'ai plutôt l'impression, d'après ce que je lis dans
le man et sur le net, que la gestion des limites d'OS X est bizarre et
qu'il laisse le programme allouer ce qu'il veut, en se réservant le
droit de le killer le jour où l'OS aura besoin de RAM, si jamais il a
dépassé sa limite.


Cela n'a rien de bizarre, c'est un choix d'implémentation. L'allocation de
la mémoire n'aura lieu qu'au moment de l'utilisation. Il n'y a pas de
réservation comme sur les dernières versions de Linux si c'est cela que tu
veux dire. Il y a du pour et du contre aux 2 méthodes.

C'est la même chose avec les pools zfs par exemple. Et la aussi c'est
"normal" car c'est un choix d'implémentation.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
thomas
Eric Levenez wrote:

Cela n'a rien de bizarre, c'est un choix d'implémentation. L'allocation de
la mémoire n'aura lieu qu'au moment de l'utilisation. Il n'y a pas de
réservation comme sur les dernières versions de Linux si c'est cela que tu
veux dire. Il y a du pour et du contre aux 2 méthodes.

C'est la même chose avec les pools zfs par exemple. Et la aussi c'est
"normal" car c'est un choix d'implémentation.


Et comment je peux faire pour être sûr qu'on ne réserve pas plus qu'une
taille donnée ?

Si c'est impossible, que se passera-t-il lorsque j'utiliserai
effectivement plus de ram qu'autorisé par setrlimit() ? Je chope un
signal ?

C'est pour un vérificateur d'algorithmes (pour un concours de
programmation), qui doit être sûr qu'on ne dépasse pas une certaine
taille en mémoire...

Merci !

--
Thomas Deniau

Avatar
luc
Thomas Deniau wrote:

Il est censé, non ? (allocation mémoire impossible car limitée avec
setrlimit).


"The setrlimit() administrative limits are not enforced except for
certain ones which are enforcible in BSD code. Those which would require
enforcement in Mach code (VM-based enforcement or scheduler- based
enforcement) are not currently enforced at all."

<http://lists.apple.com/archives/unix-porting/2005/Jun/msg00115.html>

Le post date de 2005, il semblerait qu'il soit toujours d'actualité :)

--
Luc Heinrich

Avatar
thomas
Luc Heinrich wrote:

"The setrlimit() administrative limits are not enforced except for
certain ones which are enforcible in BSD code. Those which would require
enforcement in Mach code (VM-based enforcement or scheduler- based
enforcement) are not currently enforced at all."

<http://lists.apple.com/archives/unix-porting/2005/Jun/msg00115.html>

Le post date de 2005, il semblerait qu'il soit toujours d'actualité :)


Merci...
je suis bien dans la mouise.

Je vais essayer le coup du thread via une librairie chargée
automatiquement dans le code avec DYLD_INSERT_LIBRARIES, et qui compare
le getrlimit() à la RSIZE actuellement utilisée (récupérée avec
task_info()). Mais bon...

Avatar
Vincent Lefevre
Dans l'article <C3C77828.C45A6%,
Eric Levenez écrit:

Cela n'a rien de bizarre, c'est un choix d'implémentation.
L'allocation de la mémoire n'aura lieu qu'au moment de
l'utilisation.


C'est tout de même à la limite de la conformité avec la norme C (qui
dit qu'au retour de malloc, on obtient soit un pointeur nul, soit un
pointeur vers l'espace ***alloué***). Ce choix a quand même le gros
problème de ne pas pouvoir réagir proprement.

Il n'y a pas de réservation comme sur les dernières versions de
Linux si c'est cela que tu veux dire.


Sur les dernières versions de Linux, c'est configurable.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Vincent Lefevre
Dans l'article <1ibl0gz.172edq99gno00N%,
Thomas Deniau écrit:

Et comment je peux faire pour être sûr qu'on ne réserve pas plus qu'une
taille donnée ?

Si c'est impossible, que se passera-t-il lorsque j'utiliserai
effectivement plus de ram qu'autorisé par setrlimit() ? Je chope un
signal ?

C'est pour un vérificateur d'algorithmes (pour un concours de
programmation), qui doit être sûr qu'on ne dépasse pas une certaine
taille en mémoire...


Dans ce cas, il faut aussi que tu traites les cas où les programmeurs
vont utiliser la pile pour stocker plein de données. Là je pense que
le programme devrait recevoir un signal en cas de dépassement des
ressources.

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Avatar
Eric Levenez
Le 02/02/08 22:58, dans <20080202215127$, « Vincent
Lefevre » <vincent+ a écrit :

Dans l'article <C3C77828.C45A6%,
Eric Levenez écrit:

Cela n'a rien de bizarre, c'est un choix d'implémentation.
L'allocation de la mémoire n'aura lieu qu'au moment de
l'utilisation.


C'est tout de même à la limite de la conformité avec la norme C (qui
dit qu'au retour de malloc, on obtient soit un pointeur nul, soit un
pointeur vers l'espace ***alloué***).


Malloc retourne un pointeur sur un objet alloué mais rien ne dit que
l'allocation doit être physique ou virtuelle. Et souvent sur Unix l'espace
n'est pas alloué mais juste réservé.

Ce choix a quand même le gros
problème de ne pas pouvoir réagir proprement.


"proprement" ? Ce choix a l'avantage d'être dynamique et est en concordance
avec le swap qui n'utilise pas une place limitée par une partition dédiée.
Si on veut vraiment tester sous Mac OS X (ou un autre Unix) la place
retournée par malloc, il suffit de la remplir par un pattern.

Il n'y a pas de réservation comme sur les dernières versions de
Linux si c'est cela que tu veux dire.


Sur les dernières versions de Linux, c'est configurable.


Sur GNU/Linux il y a tellement de noyaux, de malloc différents, de
configurations de l'overcommit, qu'un programme aura du mal à savoir si le
pointeur retourné par malloc pointe sur une zone allouée physiquement.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.


Avatar
Vincent Lefevre
Dans l'article <C3CAAF4A.C4911%,
Eric Levenez écrit:

Le 02/02/08 22:58, dans <20080202215127$, « Vincent
Lefevre » <vincent+ a écrit :

Ce choix a quand même le gros
problème de ne pas pouvoir réagir proprement.


"proprement" ? Ce choix a l'avantage d'être dynamique et est en concordance
avec le swap qui n'utilise pas une place limitée par une partition dédiée.
Si on veut vraiment tester sous Mac OS X (ou un autre Unix) la place
retournée par malloc, il suffit de la remplir par un pattern.


Non, ça ne teste rien du tout. Ça force l'allocation, et s'il n'y a pas
assez de mémoire, le programme plante!

Il n'y a pas de réservation comme sur les dernières versions de
Linux si c'est cela que tu veux dire.


Sur les dernières versions de Linux, c'est configurable.


Sur GNU/Linux il y a tellement de noyaux, de malloc différents, de
configurations de l'overcommit, qu'un programme aura du mal à savoir si le
pointeur retourné par malloc pointe sur une zone allouée physiquement.


Le programme n'a pas besoin de savoir. Il suffit juste de tester la
valeur de retour. Et si l'utilisateur a configuré son noyau de manière
à ne pas (trop) surallouer, en général, le programme ne plantera pas
(s'il est bien écrit).

--
Vincent Lefèvre - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)



1 2