From effcbf2060a48b01779a713fe66c82714a7fb7f2 Mon Sep 17 00:00:00 2001 From: Riccardo Spagni Date: Sat, 29 Sep 2018 22:17:00 +0200 Subject: [PATCH] Merge pull request #4459 bcf3f6af fuzz_tests: catch unhandled exceptions (moneromooo-monero) 3ebd05d4 miner: restore stream flags after changing them (moneromooo-monero) a093092e levin_protocol_handler_async: do not propagate exception through dtor (moneromooo-monero) 1eebb82b net_helper: do not propagate exceptions through dtor (moneromooo-monero) fb6a3630 miner: do not propagate exceptions through dtor (moneromooo-monero) 2e2139ff epee: do not propagate exception through dtor (moneromooo-monero) 0749a8bd db_lmdb: do not propagate exceptions in dtor (moneromooo-monero) 1b0afeeb wallet_rpc_server: exit cleanly on unhandled exceptions (moneromooo-monero) 418a9936 unit_tests: catch unhandled exceptions (moneromooo-monero) ea7f9543 threadpool: do not propagate exceptions through the dtor (moneromooo-monero) 6e855422 gen_multisig: nice exit on unhandled exception (moneromooo-monero) 53df2deb db_lmdb: catch error in mdb_stat calls during migration (moneromooo-monero) e67016dd blockchain_blackball: catch failure to commit db transaction (moneromooo-monero) 661439f4 mlog: don't remove old logs if we failed to rename the current file (moneromooo-monero) 5fdcda50 easylogging++: test for NULL before dereference (moneromooo-monero) 7ece1550 performance_test: fix bad last argument calling add_arg (moneromooo-monero) a085da32 unit_tests: add check for page size > 0 before dividing (moneromooo-monero) d8b1ec8b unit_tests: use std::shared_ptr to shut coverity up about leaks (moneromooo-monero) 02563bf4 simplewallet: top level exception catcher to print nicer messages (moneromooo-monero) c57a65b2 blockchain_blackball: fix shift range for 32 bit archs (moneromooo-monero) --- contrib/epee/include/console_handler.h | 3 +- .../net/levin_protocol_handler_async.h | 6 ++ contrib/epee/include/net/net_helper.h | 3 +- contrib/epee/src/mlog.cpp | 7 +- external/easylogging++/easylogging++.cc | 4 +- src/blockchain_db/lmdb/db_lmdb.cpp | 21 ++++-- .../blockchain_blackball.cpp | 8 ++- src/common/threadpool.cpp | 3 +- src/cryptonote_basic/miner.cpp | 6 +- src/gen_multisig/gen_multisig.cpp | 4 +- src/simplewallet/simplewallet.cpp | 4 +- src/wallet/wallet_rpc_server.cpp | 3 + tests/fuzz/fuzzer.cpp | 4 ++ tests/performance_tests/main.cpp | 8 +-- tests/unit_tests/main.cpp | 4 ++ tests/unit_tests/mlocker.cpp | 69 ++++++++++--------- 16 files changed, 101 insertions(+), 56 deletions(-) diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h index 0e22a971c..2ccf5b095 100644 --- a/contrib/epee/include/console_handler.h +++ b/contrib/epee/include/console_handler.h @@ -63,7 +63,8 @@ namespace epee ~async_stdin_reader() { - stop(); + try { stop(); } + catch (...) { /* ignore */ } } #ifdef HAVE_READLINE diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 0b1fe05fa..e9853ee26 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -275,6 +275,9 @@ public: } virtual ~async_protocol_handler() { + try + { + m_deletion_initiated = true; if(m_connection_initialized) { @@ -288,6 +291,9 @@ public: CHECK_AND_ASSERT_MES_NO_RET(0 == boost::interprocess::ipcdetail::atomic_read32(&m_wait_count), "Failed to wait for operation completion. m_wait_count = " << m_wait_count); MTRACE(m_connection_context << "~async_protocol_handler()"); + + } + catch (...) { /* ignore */ } } bool start_outer_call() diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h index 2c2efcd82..94744ac21 100644 --- a/contrib/epee/include/net/net_helper.h +++ b/contrib/epee/include/net/net_helper.h @@ -106,7 +106,8 @@ namespace net_utils ~blocked_mode_client() { //profile_tools::local_coast lc("~blocked_mode_client()", 3); - shutdown(); + try { shutdown(); } + catch(...) { /* ignore */ } } inline diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index cd9867ff5..61d853ef4 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -137,7 +137,12 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s el::Loggers::addFlag(el::LoggingFlag::StrictLogFileSizeCheck); el::Helpers::installPreRollOutCallback([filename_base, max_log_files](const char *name, size_t){ std::string rname = generate_log_filename(filename_base.c_str()); - rename(name, rname.c_str()); + int ret = rename(name, rname.c_str()); + if (ret < 0) + { + // can't log a failure, but don't do the file removal below + return; + } if (max_log_files != 0) { std::vector found_files; diff --git a/external/easylogging++/easylogging++.cc b/external/easylogging++/easylogging++.cc index b438fa543..a4bdad4cf 100644 --- a/external/easylogging++/easylogging++.cc +++ b/external/easylogging++/easylogging++.cc @@ -1975,11 +1975,11 @@ void VRegistry::setCategories(const char* categories, bool clear) { m_cached_allowed_categories.clear(); m_categoriesString.clear(); } + if (!categories) + return; if (!m_categoriesString.empty()) m_categoriesString += ","; m_categoriesString += categories; - if (!categories) - return; bool isCat = true; bool isLevel = false; diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index d8f7df5f7..824598f8c 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -1145,7 +1145,10 @@ BlockchainLMDB::~BlockchainLMDB() // batch transaction shouldn't be active at this point. If it is, consider it aborted. if (m_batch_active) - batch_abort(); + { + try { batch_abort(); } + catch (...) { /* ignore */ } + } if (m_open) close(); } @@ -3589,7 +3592,9 @@ void BlockchainLMDB::migrate_0_1() throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_heights: ", result).c_str())); if (!i) { MDB_stat ms; - mdb_stat(txn, m_block_heights, &ms); + result = mdb_stat(txn, m_block_heights, &ms); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to query block_heights table: ", result).c_str())); i = ms.ms_entries; } } @@ -3692,7 +3697,9 @@ void BlockchainLMDB::migrate_0_1() throw0(DB_ERROR(lmdb_error("Failed to open a cursor for block_timestamps: ", result).c_str())); if (!i) { MDB_stat ms; - mdb_stat(txn, m_block_info, &ms); + result = mdb_stat(txn, m_block_info, &ms); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to query block_info table: ", result).c_str())); i = ms.ms_entries; } } @@ -3812,7 +3819,9 @@ void BlockchainLMDB::migrate_0_1() throw0(DB_ERROR(lmdb_error("Failed to open a cursor for spent_keys: ", result).c_str())); if (!i) { MDB_stat ms; - mdb_stat(txn, m_hf_versions, &ms); + result = mdb_stat(txn, m_hf_versions, &ms); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to query hf_versions table: ", result).c_str())); i = ms.ms_entries; } } @@ -3967,7 +3976,9 @@ void BlockchainLMDB::migrate_0_1() throw0(DB_ERROR(lmdb_error("Failed to open a cursor for txs: ", result).c_str())); if (!i) { MDB_stat ms; - mdb_stat(txn, m_txs, &ms); + result = mdb_stat(txn, m_txs, &ms); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to query txs table: ", result).c_str())); i = ms.ms_entries; if (i) { MDB_val_set(pk, "txblk"); diff --git a/src/blockchain_utilities/blockchain_blackball.cpp b/src/blockchain_utilities/blockchain_blackball.cpp index 1c6e54d10..5eb2acc79 100644 --- a/src/blockchain_utilities/blockchain_blackball.cpp +++ b/src/blockchain_utilities/blockchain_blackball.cpp @@ -401,7 +401,8 @@ static bool for_all_transactions(const std::string &filename, uint64_t &start_id } mdb_cursor_close(cur); - mdb_txn_commit(txn); + dbr = mdb_txn_commit(txn); + if (dbr) throw std::runtime_error("Failed to commit db transaction: " + std::string(mdb_strerror(dbr))); tx_active = false; mdb_dbi_close(env, dbi); mdb_env_close(env); @@ -471,7 +472,8 @@ static uint64_t find_first_diverging_transaction(const std::string &first_filena for (int i = 0; i < 2; ++i) { mdb_cursor_close(cur[i]); - mdb_txn_commit(txn[i]); + dbr = mdb_txn_commit(txn[i]); + if (dbr) throw std::runtime_error("Failed to query transaction: " + std::string(mdb_strerror(dbr))); tx_active[i] = false; mdb_dbi_close(env[i], dbi[i]); mdb_env_close(env[i]); @@ -675,7 +677,7 @@ static uint64_t get_ring_subset_instances(MDB_txn *txn, uint64_t amount, const s uint64_t extra = 0; std::vector subset; subset.reserve(ring.size()); - for (uint64_t mask = 1; mask < (1u << ring.size()) - 1; ++mask) + for (uint64_t mask = 1; mask < (((uint64_t)1) << ring.size()) - 1; ++mask) { subset.resize(0); for (size_t i = 0; i < ring.size(); ++i) diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp index 6b69e2a12..5ea04a353 100644 --- a/src/common/threadpool.cpp +++ b/src/common/threadpool.cpp @@ -57,7 +57,8 @@ threadpool::~threadpool() { has_work.notify_all(); } for (size_t i = 0; i(total_hr)/static_cast(m_last_hash_rates.size()); + const auto flags = std::cout.flags(); const auto precision = std::cout.precision(); - std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << precision << ENDL; + std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << flags << precision << ENDL; } } m_last_hr_merge_time = misc_utils::get_tick_count(); diff --git a/src/gen_multisig/gen_multisig.cpp b/src/gen_multisig/gen_multisig.cpp index f11f442bc..69be70e1b 100644 --- a/src/gen_multisig/gen_multisig.cpp +++ b/src/gen_multisig/gen_multisig.cpp @@ -167,6 +167,8 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str int main(int argc, char* argv[]) { + TRY_ENTRY(); + po::options_description desc_params(wallet_args::tr("Wallet options")); command_line::add_arg(desc_params, arg_filename_base); command_line::add_arg(desc_params, arg_scheme); @@ -254,5 +256,5 @@ int main(int argc, char* argv[]) return 1; return 0; - //CATCH_ENTRY_L0("main", 1); + CATCH_ENTRY_L0("main", 1); } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 06655ed69..7c68de3f3 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -8073,6 +8073,8 @@ void simple_wallet::commit_or_save(std::vector& ptx_ //---------------------------------------------------------------------------------------------------- int main(int argc, char* argv[]) { + TRY_ENTRY(); + #ifdef WIN32 // Activate UTF-8 support for Boost filesystem classes on Windows std::locale::global(boost::locale::generator().generate("")); @@ -8167,5 +8169,5 @@ int main(int argc, char* argv[]) w.deinit(); } return 0; - //CATCH_ENTRY_L0("main", 1); + CATCH_ENTRY_L0("main", 1); } diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 27631187c..5991e0cc2 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -3457,6 +3457,8 @@ public: std::string const t_executor::NAME = "Wallet RPC Daemon"; int main(int argc, char** argv) { + TRY_ENTRY(); + namespace po = boost::program_options; const auto arg_wallet_file = wallet_args::arg_wallet_file(); @@ -3500,4 +3502,5 @@ int main(int argc, char** argv) { } return daemonizer::daemonize(argc, const_cast(argv), t_executor{}, *vm) ? 0 : 1; + CATCH_ENTRY_L0("main", 1); } diff --git a/tests/fuzz/fuzzer.cpp b/tests/fuzz/fuzzer.cpp index 032ff049a..ab14e2b79 100644 --- a/tests/fuzz/fuzzer.cpp +++ b/tests/fuzz/fuzzer.cpp @@ -46,6 +46,8 @@ static int __AFL_LOOP(int) int run_fuzzer(int argc, const char **argv, Fuzzer &fuzzer) { + TRY_ENTRY(); + if (argc < 2) { std::cout << "usage: " << argv[0] << " " << "" << std::endl; @@ -69,4 +71,6 @@ int run_fuzzer(int argc, const char **argv, Fuzzer &fuzzer) } return 0; + + CATCH_ENTRY_L0("run_fuzzer", 1); } diff --git a/tests/performance_tests/main.cpp b/tests/performance_tests/main.cpp index 7c5135c65..87a1573c2 100644 --- a/tests/performance_tests/main.cpp +++ b/tests/performance_tests/main.cpp @@ -75,10 +75,10 @@ int main(int argc, char** argv) const command_line::arg_descriptor arg_verbose = { "verbose", "Verbose output", false }; const command_line::arg_descriptor arg_stats = { "stats", "Including statistics (min/median)", false }; const command_line::arg_descriptor arg_loop_multiplier = { "loop-multiplier", "Run for that many times more loops", 1 }; - command_line::add_arg(desc_options, arg_filter, ""); - command_line::add_arg(desc_options, arg_verbose, ""); - command_line::add_arg(desc_options, arg_stats, ""); - command_line::add_arg(desc_options, arg_loop_multiplier, ""); + command_line::add_arg(desc_options, arg_filter); + command_line::add_arg(desc_options, arg_verbose); + command_line::add_arg(desc_options, arg_stats); + command_line::add_arg(desc_options, arg_loop_multiplier); po::variables_map vm; bool r = command_line::handle_error_helper(desc_options, [&]() diff --git a/tests/unit_tests/main.cpp b/tests/unit_tests/main.cpp index 13b62cbb4..f7251a09e 100644 --- a/tests/unit_tests/main.cpp +++ b/tests/unit_tests/main.cpp @@ -53,6 +53,8 @@ namespace cryptonote { template class t_cryptonote_protocol_handler data{new char[8 * page_size]}; - epee::mlocker *m0 = new epee::mlocker(BASE(data), 1); - epee::mlocker *m1 = new epee::mlocker(BASE(data) + 2 * page_size, 1); - epee::mlocker *m2 = new epee::mlocker(BASE(data) + 3 * page_size, 1); + std::shared_ptr m0{new epee::mlocker(BASE(data), 1)}; + std::shared_ptr m1{new epee::mlocker(BASE(data) + 2 * page_size, 1)}; + std::shared_ptr m2{new epee::mlocker(BASE(data) + 3 * page_size, 1)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 3); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 3); - delete m0; - delete m1; - delete m2; + m0 = NULL; + m1 = NULL; + m2 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); } @@ -65,14 +65,14 @@ TEST(mlocker, distinct_full_page) const size_t base_pages = epee::mlocker::get_num_locked_pages(); const size_t base_objects = epee::mlocker::get_num_locked_objects(); std::unique_ptr data{new char[8 * page_size]}; - epee::mlocker *m0 = new epee::mlocker(BASE(data), page_size); - epee::mlocker *m1 = new epee::mlocker(BASE(data) + 2 * page_size, page_size); - epee::mlocker *m2 = new epee::mlocker(BASE(data) + 3 * page_size, page_size); + std::shared_ptr m0{new epee::mlocker(BASE(data), page_size)}; + std::shared_ptr m1{new epee::mlocker(BASE(data) + 2 * page_size, page_size)}; + std::shared_ptr m2{new epee::mlocker(BASE(data) + 3 * page_size, page_size)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 3); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 3); - delete m0; - delete m1; - delete m2; + m0 = NULL; + m1 = NULL; + m2 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); } @@ -84,16 +84,16 @@ TEST(mlocker, identical) const size_t base_pages = epee::mlocker::get_num_locked_pages(); const size_t base_objects = epee::mlocker::get_num_locked_objects(); std::unique_ptr data{new char[8 * page_size]}; - epee::mlocker *m0 = new epee::mlocker(BASE(data) + page_size, 32); - epee::mlocker *m1 = new epee::mlocker(BASE(data) + page_size, 32); - epee::mlocker *m2 = new epee::mlocker(BASE(data) + page_size, 32); + std::shared_ptr m0{new epee::mlocker(BASE(data) + page_size, 32)}; + std::shared_ptr m1{new epee::mlocker(BASE(data) + page_size, 32)}; + std::shared_ptr m2{new epee::mlocker(BASE(data) + page_size, 32)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 3); - delete m1; + m1 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 2); - delete m0; - delete m2; + m0 = NULL; + m2 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); } @@ -105,16 +105,16 @@ TEST(mlocker, overlapping_small) const size_t base_pages = epee::mlocker::get_num_locked_pages(); const size_t base_objects = epee::mlocker::get_num_locked_objects(); std::unique_ptr data{new char[8 * page_size]}; - epee::mlocker *m0 = new epee::mlocker(BASE(data), 32); - epee::mlocker *m1 = new epee::mlocker(BASE(data) + 16, 32); - epee::mlocker *m2 = new epee::mlocker(BASE(data) + 8, 32); + std::shared_ptr m0{new epee::mlocker(BASE(data), 32)}; + std::shared_ptr m1{new epee::mlocker(BASE(data) + 16, 32)}; + std::shared_ptr m2{new epee::mlocker(BASE(data) + 8, 32)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 3); - delete m1; + m1 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 2); - delete m2; - delete m0; + m2 = NULL; + m0 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); } @@ -126,16 +126,16 @@ TEST(mlocker, multi_page) const size_t base_pages = epee::mlocker::get_num_locked_pages(); const size_t base_objects = epee::mlocker::get_num_locked_objects(); std::unique_ptr data{new char[8 * page_size]}; - epee::mlocker *m0 = new epee::mlocker(BASE(data) + page_size, page_size * 3); + std::shared_ptr m0{new epee::mlocker(BASE(data) + page_size, page_size * 3)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 3); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 1); - epee::mlocker *m1 = new epee::mlocker(BASE(data) + page_size * 7, page_size); + std::shared_ptr m1{new epee::mlocker(BASE(data) + page_size * 7, page_size)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 4); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 2); - delete m0; + m0 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 1); - delete m1; + m1 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); } @@ -147,10 +147,10 @@ TEST(mlocker, cross_page) const size_t base_pages = epee::mlocker::get_num_locked_pages(); const size_t base_objects = epee::mlocker::get_num_locked_objects(); std::unique_ptr data{new char[2 * page_size]}; - epee::mlocker *m0 = new epee::mlocker(BASE(data) + page_size - 1, 2); + std::shared_ptr m0{new epee::mlocker(BASE(data) + page_size - 1, 2)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 2); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 1); - delete m0; + m0 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); } @@ -158,21 +158,22 @@ TEST(mlocker, cross_page) TEST(mlocker, redundant) { const size_t page_size = epee::mlocker::get_page_size(); + ASSERT_TRUE(page_size > 0); const size_t base_pages = epee::mlocker::get_num_locked_pages(); const size_t base_objects = epee::mlocker::get_num_locked_objects(); std::unique_ptr data{new char[2 * page_size]}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); - epee::mlocker *m0 = new epee::mlocker(BASE(data), 32); + std::shared_ptr m0{new epee::mlocker(BASE(data), 32)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 1); - epee::mlocker *m1 = new epee::mlocker(BASE(data), 32); + std::shared_ptr m1{new epee::mlocker(BASE(data), 32)}; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 2); - delete m1; + m1 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 1); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 1); - delete m0; + m0 = NULL; ASSERT_EQ(epee::mlocker::get_num_locked_pages(), base_pages + 0); ASSERT_EQ(epee::mlocker::get_num_locked_objects(), base_objects + 0); }