OR-Tools  8.2
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"
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__)
38enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 };
39#endif
40
41namespace 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.
51static 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.
63inline 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
72static const int kLogBufSize = 3000;
73static bool crashed = false;
75static char crash_buf[kLogBufSize + 1] = {0}; // Will end in '\0'
76
77void 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) {
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
static void ATTRIBUTE_NORETURN Fail()
int LogSeverity
Definition: log_severity.h:22
Definition: file.cc:141
T sync_val_compare_and_swap(T *ptr, T oldval, T newval)
void SetCrashReason(const CrashReason *r)
const char * const_basename(const char *filepath)
static bool DoRawLog(char **buf, int *size, const char *format,...)
Definition: raw_logging.cc:51
static bool crashed
Definition: raw_logging.cc:73
void RawLog__(LogSeverity severity, const char *file, int line, const char *format,...)
Definition: raw_logging.cc:77
GOOGLE_GLOG_DLL_DECL const char *const LogSeverityNames[NUM_SEVERITIES]
static bool VADoRawLog(char **buf, int *size, const char *format, va_list ap)
Definition: raw_logging.cc:63
static const int kLogBufSize
Definition: raw_logging.cc:72
const int GLOG_FATAL
Definition: log_severity.h:25
static char crash_buf[kLogBufSize+1]
Definition: raw_logging.cc:75
static logging_internal::CrashReason crash_reason
#define safe_write(fd, s, len)
Definition: raw_logging.cc:30