mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Log sanitizer trap messages from separate thread
This commit is contained in:
parent
dbcd0fdd3e
commit
d07af62370
@ -163,7 +163,8 @@ public:
|
||||
enum Signals : int
|
||||
{
|
||||
StdTerminate = -1,
|
||||
StopThread = -2
|
||||
StopThread = -2,
|
||||
SanitizerTrap = -3,
|
||||
};
|
||||
|
||||
explicit SignalListener(BaseDaemon & daemon_)
|
||||
@ -223,8 +224,12 @@ public:
|
||||
std::string query_id;
|
||||
DB::ThreadStatus * thread_ptr{};
|
||||
|
||||
DB::readPODBinary(info, in);
|
||||
DB::readPODBinary(context, in);
|
||||
if (sig != SanitizerTrap)
|
||||
{
|
||||
DB::readPODBinary(info, in);
|
||||
DB::readPODBinary(context, in);
|
||||
}
|
||||
|
||||
DB::readPODBinary(stack_trace, in);
|
||||
DB::readBinary(thread_num, in);
|
||||
DB::readBinary(query_id, in);
|
||||
@ -279,7 +284,14 @@ private:
|
||||
VERSION_STRING, VERSION_OFFICIAL, daemon.build_id_info, thread_num, query_id, strsignal(sig), sig);
|
||||
}
|
||||
|
||||
LOG_FATAL(log, signalToErrorMessage(sig, info, context));
|
||||
String error_message;
|
||||
|
||||
if (sig != SanitizerTrap)
|
||||
error_message = signalToErrorMessage(sig, info, context);
|
||||
else
|
||||
error_message = "Sanitizer trap.";
|
||||
|
||||
LOG_FATAL(log, error_message);
|
||||
|
||||
if (stack_trace.getSize())
|
||||
{
|
||||
@ -305,12 +317,12 @@ private:
|
||||
String build_id_hex{};
|
||||
#endif
|
||||
|
||||
SentryWriter::onFault(sig, info, context, stack_trace, build_id_hex);
|
||||
if (sig != SanitizerTrap)
|
||||
SentryWriter::onFault(sig, error_message, stack_trace, build_id_hex);
|
||||
|
||||
/// When everything is done, we will try to send these error messages to client.
|
||||
if (thread_ptr)
|
||||
thread_ptr->onFatalError();
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@ -320,35 +332,27 @@ extern "C" void __sanitizer_set_death_callback(void (*)());
|
||||
|
||||
static void sanitizerDeathCallback()
|
||||
{
|
||||
Poco::Logger * log = &Poco::Logger::get("BaseDaemon");
|
||||
/// Also need to send data via pipe. Otherwise it may lead to deadlocks or failures in printing diagnostic info.
|
||||
|
||||
StringRef query_id = DB::CurrentThread::getQueryId(); /// This is signal safe.
|
||||
char buf[signal_pipe_buf_size];
|
||||
DB::WriteBufferFromFileDescriptorDiscardOnFailure out(signal_pipe.fds_rw[1], signal_pipe_buf_size, buf);
|
||||
|
||||
if (query_id.size == 0)
|
||||
{
|
||||
LOG_FATAL(log, "(version {}{}) (from thread {}) (no query) Sanitizer trap.",
|
||||
VERSION_STRING, VERSION_OFFICIAL, getThreadId());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_FATAL(log, "(version {}{}) (from thread {}) (query_id: {}) Sanitizer trap.",
|
||||
VERSION_STRING, VERSION_OFFICIAL, getThreadId(), query_id);
|
||||
}
|
||||
const StackTrace stack_trace;
|
||||
|
||||
/// Just in case print our own stack trace. In case when llvm-symbolizer does not work.
|
||||
StackTrace stack_trace;
|
||||
if (stack_trace.getSize())
|
||||
{
|
||||
std::stringstream bare_stacktrace;
|
||||
bare_stacktrace << "Stack trace:";
|
||||
for (size_t i = stack_trace.getOffset(); i < stack_trace.getSize(); ++i)
|
||||
bare_stacktrace << ' ' << stack_trace.getFramePointers()[i];
|
||||
StringRef query_id = DB::CurrentThread::getQueryId();
|
||||
query_id.size = std::min(query_id.size, max_query_id_size);
|
||||
|
||||
LOG_FATAL(log, bare_stacktrace.str());
|
||||
}
|
||||
int sig = SignalListener::SanitizerTrap;
|
||||
DB::writeBinary(sig, out);
|
||||
DB::writePODBinary(stack_trace, out);
|
||||
DB::writeBinary(UInt32(getThreadId()), out);
|
||||
DB::writeStringBinary(query_id, out);
|
||||
DB::writePODBinary(DB::current_thread, out);
|
||||
|
||||
/// Write symbolized stack trace line by line for better grep-ability.
|
||||
stack_trace.toStringEveryLine([&](const std::string & s) { LOG_FATAL(log, s); });
|
||||
out.next();
|
||||
|
||||
/// The time that is usually enough for separate thread to print info into log.
|
||||
sleepForSeconds(10);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2,23 +2,26 @@
|
||||
|
||||
#include <Poco/File.h>
|
||||
#include <Poco/Util/Application.h>
|
||||
#include <Poco/Util/LayeredConfiguration.h>
|
||||
|
||||
#include <common/defines.h>
|
||||
#include <common/getFQDNOrHostName.h>
|
||||
#include <common/logger_useful.h>
|
||||
|
||||
#include <Common/StackTrace.h>
|
||||
|
||||
#if !defined(ARCADIA_BUILD)
|
||||
# include "Common/config_version.h"
|
||||
# include <Common/config.h>
|
||||
#endif
|
||||
|
||||
#if USE_SENTRY
|
||||
|
||||
# include <sentry.h> // Y_IGNORE
|
||||
# include <stdio.h>
|
||||
# include <filesystem>
|
||||
#endif
|
||||
|
||||
|
||||
#if USE_SENTRY
|
||||
namespace
|
||||
{
|
||||
|
||||
@ -76,12 +79,12 @@ void sentry_logger(sentry_level_t level, const char * message, va_list args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void SentryWriter::initialize(Poco::Util::LayeredConfiguration & config)
|
||||
{
|
||||
#if USE_SENTRY
|
||||
bool enabled = false;
|
||||
bool debug = config.getBool("send_crash_reports.debug", false);
|
||||
auto * logger = &Poco::Logger::get("SentryWriter");
|
||||
@ -146,28 +149,19 @@ void SentryWriter::initialize(Poco::Util::LayeredConfiguration & config)
|
||||
{
|
||||
LOG_INFO(logger, "Sending crash reports is disabled");
|
||||
}
|
||||
#else
|
||||
UNUSED(config);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SentryWriter::shutdown()
|
||||
{
|
||||
#if USE_SENTRY
|
||||
if (initialized)
|
||||
{
|
||||
sentry_shutdown();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SentryWriter::onFault(int sig, const siginfo_t & info, const ucontext_t & context, const StackTrace & stack_trace, const String & build_id_hex)
|
||||
void SentryWriter::onFault(int sig, const std::string & error_message, const StackTrace & stack_trace, const std::string & build_id_hex)
|
||||
{
|
||||
#if USE_SENTRY
|
||||
auto * logger = &Poco::Logger::get("SentryWriter");
|
||||
if (initialized)
|
||||
{
|
||||
const std::string & error_message = signalToErrorMessage(sig, info, context);
|
||||
sentry_value_t event = sentry_value_new_message_event(SENTRY_LEVEL_FATAL, "fault", error_message.c_str());
|
||||
sentry_set_tag("signal", strsignal(sig));
|
||||
sentry_set_extra("signal_number", sentry_value_new_int32(sig));
|
||||
@ -240,11 +234,12 @@ void SentryWriter::onFault(int sig, const siginfo_t & info, const ucontext_t & c
|
||||
{
|
||||
LOG_INFO(logger, "Not sending crash report");
|
||||
}
|
||||
#else
|
||||
UNUSED(sig);
|
||||
UNUSED(info);
|
||||
UNUSED(context);
|
||||
UNUSED(stack_trace);
|
||||
UNUSED(build_id_hex);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void SentryWriter::initialize(Poco::Util::LayeredConfiguration &) {}
|
||||
void SentryWriter::shutdown() {}
|
||||
void SentryWriter::onFault(int, const std::string &, const StackTrace &, const std::string &) {}
|
||||
|
||||
#endif
|
||||
|
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <common/types.h>
|
||||
#include <Common/StackTrace.h>
|
||||
|
||||
#include <Poco/Util/LayeredConfiguration.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Poco { namespace Util { class LayeredConfiguration; }}
|
||||
class StackTrace;
|
||||
|
||||
|
||||
/// \brief Sends crash reports to ClickHouse core developer team via https://sentry.io
|
||||
///
|
||||
/// This feature can enabled with "send_crash_reports.enabled" server setting,
|
||||
@ -14,20 +14,16 @@
|
||||
///
|
||||
/// It is possible to send those reports to your own sentry account or account of consulting company you hired
|
||||
/// by overriding "send_crash_reports.endpoint" setting. "send_crash_reports.debug" setting will allow to do that for
|
||||
class SentryWriter
|
||||
namespace SentryWriter
|
||||
{
|
||||
public:
|
||||
SentryWriter() = delete;
|
||||
|
||||
static void initialize(Poco::Util::LayeredConfiguration & config);
|
||||
static void shutdown();
|
||||
void initialize(Poco::Util::LayeredConfiguration & config);
|
||||
void shutdown();
|
||||
|
||||
/// Not signal safe and can't be called from a signal handler
|
||||
static void onFault(
|
||||
void onFault(
|
||||
int sig,
|
||||
const siginfo_t & info,
|
||||
const ucontext_t & context,
|
||||
const std::string & error_message,
|
||||
const StackTrace & stack_trace,
|
||||
const String & build_id_hex
|
||||
const std::string & build_id_hex
|
||||
);
|
||||
};
|
||||
|
@ -20,5 +20,7 @@
|
||||
#define ARROW_VERSION_PATCH
|
||||
#define ARROW_VERSION ((ARROW_VERSION_MAJOR * 1000) + ARROW_VERSION_MINOR) * 1000 + ARROW_VERSION_PATCH
|
||||
|
||||
/* #undef DOUBLE_CONVERSION_HAS_CASE_INSENSIBILITY */
|
||||
#define ARROW_SO_VERSION ""
|
||||
#define ARROW_FULL_SO_VERSION ""
|
||||
|
||||
/* #undef GRPCPP_PP_INCLUDE */
|
||||
|
Loading…
Reference in New Issue
Block a user