c++heap-memorycplexheap-corruption

heap corruption tracing in C++ with CPLEX


I cannot find a solution how to trace a heap corruption error to its root cause in C++.

I have programmed a CPLEX model in C++ and till now everything was fine. I used to test some new instances and now I get all of the sudden heap corruption errors. The application verifier gives me this back:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<avrf:logfile xmlns:avrf="Application Verifier">
    <avrf:logSession TimeStarted="2022-01-27 : 14:40:09" PID="7876" Version="2">
        <avrf:logEntry Time="2022-01-27 : 14:40:27" LayerName="Heaps" StopCode="0xF" Severity="Error">
            <avrf:message>Corrupted suffix pattern for heap block.</avrf:message>
            <avrf:parameter1>1f684551000 - Heap handle used in the call.</avrf:parameter1>
            <avrf:parameter2>1f6871a7fe0 - Heap block involved in the operation.</avrf:parameter2>
            <avrf:parameter3>18 - Size of the heap block.</avrf:parameter3>
            <avrf:parameter4>1f6871a7ff8 - Corruption address.</avrf:parameter4>
            <avrf:stackTrace>
                <avrf:trace>vrfcore!VerifierDisableVerifier+7a7 ( @ 0)</avrf:trace>
                <avrf:trace>verifier!VerifierStopMessage+b9 ( @ 0)</avrf:trace>
                <avrf:trace>verifier!VerifierDisableFaultInjectionExclusionRange+3693 ( @ 0)</avrf:trace>
                <avrf:trace>verifier!VerifierDisableFaultInjectionExclusionRange+39a4 ( @ 0)</avrf:trace>
                <avrf:trace>verifier!VerifierDisableFaultInjectionExclusionRange+b02 ( @ 0)</avrf:trace>
                <avrf:trace>verifier!VerifierDisableFaultInjectionExclusionRange+c3f ( @ 0)</avrf:trace>
                <avrf:trace>verifier!VerifierDisableFaultInjectionExclusionRange+27ad ( @ 0)</avrf:trace>
                <avrf:trace>ntdll!RtlRegisterSecureMemoryCacheCallback+1744 ( @ 0)</avrf:trace>
                <avrf:trace>ntdll!RtlGetCurrentServiceSessionId+1471 ( @ 0)</avrf:trace>
                <avrf:trace>ntdll!RtlGetCurrentServiceSessionId+1324 ( @ 0)</avrf:trace>
                <avrf:trace>ntdll!RtlFreeHeap+51 ( @ 0)</avrf:trace>
                <avrf:trace>vrfcore!VerifierSetAPIClassName+1fc ( @ 0)</avrf:trace>
                <avrf:trace>ucrtbase!free_base+1b ( @ 0)</avrf:trace>
                <avrf:trace>my_exe!std::_Deallocate&lt;16,0&gt;+57 (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\xmemory @ 255)</avrf:trace>
                <avrf:trace>my_exe!std::allocator&lt;int&gt;::deallocate+43 (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\xmemory @ 823)</avrf:trace>
                <avrf:trace>my_exe!std::vector&lt;int,std::allocator&lt;int&gt; &gt;::_Tidy+b2 (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\vector @ 1635)</avrf:trace>
                <avrf:trace>my_exe!std::vector&lt;int,std::allocator&lt;int&gt; &gt;::~vector&lt;int,std::allocator&lt;int&gt; &gt;+2b (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\vector @ 588)</avrf:trace>
                <avrf:trace>my_exe!std::vector&lt;int,std::allocator&lt;int&gt; &gt;::`scalar deleting destructor&apos;+23 ( @ 0)</avrf:trace>
                <avrf:trace>my_exe!std::_Default_allocator_traits&lt;std::allocator&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt; &gt; &gt;::destroy&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt; &gt;+32 (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\xmemory @ 692)</avrf:trace>
                <avrf:trace>my_exe!std::_Destroy_range&lt;std::allocator&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt; &gt; &gt;+68 (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\xmemory @ 937)</avrf:trace>
                <avrf:trace>my_exe!std::vector&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt;,std::allocator&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt; &gt; &gt;::_Tidy+87 (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\vector @ 1633)</avrf:trace>
                <avrf:trace>my_exe!std::vector&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt;,std::allocator&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt; &gt; &gt;::~vector&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt;,std::allocator&lt;std::vector&lt;int,std::allocator&lt;int&gt; &gt; &gt; &gt;+2b (C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\vector @ 588)</avrf:trace>
                <avrf:trace>my_exe!Model::~Model+124 ( @ 0)</avrf:trace>
                <avrf:trace>my_exe!Simulation::Simulation+fbd (C:\Users\un_po\source\repos\my_exe\my_exe\Simulation.cpp @ 240)</avrf:trace>
                <avrf:trace>my_exe!main+5c1 (C:\Users\un_po\source\repos\my_exe\my_exe\run.cpp @ 188)</avrf:trace>
                <avrf:trace>my_exe!__scrt_common_main_seh+10c (d:\a01\_work\20\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288)</avrf:trace>
                <avrf:trace>KERNEL32!BaseThreadInitThunk+14 ( @ 0)</avrf:trace>
                <avrf:trace>ntdll!RtlUserThreadStart+21 ( @ 0)</avrf:trace>
            </avrf:stackTrace>
        </avrf:logEntry>
    </avrf:logSession>
</avrf:logfile>

I read somewhere that I can use the adress to find the error, but unfortunately I am lost. I also enabled page heap in gflag. I tried to run my program in WinDBG, but the code is not executing with command line arguments...

Any advices where to continue from here?


Solution

  • So I debugged the code for quite some hours and finally found a buffer overflow of a vector, by assign a value outside of the vector length. I don't quite understand why I did not get any error message for that, but I am glad this was over. Some useful post.

    Thanks to @TimChippingtonDerrick for giving the right directions.