Coverage Report

Created: 2023-09-25 06:27

/src/abseil-cpp/absl/log/internal/globals.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2022 The Abseil Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "absl/log/internal/globals.h"
16
17
#include <atomic>
18
#include <cstdio>
19
20
#if defined(__EMSCRIPTEN__)
21
#include <emscripten/console.h>
22
#endif
23
24
#include "absl/base/attributes.h"
25
#include "absl/base/config.h"
26
#include "absl/base/internal/raw_logging.h"
27
#include "absl/base/log_severity.h"
28
#include "absl/strings/string_view.h"
29
#include "absl/strings/strip.h"
30
#include "absl/time/time.h"
31
32
namespace absl {
33
ABSL_NAMESPACE_BEGIN
34
namespace log_internal {
35
36
namespace {
37
// Keeps track of whether Logging initialization is finalized.
38
// Log messages generated before that will go to stderr.
39
ABSL_CONST_INIT std::atomic<bool> logging_initialized(false);
40
41
// The TimeZone used for logging. This may only be set once.
42
ABSL_CONST_INIT std::atomic<absl::TimeZone*> timezone_ptr{nullptr};
43
44
// If true, the logging library will symbolize stack in fatal messages
45
ABSL_CONST_INIT std::atomic<bool> symbolize_stack_trace(true);
46
47
// Specifies maximum number of stack frames to report in fatal messages.
48
ABSL_CONST_INIT std::atomic<int> max_frames_in_stack_trace(64);
49
50
ABSL_CONST_INIT std::atomic<bool> exit_on_dfatal(true);
51
ABSL_CONST_INIT std::atomic<bool> suppress_sigabort_trace(false);
52
}  // namespace
53
54
3.24M
bool IsInitialized() {
55
3.24M
  return logging_initialized.load(std::memory_order_acquire);
56
3.24M
}
57
58
0
void SetInitialized() {
59
0
  logging_initialized.store(true, std::memory_order_release);
60
0
}
61
62
3.24M
void WriteToStderr(absl::string_view message, absl::LogSeverity severity) {
63
3.24M
  if (message.empty()) return;
64
#if defined(__EMSCRIPTEN__)
65
  // In WebAssembly, bypass filesystem emulation via fwrite.
66
  // Skip a trailing newline character as emscripten_errn adds one itself.
67
  const auto message_minus_newline = absl::StripSuffix(message, "\n");
68
  // emscripten_errn was introduced in 3.1.41 but broken in standalone mode
69
  // until 3.1.43.
70
#if ABSL_INTERNAL_EMSCRIPTEN_VERSION >= 3001043
71
  emscripten_errn(message_minus_newline.data(), message_minus_newline.size());
72
#else
73
  std::string null_terminated_message(message_minus_newline);
74
  _emscripten_err(null_terminated_message.c_str());
75
#endif
76
#else
77
  // Avoid using std::cerr from this module since we may get called during
78
  // exit code, and cerr may be partially or fully destroyed by then.
79
3.24M
  std::fwrite(message.data(), message.size(), 1, stderr);
80
3.24M
#endif
81
82
#if defined(_WIN64) || defined(_WIN32) || defined(_WIN16)
83
  // C99 requires stderr to not be fully-buffered by default (7.19.3.7), but
84
  // MS CRT buffers it anyway, so we must `fflush` to ensure the string hits
85
  // the console/file before the program dies (and takes the libc buffers
86
  // with it).
87
  // https://docs.microsoft.com/en-us/cpp/c-runtime-library/stream-i-o
88
  if (severity >= absl::LogSeverity::kWarning) {
89
    std::fflush(stderr);
90
  }
91
#else
92
  // Avoid unused parameter warning in this branch.
93
3.24M
  (void)severity;
94
3.24M
#endif
95
3.24M
}
96
97
0
void SetTimeZone(absl::TimeZone tz) {
98
0
  absl::TimeZone* expected = nullptr;
99
0
  absl::TimeZone* new_tz = new absl::TimeZone(tz);
100
  // timezone_ptr can only be set once, otherwise new_tz is leaked.
101
0
  if (!timezone_ptr.compare_exchange_strong(expected, new_tz,
102
0
                                            std::memory_order_release,
103
0
                                            std::memory_order_relaxed)) {
104
0
    ABSL_RAW_LOG(FATAL,
105
0
                 "absl::log_internal::SetTimeZone() has already been called");
106
0
  }
107
0
}
108
109
3.24M
const absl::TimeZone* TimeZone() {
110
3.24M
  return timezone_ptr.load(std::memory_order_acquire);
111
3.24M
}
112
113
0
bool ShouldSymbolizeLogStackTrace() {
114
0
  return symbolize_stack_trace.load(std::memory_order_acquire);
115
0
}
116
117
0
void EnableSymbolizeLogStackTrace(bool on_off) {
118
0
  symbolize_stack_trace.store(on_off, std::memory_order_release);
119
0
}
120
121
0
int MaxFramesInLogStackTrace() {
122
0
  return max_frames_in_stack_trace.load(std::memory_order_acquire);
123
0
}
124
125
0
void SetMaxFramesInLogStackTrace(int max_num_frames) {
126
0
  max_frames_in_stack_trace.store(max_num_frames, std::memory_order_release);
127
0
}
128
129
0
bool ExitOnDFatal() { return exit_on_dfatal.load(std::memory_order_acquire); }
130
131
0
void SetExitOnDFatal(bool on_off) {
132
0
  exit_on_dfatal.store(on_off, std::memory_order_release);
133
0
}
134
135
0
bool SuppressSigabortTrace() {
136
0
  return suppress_sigabort_trace.load(std::memory_order_acquire);
137
0
}
138
139
0
bool SetSuppressSigabortTrace(bool on_off) {
140
0
  return suppress_sigabort_trace.exchange(on_off);
141
0
}
142
143
}  // namespace log_internal
144
ABSL_NAMESPACE_END
145
}  // namespace absl