OVH Cloud OVH Cloud

[HS] comportement curieux de malloc

26 réponses
Avatar
François Boisson
Bonjour,

J'ai bien conscience du HS de ce message masi il y a sur cette liste des
programmeurs avertis.
Je maintiens le paquet de camllight et le debug au fur et à mesure (il n'était
pas libre lors de la version 0.74). Il est utilisé en CPGE donc il faut le
maintenir à flot (par ailleurs il est 100x plus léger que ocaml).
Il y a un bug curieux dans la version 64 bits:

camllight utilise une pile dynamiquement étendue vers le bas via des mallocs
judicieux. Or dans la version 64 bits, cette pile est soudainement saturée
très rapidement (trop). Qui plus est un free propre de la dernière allocation
plante le système. En fouillant, je me suis aperçu que la première allocation
n'est pas contigue des suivantes. Pour être exact voilà ce que donne la
succession d'appels de la fonction

char *xmallocverbeux(asize_t size) {
char *p;
printf("->demande de %d\n",size);
p=xmalloc(size);
printf("<-0x%16x ",p);
xfree(p);
p=xmalloc(size);
printf("<<-0x%16x\n",p);
return(p);
}
(xmalloc étant malloc):

<-0x 5a768010 <<-0x 1bb3820
<-0x 1c17a40 <<-0x 1c17a40
<-0x 1c58aa0 <<-0x 1c58aa0
<-0x 1d50af0 <<-0x 1d50af0
<-0x 1d91b10 <<-0x 1d91b10
<-0x 1dd2b30 <<-0x 1dd2b30

La première ligne est celle qui met le bazar, en effet sans l'appel
malloc-free-malloc (illogique) la première allocation définissnant le sommet de
la pile puis les autres étant des augmentations successives, la pile ne peut
être étendu et bing «Out of memory» (ce qui énerve assez avec 4G de RAM)

La rustine est évidente mais je ne comprends pas ce comportement singulier au
malloc sur architecture 64 bits. Si quelqu'un a une explication/
(cela faisait plusieurs mois que je butais sur ce bug).

Merci

François Boisson

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers debian-user-french-REQUEST@lists.debian.org
En cas de soucis, contactez EN ANGLAIS listmaster@lists.debian.org
Archive: http://lists.debian.org/20120929151121.2f2faabe705231f3f3f35669@maison.homelinux.net

6 réponses

1 2 3
Avatar
Vincent Danjean
Le 02/10/2012 15:57, François Boisson a écrit :
Le script ci dessous remplit parfaitement son office pour le passage de
camllight à ocaml dans les cas simple, par contre je n'ai pas vu
d'incompatibilité surtout dans les épreuves des concours (la dernière épreuve
de Centrale proposait même des primitives Camllight et Ocaml). Quel type
d'incompatibilité il y a?



C'est exactement pour les choses que tu mets dans ta liste.
C'est effectivement facile de passer de Camllight à Ocaml mais,
quand tu est censé donner un code Camllight correct, à cause de
ces différences minimes, tu ne peux pas te contenter de le tester
avec OCaml.

[...]
sed -e '1,$s/ prefix ([^ ]*) / ( 1 ) /g' |
sed -e '1,$s/copy_vect/Array.copy/g' |
sed -e '1,$s/vect_length/Array.length/g' |


[...]

--
Vincent Danjean GPG key ID 0x9D025E87
GPG key fingerprint: FC95 08A6 854D DB48 4B9A 8A94 0BF7 7867 9D02 5E87
Unofficial pkgs: http://moais.imag.fr/membres/vincent.danjean/deb.html
APT repo: deb http://people.debian.org/~vdanjean/debian unstable main

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Vincent Danjean
Le 02/10/2012 09:41, BERTRAND Joël a écrit :
Et comment t'assures-tu que le prochain mmap() va pouvoir
se faire exactement là où tu veux (juste après le mmap()
précédent) ? Le seul truc que je vois de viable, c'est la liste
chaînée ou l'arbre si l'on peut vouloir accéder à un objet
précis en fonction d'un champ connu.



Tu peux choisir l'adresse où tu fais ton mmap (au lieu de passer
NULL en premier paramètre).
C'est fait assez classiquement quand on veut réserver la même
plage d'adresses dans des processus différents (éventuellement sur
des machines similaires mais distinctes) pour, par exemple, faire
une DSM ou de la migration transparente de structures de données.

Maintenant qu'il y a de la randomisation par défaut pour l'espace
d'adressage, il doit probablement falloir regarder un peu
/proc/self/maps pour choisir le lieu où faire le mmap.
Sur mes ordis, je désactive toujours cette randomisation : je
programme et c'est impossible de débogguer avec gdb si les adresses
changent d'une exécution à l'autre.

Cordialement,
Vincent

--
Vincent Danjean GPG key ID 0x9D025E87
GPG key fingerprint: FC95 08A6 854D DB48 4B9A 8A94 0BF7 7867 9D02 5E87
Unofficial pkgs: http://moais.imag.fr/membres/vincent.danjean/deb.html
APT repo: deb http://people.debian.org/~vdanjean/debian unstable main

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
BERTRAND Joël
Vincent Danjean a écrit :
Le 02/10/2012 09:41, BERTRAND Joël a écrit :
Et comment t'assures-tu que le prochain mmap() va pouvoir
se faire exactement là où tu veux (juste après le mmap()
précédent) ? Le seul truc que je vois de viable, c'est la liste
chaînée ou l'arbre si l'on peut vouloir accéder à un objet
précis en fonction d'un champ connu.



