c++memorydynamic-linkingskia

Memory crash of modified Skia. Is it due to cross-dynamic-link-library call?


OS: Windows11

I need to utilize the IR part of Skia, so I add SK_API, which will be defined to __declspec(dllexport), __declspec(dllimport) and some other flags, to the hidden functions/classes to export symbols, compile it to dynamic link libraries (I'm working on windows, so *.dll), and link the dlls to my project. Note that I did not modify any code apart from the symbol export. But when the SkSL::Program class destructs, the program crashes and goes into ntdll.dll, which is the memory runtime library of Windows system, and can not be traced further.

The crash in C++ runtime library picture

The crash stack track picture

The crash shows as bellow:

Micro Visual C++ Runtime Library

Debug Assertion Failed!

Program:...kernel fusion\cmake-build-debug-clang-vcpkg\bin\test skia.exeFile: minkernel\crts\ucrt\srclappcrtheapidebug heap.cppLine: 908

Expression: is_block type_valid(header->_block_use)

The IR part of Skia has its own memory allocation/pooling and constructors/destructors, so I assume the problem is caused by cross-dll memory management (I'm not familiar with this). To test this idea, I implement a function in Skia to destruct SkSL::Program and export its symbol for external call (namely executed in skia.dll). However, this can't solve the crash.

Could someone tell me what causes the crash and how to fix it? I would be gratefull.


Solution

  • I finally found the bug. Just as @Botje said, it's because of the mixture of release/debug mode of DLLs, but in a different way.

    When building Skia with the is_debug_build=true arg, I guess it's actually built in Release with Debug Info mode. A friend told me that in windows MSVC runtime library, the std library classes may contain some member variables for Debug mode, but not for Release with Debug Info mode. This may bring the inconsistency of std classes between the skia dll and my project.

    To address this issue, I set the cmake setting set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded") to force the compiler to use MD instead of MDd. And this may link the specific MSVC runtime library version without debug member variables to keep the consistency.