reload symbols and fix build-id

This commit is contained in:
Amos Bird 2020-11-30 22:30:55 +08:00
parent cbbdec572a
commit 310918b06a
No known key found for this signature in database
GPG Key ID: 80D430DCBECFEDB4
14 changed files with 47 additions and 18 deletions

View File

@ -768,7 +768,7 @@ void BaseDaemon::initializeTerminationAndSignalProcessing()
signal_listener_thread.start(*signal_listener); signal_listener_thread.start(*signal_listener);
#if defined(__ELF__) && !defined(__FreeBSD__) #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()) if (build_id_hex.empty())
build_id_info = "no build id"; build_id_info = "no build id";
else else

View File

@ -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)); sentry_set_extra("signal_number", sentry_value_new_int32(sig));
#if defined(__ELF__) && !defined(__FreeBSD__) #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()); sentry_set_tag("build_id", build_id_hex.c_str());
#endif #endif

View File

@ -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_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_DROP_CACHE, "DROP CACHE", GROUP, SYSTEM) \
M(SYSTEM_RELOAD_CONFIG, "RELOAD CONFIG", GLOBAL, SYSTEM_RELOAD) \ 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_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_EMBEDDED_DICTIONARIES, "RELOAD EMBEDDED DICTIONARIES", GLOBAL, SYSTEM_RELOAD) /* implicitly enabled by the grant SYSTEM_RELOAD_DICTIONARY ON *.* */\
M(SYSTEM_RELOAD, "", GROUP, SYSTEM) \ M(SYSTEM_RELOAD, "", GROUP, SYSTEM) \

View File

@ -195,7 +195,8 @@ void StackTrace::symbolize(const StackTrace::FramePointers & frame_pointers, siz
{ {
#if defined(__ELF__) && !defined(__FreeBSD__) && !defined(ARCADIA_BUILD) #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<std::string, DB::Dwarf> dwarfs; std::unordered_map<std::string, DB::Dwarf> dwarfs;
for (size_t i = 0; i < offset; ++i) for (size_t i = 0; i < offset; ++i)
@ -316,7 +317,8 @@ static void toStringEveryLineImpl(
return callback("<Empty trace>"); return callback("<Empty trace>");
#if defined(__ELF__) && !defined(__FreeBSD__) #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<std::string, DB::Dwarf> dwarfs; std::unordered_map<std::string, DB::Dwarf> dwarfs;
std::stringstream out; // STYLE_CHECK_ALLOW_STD_STRING_STREAM std::stringstream out; // STYLE_CHECK_ALLOW_STD_STRING_STREAM

View File

@ -300,12 +300,12 @@ void collectSymbolsFromELF(dl_phdr_info * info,
String our_build_id = getBuildIDFromProgramHeaders(info); String our_build_id = getBuildIDFromProgramHeaders(info);
/// If the name is empty - it's 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. /// Find a elf file for the main executable and set the build-id.
if (object_name.empty()) if (object_name.empty())
{ {
object_name = "/proc/self/exe"; object_name = "/proc/self/exe";
if (build_id.empty())
build_id = our_build_id; build_id = our_build_id;
} }
@ -316,9 +316,16 @@ void collectSymbolsFromELF(dl_phdr_info * info,
return; return;
/// Debug info and symbol table sections may be split to separate binary. /// 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(); 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. /// 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; return build_id_hex;
} }
SymbolIndex & SymbolIndex::instance() MultiVersion<SymbolIndex>::Version SymbolIndex::instance(bool reload)
{ {
static SymbolIndex instance; static MultiVersion<SymbolIndex> instance(std::unique_ptr<SymbolIndex>(new SymbolIndex));
return instance; if (reload)
instance.set(std::unique_ptr<SymbolIndex>(new SymbolIndex));
return instance.get();
} }
} }

View File

@ -7,6 +7,7 @@
#include <Common/Elf.h> #include <Common/Elf.h>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <Common/MultiVersion.h>
namespace DB namespace DB
{ {
@ -21,7 +22,7 @@ protected:
SymbolIndex() { update(); } SymbolIndex() { update(); }
public: public:
static SymbolIndex & instance(); static MultiVersion<SymbolIndex>::Version instance(bool reload = false);
struct Symbol struct Symbol
{ {

View File

@ -25,7 +25,8 @@ int main(int argc, char ** argv)
return 1; 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()) for (const auto & elem : symbol_index.symbols())
std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n"; std::cout << elem.name << ": " << elem.address_begin << " ... " << elem.address_end << "\n";

View File

@ -106,7 +106,8 @@ private:
StringRef impl(uintptr_t addr) const 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<const void *>(addr))) if (const auto * object = symbol_index.findObject(reinterpret_cast<const void *>(addr)))
{ {

View File

@ -66,7 +66,8 @@ public:
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override 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 ColumnPtr & column = arguments[0].column;
const ColumnUInt64 * column_concrete = checkAndGetColumn<ColumnUInt64>(column.get()); const ColumnUInt64 * column_concrete = checkAndGetColumn<ColumnUInt64>(column.get());

View File

@ -40,7 +40,7 @@ public:
ColumnPtr executeImpl(const ColumnsWithTypeAndName &, const DataTypePtr &, size_t input_rows_count) const override 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());
} }
}; };

