fix debug build using gcc -fsanitize=undefined (#374)

This commit is contained in:
Roman Gershman 2018-12-12 11:16:49 +02:00 committed by Sergiu Deitsch
parent 125d6b3df4
commit 6adf6d7ae5
3 changed files with 29 additions and 3 deletions

View File

@ -206,6 +206,12 @@ thread_local int tls;
int main() { }
" HAVE_CXX11_TLS)
check_cxx_source_compiles ("
#include <type_traits>
std::aligned_storage<sizeof(char), alignof(char)>::type data;
int main() { }
" HAVE_ALIGNED_STORAGE)
if (WITH_TLS)
# Cygwin does not support the thread attribute. Don't bother.
if (HAVE_GCC_TLS)

View File

@ -189,6 +189,9 @@
/* Define to necessary thread-local storage attribute. */
#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE}
/* Check whether aligned_storage and alignof present */
#cmakedefine HAVE_ALIGNED_STORAGE ${HAVE_ALIGNED_STORAGE}
/* Version number of package */
#cmakedefine VERSION

View File

@ -1153,7 +1153,15 @@ static LogMessage::LogMessageData fatal_msg_data_shared;
// LogMessageData object exists (in this case glog makes zero heap memory
// allocations).
static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true;
static GLOG_THREAD_LOCAL_STORAGE char thread_msg_data[sizeof(LogMessage::LogMessageData)];
#ifdef HAVE_ALIGNED_STORAGE
static GLOG_THREAD_LOCAL_STORAGE
std::aligned_storage<sizeof(LogMessage::LogMessageData),
alignof(LogMessage::LogMessageData)>::type thread_msg_data;
#else
static GLOG_THREAD_LOCAL_STORAGE
char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)];
#endif // HAVE_ALIGNED_STORAGE
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
LogMessage::LogMessageData::LogMessageData()
@ -1213,10 +1221,19 @@ void LogMessage::Init(const char* file,
allocated_ = NULL;
if (severity != GLOG_FATAL || !exit_on_dfatal) {
#ifdef GLOG_THREAD_LOCAL_STORAGE
const uintptr_t kAlign = sizeof(void*) - 1;
// No need for locking, because this is thread local.
if (thread_data_available) {
thread_data_available = false;
#ifdef HAVE_ALIGNED_STORAGE
data_ = new (&thread_msg_data) LogMessageData;
#else
char* align_ptr =
reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(thread_msg_data + kAlign) & ~kAlign);
data_ = new (align_ptr) LogMessageData;
assert(reinterpret_cast<uintptr_t>(align_ptr) % sizeof(void*) == 0);
#endif
} else {
allocated_ = new LogMessageData();
data_ = allocated_;
@ -1294,7 +1311,7 @@ void LogMessage::Init(const char* file,
LogMessage::~LogMessage() {
Flush();
#ifdef GLOG_THREAD_LOCAL_STORAGE
if (data_ == static_cast<void*>(thread_msg_data)) {
if (data_ == static_cast<void*>(&thread_msg_data)) {
data_->~LogMessageData();
thread_data_available = true;
}