rocksdb icon indicating copy to clipboard operation
rocksdb copied to clipboard

WriteBatch memory leak with asan

Open caijillx opened this issue 7 months ago • 2 comments

example code

#include <iostream>
#include <string>
#include <string_view>

#include "rocksdb/db.h"

std::string GetTempString() {
  std::string temp = "temp_value";
  return temp;
}

int main() {
  rocksdb::DB* db;
  rocksdb::Options options;
  options.create_if_missing = true;

  rocksdb::Status status =
      rocksdb::DB::Open(options, "/tmp/rocksdb_slice_test", &db);

  rocksdb::WriteBatch batch;

  batch.Put("key", GetTempString());

  status = db->Write(rocksdb::WriteOptions(), &batch);

  std::string tmp;
  status = db->Get(rocksdb::ReadOptions(), "key", &tmp);
  std::cout << "Written value: " << tmp << " error: " << status.ToString()
            << std::endl;

  delete db;
  return 0;
}

compile

g++ -g -O0 -std=c++17 main.cc \
    librocksdb.a \
    -I./rocksdb-10.1.3/include \
    -pthread -ldl -lz \
    -fsanitize=address -static-libasan -static-libstdc++ -static-libgcc

execute

./a.out
Written value: temp_value error: OK

=================================================================
==43388==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 24 byte(s) in 1 object(s) allocated from:
    #0 0x5a5847 in operator new(unsigned long, std::nothrow_t const&) (/data2/lileixin.llx/test/a.out+0x5a5847)
    #1 0xaf867d in __cxa_thread_atexit (/data2/lileixin.llx/test/a.out+0xaf867d)

SUMMARY: AddressSanitizer: 24 byte(s) leaked in 1 allocation(s).

Note

This memory leak occurs approximately once every 3 runs on average os : linux-4.19 on x86 g++ : 9.21

caijillx avatar May 20 '25 12:05 caijillx


#include <iostream>
#include <string>
#include <string_view>

#include <rocksdb/db.h>
#include <rocksdb/options.h>
#include <rocksdb/write_batch.h>

std::string GetTempString() {
  std::string temp = "temp_value";
  return temp;
}

int main() {
  // Initialize RocksDB options
  rocksdb::Options options;
  options.create_if_missing = true;

  // Database pointer
  rocksdb::DB* db = nullptr;

  // Open the database
  rocksdb::Status status = rocksdb::DB::Open(options, "/tmp/rocksdb_slice_test", &db);
  if (!status.ok()) {
    std::cerr << "Failed to open database: " << status.ToString() << std::endl;
    return 1;
  }

  // Ensure database is properly closed even if an error occurs
  struct DBDeleter {
    rocksdb::DB* db_;
    DBDeleter(rocksdb::DB* db) : db_(db) {}
    ~DBDeleter() {
      if (db_) {
        db_->Close(); // Explicitly close the database
        delete db_;
      }
    }
  } db_deleter(db);

  // Write to database using a batch
  rocksdb::WriteBatch batch;
  batch.Put("key", GetTempString());

  rocksdb::WriteOptions write_options;
  status = db->Write(write_options, &batch);
  if (!status.ok()) {
    std::cerr << "Failed to write to database: " << status.ToString() << std::endl;
    return 1;
  }

  // Read from database
  std::string value;
  rocksdb::ReadOptions read_options;
  status = db->Get(read_options, "key", &value);
  if (status.ok()) {
    std::cout << "Written value: " << value << " error: " << status.ToString() << std::endl;
  } else {
    std::cerr << "Failed to read from database: " << status.ToString() << std::endl;
    return 1;
  }

  return 0;
}

ljluestc avatar May 20 '25 12:05 ljluestc

@ljluestc Thank you for your help. I tried using your program, but memory leaks are still detected. It seems that db->Close(); is not the key to solving the problem. According to issue #5931 This appears to be a known issue? I am using version 10.1.3, and not sure if it's normal for this issue to still exist in this version.

caijillx avatar May 20 '25 15:05 caijillx