v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
logging.cc
Go to the documentation of this file.
1// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/base/logging.h"
6
7#include <cctype>
8#include <cstdarg>
9#include <cstdio>
10#include <cstdlib>
11
14
15namespace v8 {
16namespace base {
17
18namespace {
19
20void DefaultDcheckHandler(const char* file, int line, const char* message);
21
22void (*g_print_stack_trace)() = nullptr;
23
24void (*g_dcheck_function)(const char*, int, const char*) = DefaultDcheckHandler;
25
26void (*g_fatal_function)(const char*, int, const char*) = nullptr;
27
28std::string PrettyPrintChar(int ch) {
29 std::ostringstream oss;
30 switch (ch) {
31#define CHAR_PRINT_CASE(ch) \
32 case ch: \
33 oss << #ch; \
34 break;
35
36 CHAR_PRINT_CASE('\0')
37 CHAR_PRINT_CASE('\'')
38 CHAR_PRINT_CASE('\\')
39 CHAR_PRINT_CASE('\a')
40 CHAR_PRINT_CASE('\b')
41 CHAR_PRINT_CASE('\f')
42 CHAR_PRINT_CASE('\n')
44 CHAR_PRINT_CASE('\t')
45 CHAR_PRINT_CASE('\v')
46#undef CHAR_PRINT_CASE
47 default:
48 if (std::isprint(ch)) {
49 oss << '\'' << ch << '\'';
50 } else {
51 oss << std::hex << "\\x" << static_cast<unsigned int>(ch);
52 }
53 }
54 return oss.str();
55}
56
57void DefaultDcheckHandler(const char* file, int line, const char* message) {
58#ifdef DEBUG
59 V8_Fatal(file, line, "Debug check failed: %s.", message);
60#else
61 // This case happens only for unit tests.
62 V8_Fatal("Debug check failed: %s.", message);
63#endif
64}
65
66} // namespace
67
68void SetPrintStackTrace(void (*print_stack_trace)()) {
69 g_print_stack_trace = print_stack_trace;
70}
71
72void SetDcheckFunction(void (*dcheck_function)(const char*, int, const char*)) {
73 g_dcheck_function = dcheck_function ? dcheck_function : &DefaultDcheckHandler;
74}
75
76void SetFatalFunction(void (*fatal_function)(const char*, int, const char*)) {
77 g_fatal_function = fatal_function;
78}
79
80void FatalOOM(OOMType type, const char* msg) {
81 // Instead of directly aborting here with a message, it could make sense to
82 // call a global callback function that would then in turn call (the
83 // equivalent of) V8::FatalProcessOutOfMemory. This way, calling this
84 // function directly would not bypass any OOM handler installed by the
85 // embedder. We might still want to keep a function like this though that
86 // contains the fallback implementation if no callback has been installed.
87
88 const char* type_str = type == OOMType::kProcess ? "process" : "JavaScript";
89 OS::PrintError("\n\n#\n# Fatal %s out of memory: %s\n#", type_str, msg);
90
91 if (g_print_stack_trace) v8::base::g_print_stack_trace();
92 fflush(stderr);
93
94#ifdef V8_FUZZILLI
95 // When fuzzing, we generally want to ignore OOM failures.
96 // It's important that we exit with a non-zero exit status here so that the
97 // fuzzer treats it as a failed execution.
98 _exit(1);
99#else
100 OS::Abort();
101#endif // V8_FUZZILLI
102}
103
104// Define specialization to pretty print characters (escaping non-printable
105// characters) and to print c strings as pointers instead of strings.
106#define DEFINE_PRINT_CHECK_OPERAND_CHAR(type) \
107 template <> \
108 std::string PrintCheckOperand<type>(type ch) { \
109 return PrettyPrintChar(ch); \
110 } \
111 template <> \
112 std::string PrintCheckOperand<type*>(type * cstr) { \
113 return PrintCheckOperand<void*>(cstr); \
114 } \
115 template <> \
116 std::string PrintCheckOperand<const type*>(const type* cstr) { \
117 return PrintCheckOperand<const void*>(cstr); \
118 }
119
123#undef DEFINE_PRINT_CHECK_OPERAND_CHAR
124
125// Explicit instantiations for commonly used comparisons.
126#define DEFINE_MAKE_CHECK_OP_STRING(type) \
127 template std::string* MakeCheckOpString<type, type>(type, type, \
128 char const*); \
129 template std::string PrintCheckOperand<type>(type);
131DEFINE_MAKE_CHECK_OP_STRING(long) // NOLINT(runtime/int)
132DEFINE_MAKE_CHECK_OP_STRING(long long) // NOLINT(runtime/int)
133DEFINE_MAKE_CHECK_OP_STRING(unsigned int)
134DEFINE_MAKE_CHECK_OP_STRING(unsigned long) // NOLINT(runtime/int)
135DEFINE_MAKE_CHECK_OP_STRING(unsigned long long) // NOLINT(runtime/int)
137#undef DEFINE_MAKE_CHECK_OP_STRING
138
139} // namespace base
140} // namespace v8
141
142namespace {
143
144// FailureMessage is a stack allocated object which has a special marker field
145// at the start and at the end. This makes it possible to retrieve the embedded
146// message from the stack.
147//
148class FailureMessage {
149 public:
150 explicit FailureMessage(const char* format, va_list arguments) {
151 memset(&message_, 0, arraysize(message_));
152 v8::base::OS::VSNPrintF(&message_[0], arraysize(message_), format,
153 arguments);
154 }
155
156 static const uintptr_t kStartMarker = 0xdecade10;
157 static const uintptr_t kEndMarker = 0xdecade11;
158 static const int kMessageBufferSize = 512;
159
160 uintptr_t start_marker_ = kStartMarker;
161 char message_[kMessageBufferSize];
162 uintptr_t end_marker_ = kEndMarker;
163};
164
165} // namespace
166
167#ifdef DEBUG
168void V8_Fatal(const char* file, int line, const char* format, ...) {
169#else
170void V8_Fatal(const char* format, ...) {
171 const char* file = "";
172 int line = 0;
173#endif
174 va_list arguments;
175 va_start(arguments, format);
176 // Format the error message into a stack object for later retrieveal by the
177 // crash processor.
178 FailureMessage message(format, arguments);
179 va_end(arguments);
180
181 if (v8::base::g_fatal_function != nullptr) {
182 v8::base::g_fatal_function(file, line, message.message_);
183 }
184
185 fflush(stdout);
186 fflush(stderr);
187
188 // Print the formatted message to stdout without cropping the output.
190 // In this case, instead of crashing the process will be terminated
191 // normally by OS::Abort. Make this clear in the output printed to stderr.
192 v8::base::OS::PrintError(
193 "\n\n#\n# Safely terminating process due to error in %s, line %d\n# ",
194 file, line);
195 // Also prefix the error message (printed below). This has two purposes:
196 // (1) it makes it clear that this error is deemed "safe" (2) it causes
197 // fuzzers that pattern-match on stderr output to ignore these failures.
198 v8::base::OS::PrintError("The following harmless error was encountered: ");
199 } else {
200 v8::base::OS::PrintError("\n\n#\n# Fatal error in %s, line %d\n# ", file,
201 line);
202 }
203
204 // Print the error message.
205 va_start(arguments, format);
206 v8::base::OS::VPrintError(format, arguments);
207 va_end(arguments);
208
209 // Print the message object's address to force stack allocation.
210 v8::base::OS::PrintError("\n#\n#\n#\n#FailureMessage Object: %p", &message);
211
212 if (v8::base::g_print_stack_trace) v8::base::g_print_stack_trace();
213
214 fflush(stderr);
216}
217
218void V8_Dcheck(const char* file, int line, const char* message) {
220 // In this mode, DCHECK failures don't lead to process termination.
221 v8::base::OS::PrintError(
222 "# Ignoring debug check failure in %s, line %d: %s\n", file, line,
223 message);
224 return;
225 }
226
227 v8::base::g_dcheck_function(file, line, message);
228}
void V8_Fatal(const char *format,...)
Definition logging.cc:170
#define CHAR_PRINT_CASE(ch)
void V8_Dcheck(const char *file, int line, const char *message)
Definition logging.cc:218
#define DEFINE_PRINT_CHECK_OPERAND_CHAR(type)
Definition logging.cc:106
#define DEFINE_MAKE_CHECK_OP_STRING(type)
Definition logging.cc:126
static void Abort()
int r
Definition mul-fft.cc:298
void SetPrintStackTrace(void(*print_stack_trace)())
Definition logging.cc:68
void FatalOOM(OOMType type, const char *msg)
Definition logging.cc:80
V8_INLINE bool DcheckFailuresAreIgnored()
Definition abort-mode.h:46
void SetDcheckFunction(void(*dcheck_function)(const char *, int, const char *))
Definition logging.cc:72
V8_INLINE bool ControlledCrashesAreHarmless()
Definition abort-mode.h:41
void SetFatalFunction(void(*fatal_function)(const char *, int, const char *))
Definition logging.cc:76
#define arraysize(array)
Definition macros.h:67