OR-Tools  8.1
raw_logging.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
15 
16 #include <errno.h>
17 #include <fcntl.h> // for open()
18 #include <stdarg.h>
19 #include <stdio.h>
20 #include <time.h>
21 
22 #include "absl/base/macros.h"
23 #include "absl/debugging/stacktrace.h"
25 #include "ortools/base/logging.h"
27 
28 #if !defined(_MSC_VER)
29 #include <sys/syscall.h> // for syscall()
30 #define safe_write(fd, s, len) syscall(SYS_write, fd, s, len)
31 #else
32 #include <io.h> // _write()
33 // Not so safe, but what can you do?
34 #define safe_write(fd, s, len) _write(fd, s, len)
35 #endif
36 
37 #if defined(_MSC_VER) && !defined(__MINGW32__)
38 enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
39 #endif
40 
41 namespace google {
42 
43 // CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths
44 // that invoke malloc() and getenv() that might acquire some locks.
45 // If this becomes a problem we should reimplement a subset of vsnprintf
46 // that does not need locks and malloc.
47 
48 // Helper for RawLog__ below.
49 // *DoRawLog writes to *buf of *size and move them past the written portion.
50 // It returns true iff there was no overflow or error.
51 static bool DoRawLog(char** buf, int* size, const char* format, ...) {
52  va_list ap;
53  va_start(ap, format);
54  int n = vsnprintf(*buf, *size, format, ap);
55  va_end(ap);
56  if (n < 0 || n > *size) return false;
57  *size -= n;
58  *buf += n;
59  return true;
60 }
61 
62 // Helper for RawLog__ below.
63 inline static bool VADoRawLog(char** buf, int* size, const char* format,
64  va_list ap) {
65  int n = vsnprintf(*buf, *size, format, ap);
66  if (n < 0 || n > *size) return false;
67  *size -= n;
68  *buf += n;
69  return true;
70 }
71 
72 static const int kLogBufSize = 3000;
73 static bool crashed = false;
75 static char crash_buf[kLogBufSize + 1] = {0}; // Will end in '\0'
76 
77 void RawLog__(LogSeverity severity, const char* file, int line,
78  const char* format, ...) {
79  if (!(absl::GetFlag(FLAGS_logtostderr) ||
80  severity >= absl::GetFlag(FLAGS_stderrthreshold) ||
81  absl::GetFlag(FLAGS_alsologtostderr) ||
83  return; // this stderr log message is suppressed
84  }
85  // can't call localtime_r here: it can allocate
86  char buffer[kLogBufSize];
87  char* buf = buffer;
88  int size = sizeof(buffer);
89 
90  // NOTE: this format should match the specification in base/logging.h
91  DoRawLog(&buf, &size, "%c0000 00:00:00.000000 %5u %s:%d] RAW: ",
93  logging_internal::const_basename(const_cast<char*>(file)), line);
94 
95  // Record the position and size of the buffer after the prefix
96  const char* msg_start = buf;
97  const int msg_size = size;
98 
99  va_list ap;
100  va_start(ap, format);
101  bool no_chop = VADoRawLog(&buf, &size, format, ap);
102  va_end(ap);
103  if (no_chop) {
104  DoRawLog(&buf, &size, "\n");
105  } else {
106  DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n");
107  }
108  // We make a raw syscall to write directly to the stderr file descriptor,
109  // avoiding FILE buffering (to avoid invoking malloc()), and bypassing
110  // libc (to side-step any libc interception).
111  // We write just once to avoid races with other invocations of RawLog__.
112  safe_write(STDERR_FILENO, buffer, strlen(buffer));
113  if (severity == GLOG_FATAL) {
116  crash_reason.line_number = line;
117  memcpy(crash_buf, msg_start, msg_size); // Don't include prefix
119  crash_reason.depth = absl::GetStackTrace(
120  crash_reason.stack, ABSL_ARRAYSIZE(crash_reason.stack), 1);
122  }
123  LogMessage::Fail(); // abort()
124  }
125 }
126 
127 } // namespace google
google::kLogBufSize
static const int kLogBufSize
Definition: raw_logging.cc:72
google::logging_internal::CrashReason::filename
const char * filename
Definition: logging_utilities.h:67
google::LogMessage::Fail
static void ATTRIBUTE_NORETURN Fail()
Definition: base/logging.cc:1392
google::logging_internal::IsGoogleLoggingInitialized
bool IsGoogleLoggingInitialized()
Definition: logging_utilities.cc:223
google::logging_internal::CrashReason::message
const char * message
Definition: logging_utilities.h:69
logging.h
LogSeverity
int LogSeverity
Definition: log_severity.h:22
logging_utilities.h
google::logging_internal::sync_val_compare_and_swap
T sync_val_compare_and_swap(T *ptr, T oldval, T newval)
Definition: logging_utilities.h:50
google::crash_buf
static char crash_buf[kLogBufSize+1]
Definition: raw_logging.cc:75
google::LogSeverityNames
GOOGLE_GLOG_DLL_DECL const char *const LogSeverityNames[NUM_SEVERITIES]
Definition: base/logging.cc:358
google::GLOG_FATAL
const int GLOG_FATAL
Definition: log_severity.h:25
google::DoRawLog
static bool DoRawLog(char **buf, int *size, const char *format,...)
Definition: raw_logging.cc:51
google::VADoRawLog
static bool VADoRawLog(char **buf, int *size, const char *format, va_list ap)
Definition: raw_logging.cc:63
google::logging_internal::GetTID
unsigned int GetTID()
Definition: logging_utilities.cc:227
google::logging_internal::SetCrashReason
void SetCrashReason(const CrashReason *r)
Definition: logging_utilities.cc:299
google::logging_internal::CrashReason::line_number
int line_number
Definition: logging_utilities.h:68
google::crash_reason
static logging_internal::CrashReason crash_reason
Definition: base/logging.cc:1048
google::logging_internal::CrashReason::stack
void * stack[32]
Definition: logging_utilities.h:73
io.h
google::logging_internal::CrashReason::depth
int depth
Definition: logging_utilities.h:74
file
Definition: file.cc:141
google::crashed
static bool crashed
Definition: raw_logging.cc:73
google::logging_internal::const_basename
const char * const_basename(const char *filepath)
Definition: logging_utilities.cc:238
raw_logging.h
google::RawLog__
void RawLog__(LogSeverity severity, const char *file, int line, const char *format,...)
Definition: raw_logging.cc:77
commandlineflags.h
google
Definition: log_severity.h:24
safe_write
#define safe_write(fd, s, len)
Definition: raw_logging.cc:30
google::logging_internal::CrashReason
Definition: logging_utilities.h:64