18#if DMLC_LOG_STACK_TRACE
21#include DMLC_EXECINFO_H
29struct Error :
public std::runtime_error {
34 explicit Error(
const std::string &s) :
std::runtime_error(s) {}
37#if DMLC_LOG_STACK_TRACE
39inline size_t LogStackTraceLevel() {
41 if (
auto var = std::getenv(
"DMLC_LOG_STACK_TRACE_DEPTH")) {
42 if (1 == sscanf(var,
"%zu", &level)) {
46 return DMLC_LOG_STACK_TRACE_SIZE;
49inline std::string Demangle(
char const *msg_str) {
52 size_t symbol_start = string::npos;
53 size_t symbol_end = string::npos;
54 if ( ((symbol_start = msg.find(
"_Z")) != string::npos)
55 && (symbol_end = msg.find_first_of(
" +", symbol_start)) ) {
56 string left_of_symbol(msg, 0, symbol_start);
57 string symbol(msg, symbol_start, symbol_end - symbol_start);
58 string right_of_symbol(msg, symbol_end);
61 size_t length = string::npos;
62 std::unique_ptr<char, void (*)(
void *__ptr)> demangled_symbol =
63 {abi::__cxa_demangle(symbol.c_str(), 0, &length, &status), &std::free};
64 if (demangled_symbol && status == 0 && length > 0) {
65 string symbol_str(demangled_symbol.get());
66 std::ostringstream os;
67 os << left_of_symbol << symbol_str << right_of_symbol;
76inline std::string StackTrace(
77 size_t start_frame = 1,
78 const size_t stack_size = DMLC_LOG_STACK_TRACE_SIZE) {
80 std::ostringstream stacktrace_os;
81 std::vector<void*> stack(stack_size);
82 int nframes = backtrace(stack.data(),
static_cast<int>(stack_size));
83 if (start_frame <
static_cast<size_t>(nframes)) {
84 stacktrace_os <<
"Stack trace:\n";
86 char **msgs = backtrace_symbols(stack.data(), nframes);
87 if (msgs !=
nullptr) {
88 for (
int frameno = start_frame; frameno < nframes; ++frameno) {
89 string msg = dmlc::Demangle(msgs[frameno]);
90 stacktrace_os <<
" [bt] (" << frameno - start_frame <<
") " << msg <<
"\n";
94 string stack_trace = stacktrace_os.str();
100inline size_t LogStackTraceLevel() {
104inline std::string demangle(
char const* msg_str) {
105 return std::string();
108inline std::string StackTrace(
size_t start_frame = 1,
109 const size_t stack_size = 0) {
110 return std::string(
"Stack trace not available when "
111 "DMLC_LOG_STACK_TRACE is disabled at compile time.");
118#include <glog/logging.h>
125inline void InitLogging(
const char* argv0) {
126 google::InitGoogleLogging(argv0);
130#elif defined DMLC_USE_LOGGING_LIBRARY
132#include DMLC_USE_LOGGING_LIBRARY
134inline void InitLogging(
const char*) {
147#pragma warning(disable : 4722)
148#pragma warning(disable : 4068)
152inline void InitLogging(
const char*) {
157inline bool DebugLoggingEnabled() {
158 static int state = 0;
160 if (
auto var = std::getenv(
"DMLC_LOG_DEBUG")) {
161 if (std::string(var) ==
"1") {
174#ifndef DMLC_GLOG_DEFINED
176template <
typename X,
typename Y>
177std::unique_ptr<std::string> LogCheckFormat(
const X& x,
const Y& y) {
178 std::ostringstream os;
179 os <<
" (" << x <<
" vs. " << y <<
") ";
181 return std::unique_ptr<std::string>(
new std::string(os.str()));
185#define DEFINE_CHECK_FUNC(name, op) \
186 template <typename X, typename Y> \
187 DMLC_ALWAYS_INLINE std::unique_ptr<std::string> LogCheck##name(const X& x, const Y& y) { \
188 if (x op y) return nullptr; \
189 return LogCheckFormat(x, y); \
191 DMLC_ALWAYS_INLINE std::unique_ptr<std::string> LogCheck##name(int x, int y) { \
192 return LogCheck##name<int, int>(x, y); \
195#pragma GCC diagnostic push
196#pragma GCC diagnostic ignored "-Wsign-compare"
197DEFINE_CHECK_FUNC(_LT, <)
198DEFINE_CHECK_FUNC(_GT, >)
199DEFINE_CHECK_FUNC(_LE, <=)
200DEFINE_CHECK_FUNC(_GE, >=)
201DEFINE_CHECK_FUNC(_EQ, ==)
202DEFINE_CHECK_FUNC(_NE, !=)
203#pragma GCC diagnostic pop
205#define CHECK_BINARY_OP(name, op, x, y) \
206 if (auto __dmlc__log__err = dmlc::LogCheck##name(x, y)) \
207 dmlc::LogMessageFatal(__FILE__, __LINE__).stream() \
208 << "Check failed: " << #x " " #op " " #y << *__dmlc__log__err << ": "
213 dmlc::LogMessageFatal(__FILE__, __LINE__).stream() \
214 << "Check failed: " #x << ": "
215#define CHECK_LT(x, y) CHECK_BINARY_OP(_LT, <, x, y)
216#define CHECK_GT(x, y) CHECK_BINARY_OP(_GT, >, x, y)
217#define CHECK_LE(x, y) CHECK_BINARY_OP(_LE, <=, x, y)
218#define CHECK_GE(x, y) CHECK_BINARY_OP(_GE, >=, x, y)
219#define CHECK_EQ(x, y) CHECK_BINARY_OP(_EQ, ==, x, y)
220#define CHECK_NE(x, y) CHECK_BINARY_OP(_NE, !=, x, y)
221#define CHECK_NOTNULL(x) \
222 ((x) == NULL ? dmlc::LogMessageFatal(__FILE__, __LINE__).stream() << "Check notnull: " #x << ' ', (x) : (x))
227 while (false) CHECK(x)
228#define DCHECK_LT(x, y) \
229 while (false) CHECK((x) < (y))
230#define DCHECK_GT(x, y) \
231 while (false) CHECK((x) > (y))
232#define DCHECK_LE(x, y) \
233 while (false) CHECK((x) <= (y))
234#define DCHECK_GE(x, y) \
235 while (false) CHECK((x) >= (y))
236#define DCHECK_EQ(x, y) \
237 while (false) CHECK((x) == (y))
238#define DCHECK_NE(x, y) \
239 while (false) CHECK((x) != (y))
241#define DCHECK(x) CHECK(x)
242#define DCHECK_LT(x, y) CHECK((x) < (y))
243#define DCHECK_GT(x, y) CHECK((x) > (y))
244#define DCHECK_LE(x, y) CHECK((x) <= (y))
245#define DCHECK_GE(x, y) CHECK((x) >= (y))
246#define DCHECK_EQ(x, y) CHECK((x) == (y))
247#define DCHECK_NE(x, y) CHECK((x) != (y))
250#if DMLC_LOG_CUSTOMIZE
251#define LOG_INFO dmlc::CustomLogMessage(__FILE__, __LINE__)
253#define LOG_INFO dmlc::LogMessage(__FILE__, __LINE__)
255#define LOG_ERROR LOG_INFO
256#define LOG_WARNING LOG_INFO
257#define LOG_FATAL dmlc::LogMessageFatal(__FILE__, __LINE__)
258#define LOG_QFATAL LOG_FATAL
261#define VLOG(x) LOG_INFO.stream()
263#define LOG(severity) LOG_##severity.stream()
264#define LG LOG_INFO.stream()
265#define LOG_IF(severity, condition) \
266 !(condition) ? (void)0 : dmlc::LogMessageVoidify() & LOG(severity)
270#define LOG_DFATAL LOG_FATAL
272#define DLOG(severity) LOG_IF(severity, ::dmlc::DebugLoggingEnabled())
273#define DLOG_IF(severity, condition) LOG_IF(severity, ::dmlc::DebugLoggingEnabled() && (condition))
277#define LOG_DFATAL LOG_ERROR
279#define DLOG(severity) true ? (void)0 : dmlc::LogMessageVoidify() & LOG(severity)
280#define DLOG_IF(severity, condition) \
281 (true || !(condition)) ? (void)0 : dmlc::LogMessageVoidify() & LOG(severity)
285#define LOG_EVERY_N(severity, n) LOG(severity)
296 const char* HumanDate() {
297#if !defined(_LIBCPP_SGX_CONFIG) && DMLC_LOG_NODATE == 0
299 _strtime_s(buffer_,
sizeof(buffer_));
301 time_t time_value = time(NULL);
305 pnow = localtime_r(&time_value, &now);
307 pnow = localtime(&time_value);
309 snprintf(buffer_,
sizeof(buffer_),
"%02d:%02d:%02d",
310 pnow->tm_hour, pnow->tm_min, pnow->tm_sec);
322#ifndef _LIBCPP_SGX_NO_IOSTREAMS
328 log_stream_(std::cout)
330 log_stream_(std::cerr)
333 log_stream_ <<
"[" << pretty_date_.HumanDate() <<
"] " << file <<
":"
337 std::ostream& stream() {
return log_stream_; }
340 std::ostream& log_stream_;
352 log_stream_ <<
"[" <<
DateLogger().HumanDate() <<
"] " << file <<
":"
356 Log(log_stream_.str());
358 std::ostream& stream() {
return log_stream_; }
364 static void Log(
const std::string& msg);
367 std::ostringstream log_stream_;
372 template <
typename T>
373 DummyOStream& operator<<(T _) {
return *
this; }
374 inline std::string str() {
return ""; }
378 LogMessage(
const char* file,
int line) : log_stream_() {}
379 DummyOStream& stream() {
return log_stream_; }
382 DummyOStream log_stream_;
385 LogMessage(
const LogMessage&);
386 void operator=(
const LogMessage&);
391#if defined(_LIBCPP_SGX_NO_IOSTREAMS)
392class LogMessageFatal :
public LogMessage {
394 LogMessageFatal(
const char* file,
int line) : LogMessage(file, line) {}
399 LogMessageFatal(
const LogMessageFatal&);
400 void operator=(
const LogMessageFatal&);
402#elif DMLC_LOG_FATAL_THROW == 0
403class LogMessageFatal :
public LogMessage {
405 LogMessageFatal(
const char* file,
int line) : LogMessage(file, line) {}
407 log_stream_ <<
"\n" << StackTrace(1, LogStackTraceLevel()) <<
"\n";
412 LogMessageFatal(
const LogMessageFatal&);
413 void operator=(
const LogMessageFatal&);
419 GetEntry().Init(file, line);
421 std::ostringstream &stream() {
return GetEntry().log_stream; }
423#if DMLC_LOG_STACK_TRACE
424 GetEntry().log_stream <<
"\n"
425 << StackTrace(1, LogStackTraceLevel())
428 throw GetEntry().Finalize();
433 std::ostringstream log_stream;
434 DMLC_NO_INLINE
void Init(
const char *file,
int line) {
438 log_stream <<
"[" << date.HumanDate() <<
"] " << file <<
":" << line
442#if DMLC_LOG_BEFORE_THROW
443 LOG(ERROR) << log_stream.str();
450#if !(defined(__MINGW32__) || defined(__MINGW64__))
451 DMLC_NO_INLINE
static Entry& ThreadLocal() {
452 static thread_local Entry result;
460#if defined(__MINGW32__) || defined(__MINGW64__)
461 DMLC_NO_INLINE Entry& GetEntry() {
467 DMLC_NO_INLINE Entry& GetEntry() {
468 return Entry::ThreadLocal();
482#if !defined(_LIBCPP_SGX_NO_IOSTREAMS)
483 void operator&(std::ostream&) {}
static void Log(const std::string &msg)
customized logging of the message. This function won't be implemented by libdmlc
Definition xgboost_custom.cc:11
namespace for dmlc
Definition array_view.h:12
Macros common to all headers.
exception class that will be thrown by default logger if DMLC_LOG_FATAL_THROW == 1
Definition logging.h:29
Error(const std::string &s)
constructor
Definition logging.h:34