diff --git a/base/daemon/BaseDaemon.cpp b/base/daemon/BaseDaemon.cpp index 22455d09cf2..ec1d1b3b8cf 100644 --- a/base/daemon/BaseDaemon.cpp +++ b/base/daemon/BaseDaemon.cpp @@ -768,7 +768,7 @@ void BaseDaemon::initializeTerminationAndSignalProcessing() signal_listener_thread.start(*signal_listener); #if defined(__ELF__) && !defined(__FreeBSD__) - String build_id_hex = DB::SymbolIndex::instance().getBuildIDHex(); + String build_id_hex = DB::SymbolIndex::instance()->getBuildIDHex(); if (build_id_hex.empty()) build_id_info = "no build id"; else diff --git a/base/daemon/SentryWriter.cpp b/base/daemon/SentryWriter.cpp index 33f2b237dd5..b52f3540bbc 100644 --- a/base/daemon/SentryWriter.cpp +++ b/base/daemon/SentryWriter.cpp @@ -168,7 +168,7 @@ void SentryWriter::onFault(int sig, const std::string & error_message, const Sta sentry_set_extra("signal_number", sentry_value_new_int32(sig)); #if defined(__ELF__) && !defined(__FreeBSD__) - const String & build_id_hex = DB::SymbolIndex::instance().getBuildIDHex(); + const String & build_id_hex = DB::SymbolIndex::instance()->getBuildIDHex(); sentry_set_tag("build_id", build_id_hex.c_str()); #endif diff --git a/src/Access/AccessType.h b/src/Access/AccessType.h index 11896f628d9..1a070420fd1 100644 --- a/src/Access/AccessType.h +++ b/src/Access/AccessType.h @@ -127,6 +127,7 @@ enum class AccessType M(SYSTEM_DROP_COMPILED_EXPRESSION_CACHE, "SYSTEM DROP COMPILED EXPRESSION, DROP COMPILED EXPRESSION CACHE, DROP COMPILED EXPRESSIONS", GLOBAL, SYSTEM_DROP_CACHE) \ M(SYSTEM_DROP_CACHE, "DROP CACHE", GROUP, SYSTEM) \ M(SYSTEM_RELOAD_CONFIG, "RELOAD CONFIG", GLOBAL, SYSTEM_RELOAD) \ + M(SYSTEM_RELOAD_SYMBOLS, "RELOAD SYMBOLS", GLOBAL, SYSTEM_RELOAD) \ M(SYSTEM_RELOAD_DICTIONARY, "SYSTEM RELOAD DICTIONARIES, RELOAD DICTIONARY, RELOAD DICTIONARIES", GLOBAL, SYSTEM_RELOAD) \ M(SYSTEM_RELOAD_EMBEDDED_DICTIONARIES, "RELOAD EMBEDDED DICTIONARIES", GLOBAL, SYSTEM_RELOAD) /* implicitly enabled by the grant SYSTEM_RELOAD_DICTIONARY ON *.* */\ M(SYSTEM_RELOAD, "", GROUP, SYSTEM) \ diff --git a/src/Common/StackTrace.cpp b/src/Common/StackTrace.cpp index 9cfdba2687f..b285a45bdc5 100644 --- a/src/Common/StackTrace.cpp +++ b/src/Common/StackTrace.cpp @@ -195,7 +195,8 @@ void StackTrace::symbolize(const StackTrace::FramePointers & frame_pointers, siz { #if defined(__ELF__) && !defined(__FreeBSD__) && !defined(ARCADIA_BUILD) - const DB::SymbolIndex & symbol_index = DB::SymbolIndex::instance(); + auto symbol_index_ptr = DB::SymbolIndex::instance(); + const DB::SymbolIndex & symbol_index = *symbol_index_ptr; std::unordered_map dwarfs; for (size_t i = 0; i < offset; ++i) @@ -316,7 +317,8 @@ static void toStringEveryLineImpl( return callback(""); #if defined(__ELF__) && !defined(__FreeBSD__) - const DB::SymbolIndex & symbol_index = DB::SymbolIndex::instance(); + auto symbol_index_ptr = DB::SymbolIndex::instance(); + const DB::SymbolIndex & symbol_index = *symbol_index_ptr; std::unordered_map dwarfs; std::stringstream out; // STYLE_CHECK_ALLOW_STD_STRING_STREAM diff --git a/src/Common/SymbolIndex.cpp b/src/Common/SymbolIndex.cpp index a738512bb30..a9b657e671b 100644 --- a/src/Common/SymbolIndex.cpp +++ b/src/Common/SymbolIndex.cpp @@ -300,13 +300,13 @@ void collectSymbolsFromELF(dl_phdr_info * info, String our_build_id = getBuildIDFromProgramHeaders(info); - /// If the name is empty - it's main executable. - /// Find a elf file for the main executable. - + /// If the name is empty and there is a non-empty build-id - it's main executable. + /// Find a elf file for the main executable and set the build-id. if (object_name.empty()) { object_name = "/proc/self/exe"; - build_id = our_build_id; + if (build_id.empty()) + build_id = our_build_id; } std::error_code ec; @@ -316,9 +316,16 @@ void collectSymbolsFromELF(dl_phdr_info * info, return; /// Debug info and symbol table sections may be split to separate binary. + std::filesystem::path local_debug_info_path = canonical_path.parent_path() / canonical_path.stem(); + local_debug_info_path += ".debug"; std::filesystem::path debug_info_path = std::filesystem::path("/usr/lib/debug") / canonical_path.relative_path(); - object_name = std::filesystem::exists(debug_info_path) ? debug_info_path : canonical_path; + if (std::filesystem::exists(local_debug_info_path)) + object_name = local_debug_info_path; + else if (std::filesystem::exists(debug_info_path)) + object_name = debug_info_path; + else + object_name = canonical_path; /// But we have to compare Build ID to check that debug info corresponds to the same executable. @@ -434,10 +441,12 @@ String SymbolIndex::getBuildIDHex() const return build_id_hex; } -SymbolIndex & SymbolIndex::instance() +MultiVersion::Version SymbolIndex::instance(bool reload) { - static SymbolIndex instance; - return instance; + static MultiVersion instance(std::unique_ptr(new SymbolIndex)); + if (reload) + instance.set(std::unique_ptr(new SymbolIndex)); + return instance.get(); } } diff --git a/src/Common/SymbolIndex.h b/src/Common/SymbolIndex.h index 8ef0a949515..b310f90988e 100644 --- a/src/Common/SymbolIndex.h +++ b/src/Common/SymbolIndex.h @@ -7,6 +7,7 @@ #include #include +#include namespace DB { @@ -21,7 +22,7 @@ protected: SymbolIndex() { update(); } public: - static SymbolIndex & instance(); + static MultiVersion::Version instance(bool reload = false); struct Symbol { diff --git a/src/Common/tests/symbol_index.cpp b/src/Common/tests/symbol_index.cpp index 67defa77242..3811bbbdd71 100644 --- a/src/Common/tests/symbol_index.cpp +++ b/src/Common/tests/symbol_index.cpp @@ -25,7 +25,8 @@ int main(int argc, char ** argv) return 1; } - const SymbolIndex & symbol_index = SymbolIndex::instance(); + auto symbol_index_ptr = SymbolIndex::instance(); + const SymbolIndex & symbol_index = *symbol_index_ptr; for (const auto & elem : symbol_index.symbols()) std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n"; diff --git a/src/Functions/addressToLine.cpp b/src/Functions/addressToLine.cpp index 0cee8365531..59e347dd348 100644 --- a/src/Functions/addressToLine.cpp +++ b/src/Functions/addressToLine.cpp @@ -106,7 +106,8 @@ private: StringRef impl(uintptr_t addr) const { - const SymbolIndex & symbol_index = SymbolIndex::instance(); + auto symbol_index_ptr = SymbolIndex::instance(); + const SymbolIndex & symbol_index = *symbol_index_ptr; if (const auto * object = symbol_index.findObject(reinterpret_cast(addr))) { diff --git a/src/Functions/addressToSymbol.cpp b/src/Functions/addressToSymbol.cpp index e0c87b7bbb9..5accfd1dd94 100644 --- a/src/Functions/addressToSymbol.cpp +++ b/src/Functions/addressToSymbol.cpp @@ -66,7 +66,8 @@ public: ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override { - const SymbolIndex & symbol_index = SymbolIndex::instance(); + auto symbol_index_ptr = SymbolIndex::instance(); + const SymbolIndex & symbol_index = *symbol_index_ptr; const ColumnPtr & column = arguments[0].column; const ColumnUInt64 * column_concrete = checkAndGetColumn(column.get()); diff --git a/src/Functions/buildId.cpp b/src/Functions/buildId.cpp index ffe3da27153..7361f0e4546 100644 --- a/src/Functions/buildId.cpp +++ b/src/Functions/buildId.cpp @@ -40,7 +40,7 @@ public: ColumnPtr executeImpl(const ColumnsWithTypeAndName &, const DataTypePtr &, size_t input_rows_count) const override { - return DataTypeString().createColumnConst(input_rows_count, SymbolIndex::instance().getBuildIDHex()); + return DataTypeString().createColumnConst(input_rows_count, SymbolIndex::instance()->getBuildIDHex()); } }; diff --git a/src/Interpreters/CrashLog.cpp b/src/Interpreters/CrashLog.cpp index 9d84d5a18e9..bf81a2e8aba 100644 --- a/src/Interpreters/CrashLog.cpp +++ b/src/Interpreters/CrashLog.cpp @@ -53,7 +53,7 @@ void CrashLogElement::appendToBlock(MutableColumns & columns) const String build_id_hex; #if defined(__ELF__) && !defined(__FreeBSD__) - build_id_hex = SymbolIndex::instance().getBuildIDHex(); + build_id_hex = SymbolIndex::instance()->getBuildIDHex(); #endif columns[i++]->insert(build_id_hex); } diff --git a/src/Interpreters/InterpreterSystemQuery.cpp b/src/Interpreters/InterpreterSystemQuery.cpp index e59d0f925e9..95642d9419b 100644 --- a/src/Interpreters/InterpreterSystemQuery.cpp +++ b/src/Interpreters/InterpreterSystemQuery.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -271,6 +272,10 @@ BlockIO InterpreterSystemQuery::execute() context.checkAccess(AccessType::SYSTEM_RELOAD_CONFIG); system_context.reloadConfig(); break; + case Type::RELOAD_SYMBOLS: + context.checkAccess(AccessType::SYSTEM_RELOAD_SYMBOLS); + (void)SymbolIndex::instance(true); + break; case Type::STOP_MERGES: startStopAction(ActionLocks::PartsMerge, false); break; @@ -604,6 +609,11 @@ AccessRightsElements InterpreterSystemQuery::getRequiredAccessForDDLOnCluster() required_access.emplace_back(AccessType::SYSTEM_RELOAD_CONFIG); break; } + case Type::RELOAD_SYMBOLS: + { + required_access.emplace_back(AccessType::SYSTEM_RELOAD_SYMBOLS); + break; + } case Type::STOP_MERGES: [[fallthrough]]; case Type::START_MERGES: { diff --git a/src/Parsers/ASTSystemQuery.cpp b/src/Parsers/ASTSystemQuery.cpp index 4ed0ecd3a91..0d6e15a3d8c 100644 --- a/src/Parsers/ASTSystemQuery.cpp +++ b/src/Parsers/ASTSystemQuery.cpp @@ -54,6 +54,8 @@ const char * ASTSystemQuery::typeToString(Type type) return "RELOAD EMBEDDED DICTIONARIES"; case Type::RELOAD_CONFIG: return "RELOAD CONFIG"; + case Type::RELOAD_SYMBOLS: + return "RELOAD SYMBOLS"; case Type::STOP_MERGES: return "STOP MERGES"; case Type::START_MERGES: diff --git a/src/Parsers/ASTSystemQuery.h b/src/Parsers/ASTSystemQuery.h index f8f803e1c0c..756b5b52600 100644 --- a/src/Parsers/ASTSystemQuery.h +++ b/src/Parsers/ASTSystemQuery.h @@ -36,6 +36,7 @@ public: RELOAD_DICTIONARIES, RELOAD_EMBEDDED_DICTIONARIES, RELOAD_CONFIG, + RELOAD_SYMBOLS, STOP_MERGES, START_MERGES, STOP_TTL_MERGES,