rocksdb
rocksdb copied to clipboard
WriteBatch memory leak with asan
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
#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 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.