#14939·rocksdb

SIGSEGV in EnvLogger::Logv() during DBImpl::Close()

Author: guxiaoxieCreated Jul 15, 2026Updated Aug 26, 2026

SIGSEGV in EnvLogger::Logv() during DBImpl::Close() — Logger destroyed before ColumnFamilyData destruction
Environment

  • RocksDB version: 7.9.2 (via rocksdbjni)
  • OS: Linux x86_64 (EulerOS 2.0 SP15)
  • Uptime before crash: ~20 days

Description

We observed a SIGSEGV crash in the RocksDB native library during database close. The crash occurs because EnvLogger is accessed after it has already been destroyed — a lifecycle/ordering bug in the DBImpl::Close() destruction sequence.

Crash Signal

SIGSEGV (0xb) at pc=0x0000000000000000 (null pointer dereference)

Native Stack Trace

C [librocksdbjni*.so+0x555fa3] rocksdb::EnvLogger::Logv(char const*, __va_list_tag*)+0x83 C [librocksdbjni*.so+0x54d08c] C [librocksdbjni*.so+0x54fd61] rocksdb::Log(rocksdb::InfoLogLevel, rocksdb::Logger*, char const*, ...)+0x81 C [librocksdbjni*.so+0x3503d8] rocksdb::ColumnFamilyData::~ColumnFamilyData()+0x538 C [librocksdbjni*.so+0x3504b5] rocksdb::ColumnFamilyData::UnrefAndTryDelete()+0xb5 C [librocksdbjni*.so+0x350528] rocksdb::SuperVersion::Cleanup()+0x48 C [librocksdbjni*.so+0x350492] rocksdb::ColumnFamilyData::UnrefAndTryDelete()+0x92 C [librocksdbjni*.so+0x351f95] rocksdb::ColumnFamilySet::~ColumnFamilySet()+0x25 C [librocksdbjni*.so+0x5007ab] rocksdb::VersionSet::~VersionSet()+0x3b C [librocksdbjni*.so+0x500bc1] rocksdb::VersionSet::~VersionSet()+0x11 C [librocksdbjni*.so+0x3bdf5e] rocksdb::DBImpl::CloseHelper()+0x6de C [librocksdbjni*.so+0x3be5e1] rocksdb::DBImpl::CloseImpl()+0x11 C [librocksdbjni*.so+0x3c1b4e] rocksdb::DBImpl::Close()+0x8e C [librocksdbjni*.so+0x2ac62e] Java_org_rocksdb_RocksDB_closeDatabase+0x1e

Root Cause Analysis

The crash follows this destruction sequence during DBImpl::Close():

DBImpl::Close() → ~VersionSet() → ~ColumnFamilySet() → ColumnFamilyData::UnrefAndTryDelete() → SuperVersion::Cleanup() → ColumnFamilyData::UnrefAndTryDelete() → ~ColumnFamilyData() ← destructor attempts to log → rocksdb::Log(logger, ...) → EnvLogger::Logv() ← SIGSEGV: logger already destroyed

The ColumnFamilyData destructor calls rocksdb::Log() to write a log message, but the Logger object has already been destroyed at this point in the shutdown sequence. This results in a null-pointer function call (pc=0x0000000000000000).

This appears to be a lifecycle ordering bug: the Logger is destroyed before ColumnFamilyData objects that still reference it during their own destruction.

Reproducibility

Low — the service ran for ~20 days before hitting this. It is a race condition during the shutdown path of DBImpl::Close(). The crash is non-deterministic and depends on the specific destruction order of internal objects.

Expected Behavior

DBImpl::Close() should ensure the Logger outlives all ColumnFamilyData objects, or ColumnFamilyData::~ColumnFamilyData() should gracefully handle the case where the logger is no longer available.