Small memory leak when using C API

There seems to be a (small) memory leak in the C API that ASAN detects. This is annoying, because we run ASAN regularly and we’ve worked pretty hard to be leak-free.

Example code to reproduce:

#define FDB_API_VERSION 630
#include <foundationdb/fdb_c.h>
#include <thread>
#include <iostream>
#include <cstdlib>

void checkError(fdb_error_t err) {
    if (err != 0) {
        std::cerr << err << "\n";

int main() {

    auto thread = std::thread([]() { checkError(fdb_run_network()); });

    FDBDatabase* db = nullptr;
    checkError(fdb_create_database("/tmp/fdb.cluster", &db));


Compiled using clang++-12 -fsanitize=address -std=c++17 /tmp/ -o /tmp/a -lfdb_c -ldl -lrt -lpthread on x86_64 Linux, using foundationdb-clients-6.3.22.

==9014==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 32 byte(s) in 1 object(s) allocated from:
    #0 0x4972dd in malloc (/tmp/a+0x4972dd)
    #1 0x7f3dab9d1cb7 in fdb_transaction_set_option (/lib/
    #2 0x7f3dab7627f3 in fdb_transaction_set_option (/lib/
    #3 0x7f3dab762905 in fdb_transaction_set_option (/lib/
    #4 0x7f3dab762c29 in fdb_transaction_set_option (/lib/
    #5 0x7f3dab742dac in fdb_transaction_set_option (/lib/
    #6 0x7f3dab46959e in fdb_transaction_set_option (/lib/
    #7 0x7f3dab641686 in fdb_transaction_set_option (/lib/
    #8 0x7f3dab6417ea in fdb_transaction_set_option (/lib/
    #9 0x7f3dab55b19f in fdb_transaction_set_option (/lib/
    #10 0x7f3dab741536 in fdb_transaction_set_option (/lib/
    #11 0x7f3dab3ed7a1 in fdb_transaction_set_option (/lib/
    #12 0x7f3dab639f3e in fdb_transaction_set_option (/lib/
    #13 0x7f3dab3c4536 in fdb_transaction_set_option (/lib/
    #14 0x7f3dab3993d8 in fdb_run_network (/lib/
    #15 0x4cb4e0 in main::$_0::operator()() const (/tmp/a+0x4cb4e0)
    #16 0x4cb4bc in void std::__invoke_impl<void, main::$_0>(std::__invoke_other, main::$_0&&) (/tmp/a+0x4cb4bc)
    #17 0x4cb44c in std::__invoke_result<main::$_0>::type std::__invoke<main::$_0>(main::$_0&&) (/tmp/a+0x4cb44c)
    #18 0x4cb424 in void std::thread::_Invoker<std::tuple<main::$_0> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (/tmp/a+0x4cb424)
    #19 0x4cb3f4 in std::thread::_Invoker<std::tuple<main::$_0> >::operator()() (/tmp/a+0x4cb3f4)
    #20 0x4cb378 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<main::$_0> > >::_M_run() (/tmp/a+0x4cb378)
    #21 0x7f3dab0ac6b3  (/lib/x86_64-linux-gnu/

Objects leaked above:
0x60300004da10 (32 bytes)

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

I know it’s only 32 bytes, but, because I don’t seem to have good symbol names in, it’s difficult to exclude in LSAN_OPTIONS. (If I also create a transaction, the leak grows to 136 bytes.)

Any thoughts? Is this expected? Am I forgetting to call some cleanup function?