CYGWIN 控制台中的奇怪错误 "cygheap base mismatch detected"

Odd error in the CYGWIN console "cygheap base mismatch detected"

我在 CYGWIN (x86_64-pc-cygwin) 和 Windows 10 上用 C 编写了一些简单的应用程序(用于测试)- GCC 9.3.0。它运行良好。但是 1-2 天前 Windows 10 更新了(功能更新 1909 (2))。我不知道更新是下一个错误的原因,但现在应用程序有时可以工作,但更多时候它会失败并出现错误:

$ ./xxx.exe
      0 [main] xxx (7152) D:\prj\xxx\xxx.exe: *** fatal error - cygheap base mismatch detected - 0x180343408/0x1093408.
This problem is probably due to using incompatible versions of the cygwin DLL.
Search for cygwin1.dll using the Windows Start->Find/Search facility
and delete all but the most recent version.  The most recent version *should*
reside in x:\cygwin\bin, where 'x' is the drive on which you have
installed the cygwin distribution.  Rebooting is also suggested if you
are unable to find another cygwin DLL.

在 Cygwin 控制台 (bash) - Cygwin.bat 中为 运行 时会发生这种情况。我在 bash 环境中没有看到奇怪的东西。 但在 PowerShell 中 运行 总是工作正常(cygwin1.dll 与应用程序在同一文件夹中)。 ldd xxx.exe 在 Cygwin 的 bash 显示:

$ ldd xxx.exe
        ntdll.dll => /cygdrive/c/WINDOWS/SYSTEM32/ntdll.dll (0x7fff5e440000)
        KERNEL32.DLL => /cygdrive/c/WINDOWS/System32/KERNEL32.DLL (0x7fff5da50000)
        KERNELBASE.dll => /cygdrive/c/WINDOWS/System32/KERNELBASE.dll (0x7fff5b860000)
        cygwin1.dll => /cygdrive/d/prj/xxx/cygwin1.dll (0xcc0000)
        FreeImage.dll => /cygdrive/d/prj/xxx/FreeImage.dll (0x180000000)
        WS2_32.dll => /cygdrive/c/WINDOWS/System32/WS2_32.dll (0x7fff5d870000)
        VCOMP140.DLL => /cygdrive/c/WINDOWS/SYSTEM32/VCOMP140.DLL (0x7fff55550000)
        RPCRT4.dll => /cygdrive/c/WINDOWS/System32/RPCRT4.dll (0x7fff5d750000)
        USER32.dll => /cygdrive/c/WINDOWS/System32/USER32.dll (0x7fff5e0b0000)
        win32u.dll => /cygdrive/c/WINDOWS/System32/win32u.dll (0x7fff5bd40000)
        GDI32.dll => /cygdrive/c/WINDOWS/System32/GDI32.dll (0x7fff5cac0000)
        gdi32full.dll => /cygdrive/c/WINDOWS/System32/gdi32full.dll (0x7fff5b570000)
        msvcp_win.dll => /cygdrive/c/WINDOWS/System32/msvcp_win.dll (0x7fff5b3d0000)
        ucrtbase.dll => /cygdrive/c/WINDOWS/System32/ucrtbase.dll (0x7fff5b470000)
        cygwin1.dll => /cygdrive/d/prj/xxx/cygwin1.dll (0xec0000)

我用以下方法构建应用程序:

...
CC = d:/apps/cygwin/gcc
LIBS := libFreeImage.a
...
$(EXE): $(OBJECTS) $(HEADERS)
    $(CC) $(CFLAGS) $(OBJECTS) -o $(EXE) $(LIBS)

这是怎么回事?哪里会出错?

rm /cygdrive/d/prj/xxx/cyg*.dll 问题可能会消失。

也就是说,您的 d:\prj\xxx\ 目录中有一个 cygwin1.dll 的恶意副本(可能还有其他 cygwin 二进制文件)与您当前安装的 cygwin 不兼容。 (或 DLL hell).

的其他变体

通常当 运行从 cygwin shell 中加载您的代码时,您只需依赖默认从 /usr/bin 加载的 cygwin DLL,而不是从 LDPATH、PATH , 或本地目录。

然后将您的 EXE 分发给非 cygwin 用户(或者简单地 运行 您在 Cygwin shell 之外的 EXE),您将 EXE 和所有相关的 DLL 一起打包到同一个文件夹。按照您的方式,您似乎在 Cygwin 环境和源代码路径中混合和匹配 DLL 位置。

然后 运行 回到 Windows 命令行参数,打包你的 EXE 和 cygwin1.dll 回到同一个文件夹。

为了消除任何其他疑虑,只需重建您的代码并将 Cygwin 更新到最新版本。