Tu peux choisir l'adresse où tu fais ton mmap (au lieu de passer
NULL en premier paramètre).



Certes.

C'est fait assez classiquement quand on veut réserver la même
plage d'adresses dans des processus différents (éventuellement sur
des machines similaires mais distinctes) pour, par exemple, faire
une DSM ou de la migration transparente de structures de données.



Oui ? Et comment fais-tu pour t'assurer à chaque fois que tu va pouvoir
rallonger ta zone mémoire sans écraser autre chose ? Soit tu fais tout à
l'aide de mmap() quitte à réécrire un allocateur, soit tu réserves à
l'avance la zone mémoire (et dans ce cas, je ne vois pas l'intérêt de
mmap(), autant utiliser un tableau tout ce qu'il y a de plus statique).
Bref, je ne vois pas en quoi utiliser mmap() te garantit de pouvoir
augmenter la taille de ta zone à ta guise parce que rien ne te garantit
d'avoir la place suffisante. Tu vas me dire que tu peux aussi mapper
quelque chose en dehors du tas, mais ça risque fort d'un peu dépendre du
système d'exploitation.

Le seul truc que je vois portable, comme c'est une pile, c'est de coder
ça sous forme de liste chaînée, mais ça suppose un travail de réécriture.

Maintenant qu'il y a de la randomisation par défaut pour l'espace
d'adressage, il doit probablement falloir regarder un peu
/proc/self/maps pour choisir le lieu où faire le mmap.



Même beaucoup :-P

Sur mes ordis, je désactive toujours cette randomisation : je
programme et c'est impossible de débogguer avec gdb si les adresses
changent d'une exécution à l'autre.

Cordialement,
Vincent



Cordialement,

JKB


--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
François Boisson
Le Wed, 3 Oct 2012 11:44:11 +0200
François Boisson a écrit:


> Si tu as la possibilité de poster le code sur github en indiquant le
> problème, il pourra rapidement faire de petits...

Bon, j'ai déposer les sources à ce jour ici avec une description du problème.

https://github.com/FBoisson/Camllight




Pour ceux qui se rappelle de cette histoire. En fait leproblème était plus
compliqué, dans ce code assez vieux, la gestion des pages du «heap» se faisait
avec un tableau de longueur liée aux adresses effectives des pages en mémoire
vive. Comme la libc6 s'étale dans toute la plage mémoire, cela donnait un
tableau gigantesque explosant le système. Le code est rectifié.
J'ai noté que sous Windows, l'allocation mémoire se limite aux adresses basses
de la plage ce qui fait que ce bug ne se manifeste pas. Quel est l'intérêt
important d'utiliser toute la plage mémoire? Est la possibilité de pouvoir
étendre sans souci un bloc alloué? Mais dans ce cas pour faire la séquence
d'attribution 1 bloc en bas de la mémoire libre, puis en bloc tout en haut
puis un bloc en bas «collé» au précédent l'empêchant d'étendre le premier
bloc. Si on attend un peu, on constate des allocations en haut et en bas
toujours jointives. Du coup je me perd en conjectures sur la stratégie de
malloc. Peut être un développeur facétieux...

François Boisson

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
Bzzz
On Tue, 23 Apr 2013 08:42:05 +0200
François Boisson wrote:

fait que ce bug ne se manifeste pas. Quel est l'intérêt importa nt
d'utiliser toute la plage mémoire? Est la possibilité de pouvoir
étendre sans souci un bloc alloué? Mais dans ce cas pour faire la
séquence d'attribution 1 bloc en bas de la mémoire libre, puis en
bloc tout en haut puis un bloc en bas «collé» au préc édent
l'empêchant d'étendre le premier bloc. Si on attend un peu, on
constate des allocations en haut et en bas toujours jointives. Du
coup je me perd en conjectures sur la stratégie de malloc. Peut à ªtre
un développeur facétieux...



Ça vaut largement sinon son rapport de bug, du moins une bonne
question aux devs.

--
<Sheer> G-Lo, tu l'as trouvée ou ta femme?
<G-Lo> Sheer: en boite
<Bastos> tu l'as monté toi même ?

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
Avatar
François Boisson
Le Tue, 23 Apr 2013 13:10:46 +0200
Bzzz a écrit:

Ça vaut largement sinon son rapport de bug, du moins une bonne
question aux devs.



Les arguments développés dans le fil par Erwan David et Sylvain sont corrects,
rien n'est spécifié dans la doc et le cahier des charges est respecté donc ça
n'est pas un bug, mais effectivement je vais peut être demander ça aux
développeurs (d'un autre coté ils ont peut être autre chose à faire...)

François Boisson

--
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.org/fr/FrenchLists

Pour vous DESABONNER, envoyez un message avec comme objet "unsubscribe"
vers
En cas de soucis, contactez EN ANGLAIS
Archive: http://lists.debian.org/
1 2 3