Detalles técnicos
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
Este síntoma por sí solo no tiene nada que ver con bases de imágenes de ejecutables, secciones de memoria compartida de Cygwin corruptas, versiones conflictivas de DLL, etc.
Es el código de Cygwin que no puede asignar una gran parte de memoria de ~ 5 MB para su almacenamiento dinámico en esta dirección fija 0x68570000, mientras que aparentemente solo hay un agujero ~ 2.5 MB de gran tamaño disponible allí. El código relevante se puede ver en la fuente msysgit .
¿Por qué esa parte del espacio de direcciones no es gratuita?
Puede haber muchas razones. En mi caso, fueron algunos otros módulos cargados en una dirección en conflicto:
La última dirección sería alrededor de 0x68570000 + 5 MB = 0x68C50000, pero hay estas DLL relacionadas con WOW64 cargadas desde 0x68810000 en adelante, que bloquean la asignación.
Cada vez que hay una DLL compartida, Windows en general intenta cargarla en la misma dirección virtual en todos los procesos para guardar algunos procesos de reubicación. Es solo una cuestión de mala suerte que estos componentes del sistema se hayan cargado de alguna manera en una dirección en conflicto esta vez .
¿Por qué hay Cygwin en tu Git?
Porque Git es un conjunto rico que consta de algunos comandos de bajo nivel y muchas utilidades útiles, y desarrollado principalmente en sistemas tipo Unix. Para poder construirlo y ejecutarlo sin una reescritura masiva, necesita al menos un entorno similar a Unix parcial.
Para lograr eso, las personas han inventado MinGW y MSYS, un conjunto mínimo de herramientas de compilación para desarrollar programas en Windows de manera similar a Unix. MSYS también contiene una biblioteca compartida, esto msys-1.0.dll
, que ayuda con algunos de los problemas de compatibilidad entre las dos plataformas durante el tiempo de ejecución. Y muchas partes de eso han sido tomadas de Cygwin, porque alguien ya tenía que resolver los mismos problemas allí.
Entonces, no es Cygwin, es la DLL de tiempo de ejecución de MinGW lo que se está comportando raro aquí.
En Cygwin, este código ha cambiado mucho desde lo que hay en MSYS 1.0: el último mensaje de confirmación para ese archivo dice "Importar Cygwin 1.3.4", ¡que es de 2001!
Tanto Cygwin actual como la nueva versión de MSYS , MSYS2, ya tienen una lógica diferente, lo que es de esperar que sea más robusto. Solo las versiones antiguas de Git para Windows se han creado utilizando el antiguo sistema MSYS roto.
Soluciones limpias:
- Instale Git para Windows 2 : está construido con el nuevo MSYS2 mantenido correctamente y también tiene muchas características nuevas, muchas correcciones de errores, mejoras de seguridad, etc. Si es posible, también se recomienda utilizar la versión de 64 bits . Pero la solución alternativa de rebase se realiza automáticamente detrás de escena para sistemas de 32 bits, por lo que las posibilidades de que el problema ocurra allí también deberían ser menores.
- Simplemente reiniciar la computadora para limpiar el espacio de direcciones (cargar estos módulos en una dirección aleatoria diferente) podría funcionar, pero en realidad, simplemente actualice a Git para Windows 2 para obtener las soluciones de seguridad, si nada más.
Soluciones Hacky:
- El cambio a
PATH
veces puede funcionar porque puede haber diferentes versiones de msys-1.0.dll
diferentes versiones de Git u otras aplicaciones basadas en MSYS, que tal vez usen diferentes direcciones, diferentes tamaños de este montón, etc.
- Rebasar
msys-1.0.dll
podría ser una pérdida de tiempo, porque 1) al ser una DLL, ya tiene información de reubicación y 2) "en cualquier versión del sistema operativo Windows no hay garantía de que una (...) DLL siempre se cargue en el mismo espacio de direcciones" de todos modos ( fuente ). La única forma en que esto puede ayudar es si el msys-1.0.dll
mismo se carga en la dirección en conflicto que está tratando de usar. Aparentemente ese es el caso a veces, ya que esto es lo que los chicos de Git para Windows están haciendo automáticamente en sistemas de 32 bits .
- Teniendo en cuenta los hallazgos anteriores, originalmente binario parcheé el
msys-1.0.dll
binario para usar un valor diferente _cygheap_start
y eso resolvió el problema de inmediato.