Merge pull request #10832 from ClickHouse/better-sanitizer

Better cooperation with sanitizers
This commit is contained in:
alexey-milovidov 2020-05-14 20:01:49 +03:00 committed by GitHub
commit 519e6ce6f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 0 deletions

View File

@ -283,6 +283,46 @@ private:
};
#if defined(SANITIZER)
extern "C" void __sanitizer_set_death_callback(void (*)());
static void sanitizerDeathCallback()
{
Logger * log = &Logger::get("BaseDaemon");
StringRef query_id = CurrentThread::getQueryId(); /// This is signal safe.
{
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.rdbuf());
}
/// 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.getFrames()[i];
LOG_FATAL(log, bare_stacktrace.rdbuf());
}
/// Write symbolized stack trace line by line for better grep-ability.
stack_trace.toStringEveryLine([&](const std::string & s) { LOG_FATAL(log, s); });
}
#endif
/** To use with std::set_terminate.
* Collects slightly more info than __gnu_cxx::__verbose_terminate_handler,
* and send it to pipe. Other thread will read this info from pipe and asynchronously write it to log.
@ -659,6 +699,10 @@ void BaseDaemon::initializeTerminationAndSignalProcessing()
add_signal_handler({SIGHUP, SIGUSR1}, closeLogsSignalHandler);
add_signal_handler({SIGINT, SIGQUIT, SIGTERM}, terminateRequestedSignalHandler);
#if defined(SANITIZER)
__sanitizer_set_death_callback(sanitizerDeathCallback);
#endif
/// Set up Poco ErrorHandler for Poco Threads.
static KillingErrorHandler killing_error_handler;
Poco::ErrorHandler::set(&killing_error_handler);

View File

@ -6,6 +6,11 @@
#include <Common/typeid_cast.h>
#include <Common/WeakHash.h>
#include <Common/HashTable/Hash.h>
#include <common/defines.h>
#if defined(MEMORY_SANITIZER)
#include <sanitizer/msan_interface.h>
#endif
namespace DB
@ -27,6 +32,15 @@ ColumnConst::ColumnConst(const ColumnPtr & data_, size_t s_)
if (data->size() != 1)
throw Exception("Incorrect size of nested column in constructor of ColumnConst: " + toString(data->size()) + ", must be 1.",
ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
/// Check that the value is initialized. We do it earlier, before it will be used, to ease debugging.
#if defined(MEMORY_SANITIZER)
if (data->isFixedAndContiguous())
{
StringRef value = data->getDataAt(0);
__msan_check_mem_is_initialized(value.data, value.size);
}
#endif
}
ColumnPtr ColumnConst::convertToFullColumn() const