Технічні деталі
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
Цей симптом сам по собі не має нічого спільного з базами зображень виконуваних файлів, зіпсованими розділами спільної пам'яті Cygwin, конфліктними версіями DLL тощо.
Цей код Cygwin не в змозі виділити ~ 5 Мб великий фрагмент пам’яті для своєї купи за цією фіксованою адресою 0x68570000, тоді як, очевидно, там був доступний лише отвір розміром 2,5 Мб. Відповідний код можна побачити у джерелі msysgit .
Чому ця частина адресного простору не вільна?
Причин може бути багато. У моєму випадку це були деякі інші модулі, завантажені за конфліктною адресою:
Остання адреса становитиме близько 0x68570000 + 5 MB = 0x68C50000, але є ці DLL-файли, пов’язані з WOW64, завантажені від 0x68810000 вгору, які блокують розподіл.
Щоразу, коли є якась спільна DLL, Windows взагалі намагається завантажити її на одну і ту ж віртуальну адресу у всіх процесах, щоб зберегти деяку обробку переїзду. Це просто невдача, що цього разу ці компоненти системи якось завантажилися на конфліктну адресу .
Чому у вашому Git є Cygwin?
Оскільки Git - це багатий набір, що складається з декількох команд низького рівня та безлічі корисних утиліт, і в основному розробляється на системах, схожих на Unix. Для того, щоб можна було створити його та запустити його без масового переписування, йому потрібно хоча б часткове середовище, схоже на Unix.
Для цього люди винайшли MinGW та MSYS - мінімальний набір інструментів побудови для розробки програм у Windows на зразок Unix. MSYS також містить спільну бібліотеку, msys-1.0.dll
яка допомагає вирішити деякі проблеми сумісності між двома платформами під час виконання. І багато частин цього було взято у Cygwin, тому що комусь уже довелося вирішити ті самі проблеми.
Отже, це не Cygwin, це DLL, що виконується MinGW, те, що тут поводиться дивно.
У Cygwin цей код насправді сильно змінився, оскільки в MSYS 1.0 - останнє повідомлення комісії для цього файлу написано "Імпортувати Cygwin 1.3.4", це з 2001 року!
І теперішній Cygwin, і нова версія MSYS - MSYS2 - вже мають іншу логіку, яка, сподіваємось, більш міцна. Це лише старі версії Git для Windows, які ще побудовані за допомогою старої зламаної системи MSYS.
Чисті розчини:
- Встановіть Git для Windows 2 - він створений за допомогою нового, належним чином підтримуваного MSYS2, а також має багато нових функцій, багато виправлень помилок, покращення безпеки тощо. Якщо це взагалі можливо, також рекомендується використовувати 64-бітну версію . Але вирішення способу відновлення баз даних виконується автоматично за кадром для 32-бітних систем, тому шанси на виникнення проблеми повинні бути і нижчими.
- Просто перезавантажте комп'ютер для очищення адресного простору (завантаження цих модулів за іншою випадковою адресою) може спрацювати, але насправді просто перейдіть на Git для Windows 2, щоб отримати виправлення безпеки, якщо нічого іншого.
Хейкі рішення:
- Зміна
PATH
іноді може спрацювати, оскільки можуть бути різні версії msys-1.0.dll
в різних версіях Git або інших додатків на основі MSYS, які, можливо, використовують різну адресу, різний розмір цієї купи тощо.
- Випуск
msys-1.0.dll
може бути марною витратою часу, оскільки 1) будучи DLL, у нього вже є інформація про переселення та 2) "у будь-якій версії ОС Windows немає гарантії, що (...) DLL завжди завантажуватиметься за тим самим адресним простором" все одно ( джерело ). Єдиний спосіб це може допомогти, якщо він msys-1.0.dll
сам завантажується за конфліктуючою адресою, яку потім намагається використовувати. Мабуть, так буває і так, адже це те, що хлопці Git для Windows роблять автоматично в 32-бітних системах .
- Враховуючи наведені вище висновки, я спочатку двійковим способом виправляв
msys-1.0.dll
бінарне, щоб використовувати інше значення, _cygheap_start
і це негайно вирішило проблему.