kuzudb / kuzu

Embeddable property graph database management system built for query speed and scalability. Implements Cypher.
https://kuzudb.com/
MIT License
1.32k stars 94 forks source link

assertion when freeing kuzu::main::QueryResult in windows x64 #3232

Open neeraj9 opened 6 months ago

neeraj9 commented 6 months ago

Kuzu Version: 0.3.2 Software: Windows 11, x64, VS 2022

I am facing a weird issue wherein when the kuzu::main::QueryResult is destroyed then ntdll.dll (on Windows x64) asserts that the heap pointer which is to be freed is invalid. I am building kuzu_shared.dll in Release configuration and using it in my application (c++) in Debug configuration. I am using other third party libraries as well.

Is there a better way to debug this, since it appears to be a memory allocation / deallocation issue.

Sample source code:

{
  // ... scope
  auto kr = connection_->query(query);
  if (!kr->isSuccess())
  {
      logger_.logTrace("ERROR: Failed to run query, error: " + kr->getErrorMessage());
      success = false;
      break;
  }
  // ...
}  // error because kr goes out of scope and delete is called on the memory allocated by Kuzu

file: C:\Program Files (x86)\Windows Kits\10\Source\10.0.22621.0\ucrt\heap\debug_heap.cpp

    // If this assertion fails, a bad pointer has been passed in.  It may be
    // totally bogus, or it may have been allocated from another heap.  The
    // pointer must have been allocated from the CRT heap.
    _ASSERTE(_CrtIsValidHeapPointer(block));
// This function is provided for backwards compatibility only.  It returns TRUE
// if the given block points to an allocation from the OS heap that underlies
// this CRT debug heap.  Back when the CRT used its own OS heap (prior to Dev10),
// this function would thus also tell you whether the block was allocated by this
// debug heap.  Now, it just tells you whether the block was allocated by some
// debug heap.
extern "C" int __cdecl _CrtIsValidHeapPointer(void const* const block)
{
    if (!block)
        return FALSE;

    return HeapValidate(__acrt_heap, 0, header_from_block(block));
}

Error details:

A breakpoint instruction (__debugbreak() statement or a similar call) was executed in app.exe.
LowLevelMahn commented 6 months ago

the Dll of Kuzu is using a different CRT as your application (Release-CRT vs. Debug-CRT) that means the heap that the Dll is controlling is different to your applications heap - that means allocated pointers from the Dll can't be freed in your application because the pointer is allocated in a different heap - that results normaly in these type of asserts (because or different to linux - Microsoft activates the debugging Heap or Debugging-STL per default)

it should work if you build a Kuzu-Debug and a Kuzu-Release build dll (and if the CRT is shared) - different C++ lib builds for Release/Debug is typical

C libraries are usually free of such dependencies and can be use between Debug and Release builds of your Application without a problem - but the Kuzu C-API is currently not safely done this way, see https://github.com/kuzudb/kuzu/issues/2527