使用 GCC 编译的 DLL 中的 malloc() 调用会崩溃,但适用于 Visual Studio

malloc() call in a DLL compiled with GCC crashes, but works with Visual Studio

提问人:LachoTomov 提问时间:12/10/2021 更新时间:12/10/2021 访问量:198

问:

我正在尝试编译以下DLL代码:

int* ptr;

DLLExport int add(int a, int b)
{
    ptr = (int*)malloc(10 * sizeof(int));
    free(ptr);

    return (a + b + 6);
}

此 DLL 在使用 Visual Studio 编译时工作正常,但在使用 mingw/gcc 编译时在 malloc() 调用时崩溃。 但是,以下代码适用于这两种编译器:

DLLExport int add(int a, int b)
{
    int* ptr;
    ptr = (int*)malloc(10 * sizeof(int));
    free(ptr);

    return (a + b + 6);
}

当我将 var 定义为静态时,它也适用于两个编译器,但是该 var 需要是外部的并在多个文件中使用,因此它不能是静态的。我尝试将其设置为易失性,但没有帮助。

我正在使用 Unity 加载 DLL,它崩溃并出现以下错误:

Received signal SIGSEGV
Stack trace:
RtlLookupFunctionEntry returned NULL function. Aborting stack walk.
0x0000020f7d1669b0 (cygwin1) lfind
0x0000020f7d1c5c6b (cygwin1) acl_get_perm
<Missing stacktrace information>

cygwin1.dll 是一个依赖项,我还需要添加它才能加载 mingw DLL(但在使用 VC 编译时我不需要添加任何其他 DLL)。

这是我用于 mingw 的 Makefile:

all:
    g++ -c -o dll.o dll.cpp -O0
    g++ -c -o pch.o pch.cpp
    g++ -shared -o dll.dll ./dll3.o ./pch.o

我的猜测是我缺少一些 g++ 标志,但我无法弄清楚是哪些标志(我尝试了很多)。 以下是 VC 编译器使用的一些命令行:

1>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\CL.exe /c /ZI /JMC /nologo /W3 /WX- /diagnostics:column /sdl /Od /D _DEBUG /D DLL2_EXPORTS /D _WINDOWS /D _USRDLL /D _WINDLL /D _UNICODE /D UNICODE /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Zc:wchar_t /Zc:forScope /Zc:inline /Yc"pch.h" /Fp"x64\Debug\Dll2.pch" /Fo"x64\Debug\\" /Fd"x64\Debug\vc142.pdb" /external:W3 /Gd /TP /FC /errorReport:prompt pch.cpp
 
...
 
1>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Tracker.exe /d "C:\Program Files (x86)\MSBuild\15.0\FileTracker\FileTracker32.dll" /i ...\Dll2\x64\Debug\Dll2.tlog /r ...\DLL2\PCH.CPP /b MSBuildConsole_CancelEvent806a58ad24214fb9a0f508edf8dd6bea  /c "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\CL.exe"  /c /ZI /JMC /nologo /W3 /WX- /diagnostics:column /sdl /Od /D _DEBUG /D DLL2_EXPORTS /D _WINDOWS /D _USRDLL /D _WINDLL /D _UNICODE /D UNICODE /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /permissive- /Zc:wchar_t /Zc:forScope /Zc:inline /Yc"pch.h" /Fp"x64\Debug\Dll2.pch" /Fo"x64\Debug\\" /Fd"x64\Debug\vc142.pdb" /external:W3 /Gd /TP /FC /errorReport:prompt pch.cpp
...
1>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe /ERRORREPORT:PROMPT /OUT:"...\Dll2\x64\Debug\Dll2.dll" /INCREMENTAL /ILK:"x64\Debug\Dll2.ilk" /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:NO /manifest:embed /DEBUG /PDB:"...\Dll2\x64\Debug\Dll2.pdb" /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"...\Dll2\x64\Debug\Dll2.lib" /MACHINE:X64 /DLL x64\Debug\dllmain.obj
 
 

非常感谢您的任何提示!

C++ gcc dll , malloc

评论

0赞 user7860670 12/10/2021
¿是变量的真实名称,还是为了 mcve 而简化?“var 需要是外部的,并在多个文件中使用”——它绝对不应该是。此外,您写了“在 malloc 上崩溃”,但随后您写了“它崩溃并出现以下错误......”,这与 malloc 无关。¿那么是哪一个呢?ptr
0赞 LachoTomov 12/10/2021
@user7860670 是的 - ptr 是实际名称。extern - 我正在尝试将成功编译为 .exe 的大型代码移植到 DLL 中。在原始代码中,var 是 extern。我希望能够以最小的更改保留代码,但我不知道是否可以在 DLL 中使用 extern......malloc - 如果我删除 malloc() 和 free() 调用 - DLL 工作并成功返回结果 - 这就是我的意思。
0赞 user7860670 12/10/2021
也许您忘记将 mingw 运行时 dll 复制到可执行文件的文件夹中?
0赞 user4581301 12/10/2021
关于Cygwin的说明:它是一个POSIX可移植性层,你需要DLL来提供支持功能。如果不需要 POSIX,并且要在 Visual Studio 中生成相同的代码,几乎可以肯定不需要,则可以使用不需要可移植性层或 DLL 的 MinGW 编译器。以下是安装 MSYS 和 MinGW 的说明。MSYS 包括一个包管理器,它可以提供一个大型的有用工具生态系统,非常类似于您在没有 Cygwin 依赖的情况下使用 Cygwin 获得的工具。
0赞 user4581301 12/10/2021
别忘了,代码中的其他地方可能有一个错误,允许它踉踉跄跄地走,直到它最终倒在完全无辜的地方。

答: 暂无答案