Détails techniques
0 [main] us 0 init_cheap: VirtualAlloc pointer is null, Win32 error 487
AllocationBase 0x0, BaseAddress 0x68570000, RegionSize 0x2A0000, State 0x10000
PortableGit\bin\bash.exe: *** Couldn't reserve space for cygwin's heap, Win32 error 0
Ce symptôme en soi n'a rien à voir avec les bases d'images d'exécutables, les sections de mémoire partagée de Cygwin corrompues, les versions conflictuelles des DLL, etc.
C'est le code Cygwin qui n'alloue pas un gros morceau de mémoire de ~ 5 Mo pour son tas à cette adresse fixe 0x68570000, alors que seul un trou de ~ 2,5 Mo était apparemment disponible. Le code pertinent peut être vu dans la source msysgit .
Pourquoi cette partie de l'espace d'adressage n'est-elle pas gratuite?
Il peut y avoir plusieurs raisons. Dans mon cas, il s'agissait d'autres modules chargés à une adresse conflictuelle:
La dernière adresse serait d'environ 0x68570000 + 5 Mo = 0x68C50000, mais il y a ces DLL liées à WOW64 chargées à partir de 0x68810000, qui bloquent l'allocation.
Chaque fois qu'il existe une DLL partagée, Windows en général essaie de la charger à la même adresse virtuelle dans tous les processus pour enregistrer un traitement de relocalisation. C'est juste une question de malchance que ces composants du système se soient en quelque sorte chargés à une adresse conflictuelle cette fois .
Pourquoi y a-t-il Cygwin dans votre Git?
Parce que Git est une suite riche composée de quelques commandes de bas niveau et de nombreux utilitaires utiles, et principalement développée sur des systèmes de type Unix. Afin de pouvoir le construire et l'exécuter sans réécriture massive, il a besoin au moins d'un environnement partiel de type Unix.
Pour ce faire, les gens ont inventé MinGW et MSYS - un ensemble minimal d'outils de construction pour développer des programmes sur Windows à la manière Unix. MSYS contient également une bibliothèque partagée, celle-ci msys-1.0.dll
, qui résout certains des problèmes de compatibilité entre les deux plates-formes lors de l'exécution. Et de nombreux éléments ont été extraits de Cygwin, car quelqu'un devait déjà résoudre les mêmes problèmes là-bas.
Ce n'est donc pas Cygwin, c'est la DLL d'exécution de MinGW qui se comporte bizarrement ici.
Dans Cygwin, ce code a en fait beaucoup changé depuis ce qui se trouve dans MSYS 1.0 - le dernier message de validation pour ce fichier dit "Import Cygwin 1.3.4", qui date de 2001!
Les deux Cygwin actuelle et la nouvelle version de MSYS - MSYS2 - ont déjà une logique différente en place, ce qui est plus robuste , espérons. Ce ne sont que les anciennes versions de Git pour Windows qui ont encore été construites en utilisant l'ancien système MSYS cassé.
Solutions propres:
- Installez Git pour Windows 2 - il est construit avec le nouveau MSYS2 correctement entretenu et possède également de nombreuses nouvelles fonctionnalités, de nombreuses corrections de bugs, des améliorations de sécurité, etc. Si possible, il est également recommandé d' utiliser la version 64 bits . Mais la solution de contournement de rebase est effectuée automatiquement en arrière-plan pour les systèmes 32 bits, donc les chances que le problème se produise là-bas devraient également être plus faibles.
- Le simple redémarrage de l'ordinateur pour nettoyer l'espace d'adressage (chargement de ces modules à une adresse aléatoire différente) peut fonctionner, mais vraiment, il suffit de mettre à niveau vers Git pour Windows 2 pour obtenir les correctifs de sécurité si rien d'autre.
Solutions hacky:
- La modification
PATH
peut parfois fonctionner car il peut y avoir différentes versions de msys-1.0.dll
dans différentes versions de Git ou d'autres applications basées sur MSYS, qui utilisent peut-être une adresse différente, une taille différente de ce tas, etc.
- Le remodelage
msys-1.0.dll
peut être une perte de temps, car 1) étant une DLL, il contient déjà des informations de relocalisation et 2) "dans n'importe quelle version de Windows OS, il n'y a aucune garantie qu'une (...) DLL se charge toujours au même espace d'adressage" de toute façon ( source ). La seule façon dont cela peut aider est que si le msys-1.0.dll
lui - même se charge à l'adresse conflictuelle qu'il essaie ensuite d'utiliser. Apparemment, c'est parfois le cas, car c'est ce que les gars de Git pour Windows font automatiquement sur les systèmes 32 bits .
- Compte tenu des conclusions ci-dessus, j'ai à l'origine binaire corrigé le
msys-1.0.dll
binaire pour utiliser une valeur différente _cygheap_start
et cela a résolu le problème immédiatement.