View File

@ -53,7 +53,7 @@ void CrashLogElement::appendToBlock(MutableColumns & columns) const
String build_id_hex; String build_id_hex;
#if defined(__ELF__) && !defined(__FreeBSD__) #if defined(__ELF__) && !defined(__FreeBSD__)
build_id_hex = SymbolIndex::instance().getBuildIDHex(); build_id_hex = SymbolIndex::instance()->getBuildIDHex();
#endif #endif
columns[i++]->insert(build_id_hex); columns[i++]->insert(build_id_hex);
} }

View File

@ -3,6 +3,7 @@
#include <Common/ActionLock.h> #include <Common/ActionLock.h>
#include <Common/typeid_cast.h> #include <Common/typeid_cast.h>
#include <Common/getNumberOfPhysicalCPUCores.h> #include <Common/getNumberOfPhysicalCPUCores.h>
#include <Common/SymbolIndex.h>
#include <Common/ThreadPool.h> #include <Common/ThreadPool.h>
#include <Common/escapeForFileName.h> #include <Common/escapeForFileName.h>
#include <Interpreters/Context.h> #include <Interpreters/Context.h>
@ -271,6 +272,10 @@ BlockIO InterpreterSystemQuery::execute()
context.checkAccess(AccessType::SYSTEM_RELOAD_CONFIG); context.checkAccess(AccessType::SYSTEM_RELOAD_CONFIG);
system_context.reloadConfig(); system_context.reloadConfig();
break; break;
case Type::RELOAD_SYMBOLS:
context.checkAccess(AccessType::SYSTEM_RELOAD_SYMBOLS);
(void)SymbolIndex::instance(true);
break;
case Type::STOP_MERGES: case Type::STOP_MERGES:
startStopAction(ActionLocks::PartsMerge, false); startStopAction(ActionLocks::PartsMerge, false);
break; break;
@ -604,6 +609,11 @@ AccessRightsElements InterpreterSystemQuery::getRequiredAccessForDDLOnCluster()
required_access.emplace_back(AccessType::SYSTEM_RELOAD_CONFIG); required_access.emplace_back(AccessType::SYSTEM_RELOAD_CONFIG);
break; break;
} }
case Type::RELOAD_SYMBOLS:
{
required_access.emplace_back(AccessType::SYSTEM_RELOAD_SYMBOLS);
break;
}
case Type::STOP_MERGES: [[fallthrough]]; case Type::STOP_MERGES: [[fallthrough]];
case Type::START_MERGES: case Type::START_MERGES:
{ {

View File

@ -54,6 +54,8 @@ const char * ASTSystemQuery::typeToString(Type type)
return "RELOAD EMBEDDED DICTIONARIES"; return "RELOAD EMBEDDED DICTIONARIES";
case Type::RELOAD_CONFIG: case Type::RELOAD_CONFIG:
return "RELOAD CONFIG"; return "RELOAD CONFIG";
case Type::RELOAD_SYMBOLS:
return "RELOAD SYMBOLS";
case Type::STOP_MERGES: case Type::STOP_MERGES:
return "STOP MERGES"; return "STOP MERGES";
case Type::START_MERGES: case Type::START_MERGES:

View File

@ -36,6 +36,7 @@ public:
RELOAD_DICTIONARIES, RELOAD_DICTIONARIES,
RELOAD_EMBEDDED_DICTIONARIES, RELOAD_EMBEDDED_DICTIONARIES,
RELOAD_CONFIG, RELOAD_CONFIG,
RELOAD_SYMBOLS,
STOP_MERGES, STOP_MERGES,
START_MERGES, START_MERGES,
STOP_TTL_MERGES, STOP_TTL_MERGES,