Debug Assertion Failed! Expression: __acrt_first_block == header

前端 未结 5 1298
星月不相逢
星月不相逢 2020-11-30 01:01

I am trying to test the dll which I wrote with GoogleTest and when I call one of the tests It throws me this error:

相关标签:
5条回答
  • 2020-11-30 01:30

    I had a similar problem and it turned out that my unittest project was set to a different code generation runtime library - so by setting it to the same as the DLL project, then no heap exception

    0 讨论(0)
  • 2020-11-30 01:30

    I was seeing this error too and in my case I had all the memory model settings lined up correctly. However having recently upgraded the projects from vs2013 to vs2015 I had stale references between the .exe and .dll, so in fact I was using the old DLL built with 2013. I had to remove the reference between the .exe and .dll and re-add it to update the name of the .lib that the exe was linking against. (Right click on the "References" child item of the .exe project and "Add", while confusingly also allows you to remove a reference).

    0 讨论(0)
  • 2020-11-30 01:31

    I encountered the same error and I found a way to get more information about the cause of the problem: It is possible to set with visual studio a breakpoint condition on the line that raise this error (so that the debugger breaks before the error message).

    It is necessary to open the corresponding file (debug_heap.cpp,somewhere in "C:\Program Files (x86)\Windows Kits\10\Source") and to write the following condition:

    Then we can continue debugging and when the breakpoint is hit, we can observe the address of the block that raise the error (the "block" argument of the "free_dbg_nolock" function that contains the breakpoint).

    From there you can observe the memory content of the block by copying the address into the memory window (Debug->Windows->Memory). If you are lucky it may be a string or an easily recognizable variable.

    You can then identify the variable that causes the bug and try to fix it.

    In my case it was a variable that was created in one dll and deleted in another. To correct it I replaced all my objects by pointers to these objects in one dll.

    0 讨论(0)
  • 2020-11-30 01:37

    As this is a DLL, the problem might lie in different heaps used for allocation and deallocation (try to build the library statically and check if that will work).

    The problem is, that DLLs and templates do not agree together very well. In general, depending on the linkage of the MSVC runtime, it might be problem if the memory is allocated in the executable and deallocated in the DLL and vice versa (because they might have different heaps). And that can happen with templates very easily, for example: you push_back() to the vector inside the removeWhiteSpaces() in the DLL, so the vector memory is allocated inside the DLL. Then you use the output vector in the executable and once it gets out of scope, it is deallocated, but inside the executable whose heap doesn't know anything about the heap it has been allocated from. Bang, you're dead.

    This can be worked-around if both DLL and the executable use the same heap. To ensure this, both the DLL and the executable must use the dynamic MSVC runtime - so make sure, that both link to the runtime dynamically, not statically. In particular, the exe should be compiled and linked with /MD[d] and the library with /LD[d] or /MD[d] as well, neither one with /MT[d]. Note that afterwards the computer which will be running the app will need the MSVC runtime library to run (for example, by installing "Visual C++ Redistributable" for the particular MSVC version).

    You could get that work even with /MT, but that is more difficult - you would need to provide some interface which will allow the objects allocated in the DLL to be deallocated there as well. For example something like:

    __declspec(dllexport) void deallocVector(std::vector<std::string> &x);
    
    void deallocVector(std::vector<std::string> &x) {
        std::vector<std::string> tmp;
        v.swap(tmp);
    }
    

    (however this does not work very well in all cases, as this needs to be called explicitly so it will not be called e.g. in case of exception - to solve this properly, you would need to provide some interface from the DLL, which will cover the vector under the hood and will take care about the proper RAII)


    EDIT: the final solution was actually was to have all of the projects (the exe, dll and the entire googleTest project) built in Multi-threaded Debug DLL (/MDd) (the GoogleTest projects are built in Multi-threaded debug(/MTd) by default)

    0 讨论(0)
  • 2020-11-30 01:38

    That verification was implemented by Microsoft software developers a long time ago in 1992 - 1993 and it is No Longer valid since in case of Heterogeneous or MPI programming a new memory Could Be allocated Not from a Local Heap.

    When an application gets a memory using OpenCL or CUDA APIs a GPU driver does all memory allocations and, of course, it doesn't use the Local Heap of the application. However, the application should release the memory before it exits. At that time Microsoft's Memory Leaks Detection API detects it and that assert is displayed.

    Please take a look at a Video Technical Report regarding origins of that verification:

    Origins of MS Visual Studio 2015 Assert __acrt_first_block == header ( VTR-010 ) https://www.youtube.com/watch?v=NJeA_YkLzxc

    Note: A weblink to the youtube video updated since I've uploaded a video with some corrections.

    0 讨论(0)
提交回复
热议问题