Git扩展:直到昨天,一切都工作得很好。

但突然我得到这个错误时,我试图拉一些仓库使用git扩展

C:\Program Files\Git\bin\git.exe pull --progress "origin" 
Done
    0 [main] us 0 init_cheap: VirtualAlloc pointer is null, Win32 error 487
AllocationBase 0x0, BaseAddress 0x68560000, RegionSize 0x390000, State 0x10000
C:\Program Files\Git\bin\sh.exe: *** Couldn't reserve space for cygwin's heap, Win32 error 0

我克隆的所有存储库都发生了这种情况。 但是,我的git bash运行良好。 我完全不知道发生了什么。知道为什么会这样吗?


当前回答

删除旧版本的%USERPROFILE%\AppData\Local\SourceTree\app-x.xX为我工作。不知道它是如何连接到命令行git…

其他回答

我在LPCEXpresso构建中遇到过这个问题。如果在PATH中有C:\MinGW\bin。不知何故,我不得不删除它来摆脱这个问题,因为其他一些MinGW喜欢基于

只是想在这里分享我的经验。我在Windows 64位机器上为MTK平台进行交叉编译时遇到了同样的问题。MinGW和MSYS在构建过程中出现了这个问题。我通过修改msys-1.0.dll文件解决了这个问题。无论是rebase.exe还是系统重启对我都不起作用。

因为我的电脑上没有安装rebase.exe。我安装了cygwin64,并在里面使用了rebase.exe:

C:\cygwin64\bin\rebase.exe -b 0x50000000 msys-1.0.dll

虽然改基看起来很成功,但错误仍然存在。然后我在Cygwin64终端内运行rebase命令,得到一个错误:

$ rebase -b 0x50000000 msys-1.0.dll
rebase: Invalid Baseaddress 0x50000000, must be > 0x200000000

后来我试了几个地址,但都不行。所以我最终改变了msys-1.0.dll文件,它解决了这个问题。

Cygwin使用持久共享内存部分,有时可能会损坏。这种情况的症状是一些Cygwin程序开始失败,但其他应用程序不受影响。由于这些共享内存段是持久的,在解决问题之前,通常需要重新启动系统来清除它们。

如果重新启动没有纠正这个问题(正如Greg Hegwill的回答所建议的那样),那么检查您的PATH是否有冲突的msys-1.0.dll安装(可能还有其他相关的dll)。

在我的特殊情况下,MinGW的msys安装在其bin目录(<MinGW_Install_Path>\msys\1.0\bin)中有该DLL的副本,并且它列在PATH中。Git的cmd目录列在PATH中,但它的bin没有。(Git的msys-1.0.dll版本在bin目录下。显然,MSys-Git的默认安装不会将其bin添加到PATH中。)

一个临时的修复是将Git的bin目录添加到PATH中,这样它就会出现在MinGW的路径之前。(一个更永久的修复可能涉及整理MinGW的msys和Git之间的路径冲突和/或删除重复的msys安装。)

tl;dr:安装64位Git for Windows 2。


技术细节

      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代码未能在这个固定地址0x68570000处为堆分配约5 MB的大内存块,而那里显然只有约2.5 MB的大洞可用。相关代码可以在msysgit源代码中看到。


为什么这部分地址空间不是空闲的?

原因有很多。在我的情况下,它是一些其他模块加载在一个冲突的地址:

最后一个地址大约是0x68570000 + 5 MB = 0x68C50000,但是这些wow64相关的dll从0x68810000以上加载,这阻碍了分配。

每当有一些共享DLL时,Windows通常会尝试在所有进程中以相同的虚拟地址加载它,以节省一些重定位处理。这只是一个坏运气的问题,这些系统组件以某种方式加载在一个冲突的地址。


为什么你的Git里有Cygwin ?

因为Git是一个丰富的套件,由一些低级命令和许多有用的实用程序组成,并且主要是在类unix系统上开发的。为了能够在不进行大量重写的情况下构建和运行它,它至少需要一个部分类unix的环境。

为了实现这一点,人们发明了MinGW和MSYS——它们是在Windows上以类似unix的方式开发程序的最小构建工具集。MSYS还包含一个共享库,这个MSYS -1.0.dll,它有助于在运行时解决两个平台之间的一些兼容性问题。其中的许多部分都是从Cygwin那里获得的,因为有人已经在那里解决了同样的问题。

所以不是Cygwin,而是MinGW的运行时DLL行为异常。

在Cygwin中,与MSYS 1.0相比,这段代码实际上发生了很大的变化——该文件的最后一个提交消息说“导入Cygwin 1.3.4”,这是从2001年开始的!

当前的Cygwin和MSYS的新版本(MSYS2)都已经有了不同的逻辑,希望更加健壮。它只是旧版本的Git for Windows,仍然是使用旧的破碎的MSYS系统构建的。


清洁解决方案:

Install Git for Windows 2 - it is built with the new, properly maintained MSYS2 and also has many new features, plenty of bug fixes, security improvements and so on. If at all possible, it is also recommended to use the 64-bit version. But the rebase workaround is performed automatically behind the scenes for 32-bit systems, so the chances of the problem happening there should be lower too. Simply restarting the computer to clean the address space (loading these modules at a different random address) might work, but really, just upgrade to Git for Windows 2 to get the security fixes if nothing else.

出租汽车司机解决方案:

Changing PATH can sometimes work because there might be different versions of msys-1.0.dll in different versions of Git or other MSYS-based applications, which perhaps use different address, different size of this heap etc. Rebasing msys-1.0.dll might be a waste of time, because 1) being a DLL, it already has relocation information and 2) "in any version of Windows OS there is no guarantee that a (...) DLL will always load at same address space" anyway (source). The only way this can help is if the msys-1.0.dll itself loads at the conflicting address it's then trying to use. Apparently that's the case sometimes, as this is what the Git for Windows guys are doing automatically on 32-bit systems. Considering the findings above, I originally binary patched the msys-1.0.dll binary to use a different value for _cygheap_start and that resolved the problem immediately.