mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Print build id in crash messages
This commit is contained in:
parent
32c7ff7d2c
commit
ead4a2cfd9
@ -50,6 +50,7 @@
|
||||
#include <Common/getMultipleKeysFromConfig.h>
|
||||
#include <Common/ClickHouseRevision.h>
|
||||
#include <Common/Config/ConfigProcessor.h>
|
||||
#include <Common/SymbolIndex.h>
|
||||
|
||||
#if !defined(ARCADIA_BUILD)
|
||||
# include <Common/config_version.h>
|
||||
@ -236,7 +237,8 @@ private:
|
||||
|
||||
void onTerminate(const std::string & message, UInt32 thread_num) const
|
||||
{
|
||||
LOG_FATAL(log, "(version {}{}) (from thread {}) {}", VERSION_STRING, VERSION_OFFICIAL, thread_num, message);
|
||||
LOG_FATAL(log, "(version {}{}, {}) (from thread {}) {}",
|
||||
VERSION_STRING, VERSION_OFFICIAL, daemon.build_id_info, thread_num, message);
|
||||
}
|
||||
|
||||
void onFault(
|
||||
@ -249,17 +251,15 @@ private:
|
||||
{
|
||||
LOG_FATAL(log, "########################################");
|
||||
|
||||
if (query_id.empty())
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "(version " << VERSION_STRING << VERSION_OFFICIAL << ")";
|
||||
message << " (from thread " << thread_num << ")";
|
||||
if (query_id.empty())
|
||||
message << " (no query)";
|
||||
else
|
||||
message << " (query_id: " << query_id << ")";
|
||||
message << " Received signal " << strsignal(sig) << " (" << sig << ").";
|
||||
|
||||
LOG_FATAL(log, message.str());
|
||||
LOG_FATAL(log, "(version {}{}, {}) (from thread {}) (no query) Received signal {} ({})",
|
||||
VERSION_STRING, VERSION_OFFICIAL, daemon.build_id_info, thread_num, strsignal(sig), sig);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_FATAL(log, "(version {}{}, {}) (from thread {}) (query_id: {}) Received signal {} ({})",
|
||||
VERSION_STRING, VERSION_OFFICIAL, daemon.build_id_info, thread_num, query_id, strsignal(sig), sig);
|
||||
}
|
||||
|
||||
LOG_FATAL(log, signalToErrorMessage(sig, info, context));
|
||||
@ -292,17 +292,15 @@ static void sanitizerDeathCallback()
|
||||
|
||||
StringRef query_id = DB::CurrentThread::getQueryId(); /// This is signal safe.
|
||||
|
||||
if (query_id.empty())
|
||||
{
|
||||
std::stringstream message;
|
||||
message << "(version " << VERSION_STRING << VERSION_OFFICIAL << ")";
|
||||
message << " (from thread " << getThreadId() << ")";
|
||||
if (query_id.size == 0)
|
||||
message << " (no query)";
|
||||
else
|
||||
message << " (query_id: " << query_id << ")";
|
||||
message << " Sanitizer trap.";
|
||||
|
||||
LOG_FATAL(log, message.str());
|
||||
LOG_FATAL(log, "(version {}{}, {}) (from thread {}) (no query) Sanitizer trap.",
|
||||
VERSION_STRING, VERSION_OFFICIAL, daemon.build_id_info, thread_num);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_FATAL(log, "(version {}{}, {}) (from thread {}) (query_id: {}) Sanitizer trap.",
|
||||
VERSION_STRING, VERSION_OFFICIAL, daemon.build_id_info, thread_num, query_id);
|
||||
}
|
||||
|
||||
/// Just in case print our own stack trace. In case when llvm-symbolizer does not work.
|
||||
@ -711,6 +709,12 @@ void BaseDaemon::initializeTerminationAndSignalProcessing()
|
||||
|
||||
signal_listener = std::make_unique<SignalListener>(*this);
|
||||
signal_listener_thread.start(*signal_listener);
|
||||
|
||||
String build_id_hex = DB::SymbolIndex::instance().getBuildIDHex();
|
||||
if (build_id_hex.empty())
|
||||
build_id_info = "no build id";
|
||||
else
|
||||
build_id_info = "build id: " + build_id_hex;
|
||||
}
|
||||
|
||||
void BaseDaemon::logRevision() const
|
||||
|
@ -198,6 +198,8 @@ protected:
|
||||
std::string config_path;
|
||||
DB::ConfigProcessor::LoadedConfig loaded_config;
|
||||
Poco::Util::AbstractConfiguration * last_configuration = nullptr;
|
||||
|
||||
String build_id_info;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#if defined(__ELF__) && !defined(__FreeBSD__)
|
||||
|
||||
#include <Common/SymbolIndex.h>
|
||||
#include <Common/hex.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
@ -276,15 +277,21 @@ bool searchAndCollectSymbolsFromELFSymbolTable(
|
||||
|
||||
void collectSymbolsFromELF(dl_phdr_info * info,
|
||||
std::vector<SymbolIndex::Symbol> & symbols,
|
||||
std::vector<SymbolIndex::Object> & objects)
|
||||
std::vector<SymbolIndex::Object> & objects,
|
||||
String & build_id)
|
||||
{
|
||||
std::string object_name = info->dlpi_name;
|
||||
|
||||
String our_build_id = getBuildIDFromProgramHeaders(info);
|
||||
|
||||
/// If the name is empty - it's main executable.
|
||||
/// Find a elf file for the main executable.
|
||||
|
||||
if (object_name.empty())
|
||||
{
|
||||
object_name = "/proc/self/exe";
|
||||
build_id = our_build_id;
|
||||
}
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::path canonical_path = std::filesystem::canonical(object_name, ec);
|
||||
@ -298,7 +305,6 @@ void collectSymbolsFromELF(dl_phdr_info * info,
|
||||
object_name = std::filesystem::exists(debug_info_path) ? debug_info_path : canonical_path;
|
||||
|
||||
/// But we have to compare Build ID to check that debug info corresponds to the same executable.
|
||||
String our_build_id = getBuildIDFromProgramHeaders(info);
|
||||
|
||||
SymbolIndex::Object object;
|
||||
object.elf = std::make_unique<Elf>(object_name);
|
||||
@ -343,7 +349,7 @@ int collectSymbols(dl_phdr_info * info, size_t, void * data_ptr)
|
||||
SymbolIndex::Data & data = *reinterpret_cast<SymbolIndex::Data *>(data_ptr);
|
||||
|
||||
collectSymbolsFromProgramHeaders(info, data.symbols);
|
||||
collectSymbolsFromELF(info, data.symbols, data.objects);
|
||||
collectSymbolsFromELF(info, data.symbols, data.objects, data.build_id);
|
||||
|
||||
/* Continue iterations */
|
||||
return 0;
|
||||
@ -396,6 +402,22 @@ const SymbolIndex::Object * SymbolIndex::findObject(const void * address) const
|
||||
return find(address, data.objects);
|
||||
}
|
||||
|
||||
String SymbolIndex::getBuildIDHex() const
|
||||
{
|
||||
String build_id_binary = getBuildID();
|
||||
String build_id_hex;
|
||||
build_id_hex.resize(build_id_binary.size() * 2);
|
||||
|
||||
char * pos = build_id_hex.data();
|
||||
for (auto c : build_id_binary)
|
||||
{
|
||||
writeHexByteUppercase(c, pos);
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
return build_id_hex;
|
||||
}
|
||||
|
||||
SymbolIndex & SymbolIndex::instance()
|
||||
{
|
||||
static SymbolIndex instance;
|
||||
|
@ -45,10 +45,15 @@ public:
|
||||
const std::vector<Symbol> & symbols() const { return data.symbols; }
|
||||
const std::vector<Object> & objects() const { return data.objects; }
|
||||
|
||||
/// The BuildID that is generated by compiler.
|
||||
String getBuildID() const { return data.build_id; }
|
||||
String getBuildIDHex() const;
|
||||
|
||||
struct Data
|
||||
{
|
||||
std::vector<Symbol> symbols;
|
||||
std::vector<Object> objects;
|
||||
String build_id;
|
||||
};
|
||||
private:
|
||||
Data data;
|
||||
|
Loading…
Reference in New Issue
Block a user