1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/check_version_internal.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/debug/alias.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/debug/dump_without_crashing.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/feature_list.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/features.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/thread_annotations.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/types/cxx23_to_underlying.h"
18*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
19*6777b538SAndroid Build Coastguard Worker
20*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL)
21*6777b538SAndroid Build Coastguard Worker // Forward declaring this ptr for code simplicity below, we'll never dereference
22*6777b538SAndroid Build Coastguard Worker // it under NaCl.
23*6777b538SAndroid Build Coastguard Worker namespace base::debug {
24*6777b538SAndroid Build Coastguard Worker class CrashKeyString;
25*6777b538SAndroid Build Coastguard Worker } // namespace base::debug
26*6777b538SAndroid Build Coastguard Worker #else
27*6777b538SAndroid Build Coastguard Worker #include "base/debug/crash_logging.h"
28*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(IS_NACL)
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker namespace logging {
31*6777b538SAndroid Build Coastguard Worker
32*6777b538SAndroid Build Coastguard Worker namespace {
33*6777b538SAndroid Build Coastguard Worker
GetDumpSeverity()34*6777b538SAndroid Build Coastguard Worker LogSeverity GetDumpSeverity() {
35*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(USE_FUZZING_ENGINE)
36*6777b538SAndroid Build Coastguard Worker // Crash in fuzzing builds because non-fatal CHECKs will eventually be
37*6777b538SAndroid Build Coastguard Worker // migrated to fatal CHECKs.
38*6777b538SAndroid Build Coastguard Worker return LOGGING_FATAL;
39*6777b538SAndroid Build Coastguard Worker #else
40*6777b538SAndroid Build Coastguard Worker return DCHECK_IS_ON() ? LOGGING_DCHECK : LOGGING_ERROR;
41*6777b538SAndroid Build Coastguard Worker #endif
42*6777b538SAndroid Build Coastguard Worker }
43*6777b538SAndroid Build Coastguard Worker
GetNotFatalUntilSeverity(base::NotFatalUntil fatal_milestone)44*6777b538SAndroid Build Coastguard Worker LogSeverity GetNotFatalUntilSeverity(base::NotFatalUntil fatal_milestone) {
45*6777b538SAndroid Build Coastguard Worker if (fatal_milestone != base::NotFatalUntil::NoSpecifiedMilestoneInternal &&
46*6777b538SAndroid Build Coastguard Worker base::to_underlying(fatal_milestone) <= BASE_CHECK_VERSION_INTERNAL) {
47*6777b538SAndroid Build Coastguard Worker return LOGGING_FATAL;
48*6777b538SAndroid Build Coastguard Worker }
49*6777b538SAndroid Build Coastguard Worker return GetDumpSeverity();
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker
GetCheckSeverity(base::NotFatalUntil fatal_milestone)52*6777b538SAndroid Build Coastguard Worker LogSeverity GetCheckSeverity(base::NotFatalUntil fatal_milestone) {
53*6777b538SAndroid Build Coastguard Worker // CHECKs are fatal unless `fatal_milestone` overrides it.
54*6777b538SAndroid Build Coastguard Worker if (fatal_milestone == base::NotFatalUntil::NoSpecifiedMilestoneInternal) {
55*6777b538SAndroid Build Coastguard Worker return LOGGING_FATAL;
56*6777b538SAndroid Build Coastguard Worker }
57*6777b538SAndroid Build Coastguard Worker return GetNotFatalUntilSeverity(fatal_milestone);
58*6777b538SAndroid Build Coastguard Worker }
59*6777b538SAndroid Build Coastguard Worker
GetNotReachedSeverity(base::NotFatalUntil fatal_milestone)60*6777b538SAndroid Build Coastguard Worker LogSeverity GetNotReachedSeverity(base::NotFatalUntil fatal_milestone) {
61*6777b538SAndroid Build Coastguard Worker // NOTREACHED severity is controlled by kNotReachedIsFatal unless
62*6777b538SAndroid Build Coastguard Worker // `fatal_milestone` overrides it.
63*6777b538SAndroid Build Coastguard Worker //
64*6777b538SAndroid Build Coastguard Worker // NOTREACHED() instances may be hit before base::FeatureList is enabled.
65*6777b538SAndroid Build Coastguard Worker if (fatal_milestone == base::NotFatalUntil::NoSpecifiedMilestoneInternal &&
66*6777b538SAndroid Build Coastguard Worker base::FeatureList::GetInstance() &&
67*6777b538SAndroid Build Coastguard Worker base::FeatureList::IsEnabled(base::features::kNotReachedIsFatal)) {
68*6777b538SAndroid Build Coastguard Worker return LOGGING_FATAL;
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker return GetNotFatalUntilSeverity(fatal_milestone);
71*6777b538SAndroid Build Coastguard Worker }
72*6777b538SAndroid Build Coastguard Worker
GetNotReachedCrashKey()73*6777b538SAndroid Build Coastguard Worker base::debug::CrashKeyString* GetNotReachedCrashKey() {
74*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL)
75*6777b538SAndroid Build Coastguard Worker return nullptr;
76*6777b538SAndroid Build Coastguard Worker #else
77*6777b538SAndroid Build Coastguard Worker static auto* const key = ::base::debug::AllocateCrashKeyString(
78*6777b538SAndroid Build Coastguard Worker "Logging-NOTREACHED_MESSAGE", base::debug::CrashKeySize::Size1024);
79*6777b538SAndroid Build Coastguard Worker return key;
80*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_NACL)
81*6777b538SAndroid Build Coastguard Worker }
82*6777b538SAndroid Build Coastguard Worker
GetDCheckCrashKey()83*6777b538SAndroid Build Coastguard Worker base::debug::CrashKeyString* GetDCheckCrashKey() {
84*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL)
85*6777b538SAndroid Build Coastguard Worker return nullptr;
86*6777b538SAndroid Build Coastguard Worker #else
87*6777b538SAndroid Build Coastguard Worker static auto* const key = ::base::debug::AllocateCrashKeyString(
88*6777b538SAndroid Build Coastguard Worker "Logging-DCHECK_MESSAGE", base::debug::CrashKeySize::Size1024);
89*6777b538SAndroid Build Coastguard Worker return key;
90*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_NACL)
91*6777b538SAndroid Build Coastguard Worker }
92*6777b538SAndroid Build Coastguard Worker
GetDumpWillBeCheckCrashKey()93*6777b538SAndroid Build Coastguard Worker base::debug::CrashKeyString* GetDumpWillBeCheckCrashKey() {
94*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL)
95*6777b538SAndroid Build Coastguard Worker return nullptr;
96*6777b538SAndroid Build Coastguard Worker #else
97*6777b538SAndroid Build Coastguard Worker static auto* const key = ::base::debug::AllocateCrashKeyString(
98*6777b538SAndroid Build Coastguard Worker "Logging-DUMP_WILL_BE_CHECK_MESSAGE",
99*6777b538SAndroid Build Coastguard Worker base::debug::CrashKeySize::Size1024);
100*6777b538SAndroid Build Coastguard Worker return key;
101*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_NACL)
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker
DumpWithoutCrashing(base::debug::CrashKeyString * message_key,const std::string & crash_string,const base::Location & location,base::NotFatalUntil fatal_milestone)104*6777b538SAndroid Build Coastguard Worker void DumpWithoutCrashing(base::debug::CrashKeyString* message_key,
105*6777b538SAndroid Build Coastguard Worker const std::string& crash_string,
106*6777b538SAndroid Build Coastguard Worker const base::Location& location,
107*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil fatal_milestone) {
108*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_NACL)
109*6777b538SAndroid Build Coastguard Worker static auto* const fatal_milestone_key =
110*6777b538SAndroid Build Coastguard Worker ::base::debug::AllocateCrashKeyString("Logging-FATAL_MILESTONE",
111*6777b538SAndroid Build Coastguard Worker base::debug::CrashKeySize::Size32);
112*6777b538SAndroid Build Coastguard Worker std::optional<base::debug::ScopedCrashKeyString> scoped_fatal_milestone_key;
113*6777b538SAndroid Build Coastguard Worker // Store the fatal milestone only when one is provided.
114*6777b538SAndroid Build Coastguard Worker if (fatal_milestone != base::NotFatalUntil::NoSpecifiedMilestoneInternal) {
115*6777b538SAndroid Build Coastguard Worker scoped_fatal_milestone_key.emplace(
116*6777b538SAndroid Build Coastguard Worker fatal_milestone_key,
117*6777b538SAndroid Build Coastguard Worker base::NumberToString(base::to_underlying(fatal_milestone)));
118*6777b538SAndroid Build Coastguard Worker }
119*6777b538SAndroid Build Coastguard Worker // Always store the crash string.
120*6777b538SAndroid Build Coastguard Worker base::debug::ScopedCrashKeyString scoped_message_key(message_key,
121*6777b538SAndroid Build Coastguard Worker crash_string);
122*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(IS_NACL)
123*6777b538SAndroid Build Coastguard Worker // Copy the crash message to stack memory to make sure it can be recovered in
124*6777b538SAndroid Build Coastguard Worker // crash dumps. This is easier to recover in minidumps than crash keys during
125*6777b538SAndroid Build Coastguard Worker // local debugging.
126*6777b538SAndroid Build Coastguard Worker DEBUG_ALIAS_FOR_CSTR(log_message_str, crash_string.c_str(), 1024);
127*6777b538SAndroid Build Coastguard Worker
128*6777b538SAndroid Build Coastguard Worker // Report from the same location at most once every 30 days (unless the
129*6777b538SAndroid Build Coastguard Worker // process has died). This attempts to prevent us from flooding ourselves with
130*6777b538SAndroid Build Coastguard Worker // repeat reports for the same bug.
131*6777b538SAndroid Build Coastguard Worker base::debug::DumpWithoutCrashing(location, base::Days(30));
132*6777b538SAndroid Build Coastguard Worker }
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker class NotReachedLogMessage : public LogMessage {
135*6777b538SAndroid Build Coastguard Worker public:
NotReachedLogMessage(const base::Location & location,LogSeverity severity,base::NotFatalUntil fatal_milestone)136*6777b538SAndroid Build Coastguard Worker NotReachedLogMessage(const base::Location& location,
137*6777b538SAndroid Build Coastguard Worker LogSeverity severity,
138*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil fatal_milestone)
139*6777b538SAndroid Build Coastguard Worker : LogMessage(location.file_name(), location.line_number(), severity),
140*6777b538SAndroid Build Coastguard Worker location_(location),
141*6777b538SAndroid Build Coastguard Worker fatal_milestone_(fatal_milestone) {}
~NotReachedLogMessage()142*6777b538SAndroid Build Coastguard Worker ~NotReachedLogMessage() override {
143*6777b538SAndroid Build Coastguard Worker if (severity() != logging::LOGGING_FATAL) {
144*6777b538SAndroid Build Coastguard Worker DumpWithoutCrashing(GetNotReachedCrashKey(), BuildCrashString(),
145*6777b538SAndroid Build Coastguard Worker location_, fatal_milestone_);
146*6777b538SAndroid Build Coastguard Worker }
147*6777b538SAndroid Build Coastguard Worker }
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker private:
150*6777b538SAndroid Build Coastguard Worker const base::Location location_;
151*6777b538SAndroid Build Coastguard Worker const base::NotFatalUntil fatal_milestone_;
152*6777b538SAndroid Build Coastguard Worker };
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Worker class DCheckLogMessage : public LogMessage {
155*6777b538SAndroid Build Coastguard Worker public:
DCheckLogMessage(const base::Location & location)156*6777b538SAndroid Build Coastguard Worker DCheckLogMessage(const base::Location& location)
157*6777b538SAndroid Build Coastguard Worker : LogMessage(location.file_name(),
158*6777b538SAndroid Build Coastguard Worker location.line_number(),
159*6777b538SAndroid Build Coastguard Worker LOGGING_DCHECK),
160*6777b538SAndroid Build Coastguard Worker location_(location) {}
~DCheckLogMessage()161*6777b538SAndroid Build Coastguard Worker ~DCheckLogMessage() override {
162*6777b538SAndroid Build Coastguard Worker if (severity() != logging::LOGGING_FATAL) {
163*6777b538SAndroid Build Coastguard Worker DumpWithoutCrashing(GetDCheckCrashKey(), BuildCrashString(), location_,
164*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil::NoSpecifiedMilestoneInternal);
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker private:
169*6777b538SAndroid Build Coastguard Worker const base::Location location_;
170*6777b538SAndroid Build Coastguard Worker };
171*6777b538SAndroid Build Coastguard Worker
172*6777b538SAndroid Build Coastguard Worker class CheckLogMessage : public LogMessage {
173*6777b538SAndroid Build Coastguard Worker public:
CheckLogMessage(const base::Location & location,LogSeverity severity,base::NotFatalUntil fatal_milestone)174*6777b538SAndroid Build Coastguard Worker CheckLogMessage(const base::Location& location,
175*6777b538SAndroid Build Coastguard Worker LogSeverity severity,
176*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil fatal_milestone)
177*6777b538SAndroid Build Coastguard Worker : LogMessage(location.file_name(), location.line_number(), severity),
178*6777b538SAndroid Build Coastguard Worker location_(location),
179*6777b538SAndroid Build Coastguard Worker fatal_milestone_(fatal_milestone) {}
~CheckLogMessage()180*6777b538SAndroid Build Coastguard Worker ~CheckLogMessage() override {
181*6777b538SAndroid Build Coastguard Worker if (severity() != logging::LOGGING_FATAL) {
182*6777b538SAndroid Build Coastguard Worker DumpWithoutCrashing(GetDumpWillBeCheckCrashKey(), BuildCrashString(),
183*6777b538SAndroid Build Coastguard Worker location_, fatal_milestone_);
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker }
186*6777b538SAndroid Build Coastguard Worker
187*6777b538SAndroid Build Coastguard Worker private:
188*6777b538SAndroid Build Coastguard Worker const base::Location location_;
189*6777b538SAndroid Build Coastguard Worker const base::NotFatalUntil fatal_milestone_;
190*6777b538SAndroid Build Coastguard Worker };
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
193*6777b538SAndroid Build Coastguard Worker class DCheckWin32ErrorLogMessage : public Win32ErrorLogMessage {
194*6777b538SAndroid Build Coastguard Worker public:
DCheckWin32ErrorLogMessage(const base::Location & location,SystemErrorCode err)195*6777b538SAndroid Build Coastguard Worker DCheckWin32ErrorLogMessage(const base::Location& location,
196*6777b538SAndroid Build Coastguard Worker SystemErrorCode err)
197*6777b538SAndroid Build Coastguard Worker : Win32ErrorLogMessage(location.file_name(),
198*6777b538SAndroid Build Coastguard Worker location.line_number(),
199*6777b538SAndroid Build Coastguard Worker LOGGING_DCHECK,
200*6777b538SAndroid Build Coastguard Worker err),
201*6777b538SAndroid Build Coastguard Worker location_(location) {}
~DCheckWin32ErrorLogMessage()202*6777b538SAndroid Build Coastguard Worker ~DCheckWin32ErrorLogMessage() override {
203*6777b538SAndroid Build Coastguard Worker if (severity() != logging::LOGGING_FATAL) {
204*6777b538SAndroid Build Coastguard Worker DumpWithoutCrashing(GetDCheckCrashKey(), BuildCrashString(), location_,
205*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil::NoSpecifiedMilestoneInternal);
206*6777b538SAndroid Build Coastguard Worker }
207*6777b538SAndroid Build Coastguard Worker }
208*6777b538SAndroid Build Coastguard Worker
209*6777b538SAndroid Build Coastguard Worker private:
210*6777b538SAndroid Build Coastguard Worker const base::Location location_;
211*6777b538SAndroid Build Coastguard Worker };
212*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
213*6777b538SAndroid Build Coastguard Worker class DCheckErrnoLogMessage : public ErrnoLogMessage {
214*6777b538SAndroid Build Coastguard Worker public:
DCheckErrnoLogMessage(const base::Location & location,SystemErrorCode err)215*6777b538SAndroid Build Coastguard Worker DCheckErrnoLogMessage(const base::Location& location, SystemErrorCode err)
216*6777b538SAndroid Build Coastguard Worker : ErrnoLogMessage(location.file_name(),
217*6777b538SAndroid Build Coastguard Worker location.line_number(),
218*6777b538SAndroid Build Coastguard Worker LOGGING_DCHECK,
219*6777b538SAndroid Build Coastguard Worker err),
220*6777b538SAndroid Build Coastguard Worker location_(location) {}
~DCheckErrnoLogMessage()221*6777b538SAndroid Build Coastguard Worker ~DCheckErrnoLogMessage() override {
222*6777b538SAndroid Build Coastguard Worker if (severity() != logging::LOGGING_FATAL) {
223*6777b538SAndroid Build Coastguard Worker DumpWithoutCrashing(GetDCheckCrashKey(), BuildCrashString(), location_,
224*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil::NoSpecifiedMilestoneInternal);
225*6777b538SAndroid Build Coastguard Worker }
226*6777b538SAndroid Build Coastguard Worker }
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker private:
229*6777b538SAndroid Build Coastguard Worker const base::Location location_;
230*6777b538SAndroid Build Coastguard Worker };
231*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
232*6777b538SAndroid Build Coastguard Worker
233*6777b538SAndroid Build Coastguard Worker } // namespace
234*6777b538SAndroid Build Coastguard Worker
Check(const char * condition,base::NotFatalUntil fatal_milestone,const base::Location & location)235*6777b538SAndroid Build Coastguard Worker CheckError CheckError::Check(const char* condition,
236*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil fatal_milestone,
237*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
238*6777b538SAndroid Build Coastguard Worker auto* const log_message = new CheckLogMessage(
239*6777b538SAndroid Build Coastguard Worker location, GetCheckSeverity(fatal_milestone), fatal_milestone);
240*6777b538SAndroid Build Coastguard Worker log_message->stream() << "Check failed: " << condition << ". ";
241*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
242*6777b538SAndroid Build Coastguard Worker }
243*6777b538SAndroid Build Coastguard Worker
CheckOp(char * log_message_str,base::NotFatalUntil fatal_milestone,const base::Location & location)244*6777b538SAndroid Build Coastguard Worker CheckError CheckError::CheckOp(char* log_message_str,
245*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil fatal_milestone,
246*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
247*6777b538SAndroid Build Coastguard Worker auto* const log_message = new CheckLogMessage(
248*6777b538SAndroid Build Coastguard Worker location, GetCheckSeverity(fatal_milestone), fatal_milestone);
249*6777b538SAndroid Build Coastguard Worker log_message->stream() << log_message_str;
250*6777b538SAndroid Build Coastguard Worker free(log_message_str);
251*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
252*6777b538SAndroid Build Coastguard Worker }
253*6777b538SAndroid Build Coastguard Worker
DCheck(const char * condition,const base::Location & location)254*6777b538SAndroid Build Coastguard Worker CheckError CheckError::DCheck(const char* condition,
255*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
256*6777b538SAndroid Build Coastguard Worker auto* const log_message = new DCheckLogMessage(location);
257*6777b538SAndroid Build Coastguard Worker log_message->stream() << "Check failed: " << condition << ". ";
258*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker
DCheckOp(char * log_message_str,const base::Location & location)261*6777b538SAndroid Build Coastguard Worker CheckError CheckError::DCheckOp(char* log_message_str,
262*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
263*6777b538SAndroid Build Coastguard Worker auto* const log_message = new DCheckLogMessage(location);
264*6777b538SAndroid Build Coastguard Worker log_message->stream() << log_message_str;
265*6777b538SAndroid Build Coastguard Worker free(log_message_str);
266*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
267*6777b538SAndroid Build Coastguard Worker }
268*6777b538SAndroid Build Coastguard Worker
DumpWillBeCheck(const char * condition,const base::Location & location)269*6777b538SAndroid Build Coastguard Worker CheckError CheckError::DumpWillBeCheck(const char* condition,
270*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
271*6777b538SAndroid Build Coastguard Worker auto* const log_message =
272*6777b538SAndroid Build Coastguard Worker new CheckLogMessage(location, GetDumpSeverity(),
273*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil::NoSpecifiedMilestoneInternal);
274*6777b538SAndroid Build Coastguard Worker log_message->stream() << "Check failed: " << condition << ". ";
275*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
276*6777b538SAndroid Build Coastguard Worker }
277*6777b538SAndroid Build Coastguard Worker
DumpWillBeCheckOp(char * log_message_str,const base::Location & location)278*6777b538SAndroid Build Coastguard Worker CheckError CheckError::DumpWillBeCheckOp(char* log_message_str,
279*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
280*6777b538SAndroid Build Coastguard Worker auto* const log_message =
281*6777b538SAndroid Build Coastguard Worker new CheckLogMessage(location, GetDumpSeverity(),
282*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil::NoSpecifiedMilestoneInternal);
283*6777b538SAndroid Build Coastguard Worker log_message->stream() << log_message_str;
284*6777b538SAndroid Build Coastguard Worker free(log_message_str);
285*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
286*6777b538SAndroid Build Coastguard Worker }
287*6777b538SAndroid Build Coastguard Worker
PCheck(const char * condition,const base::Location & location)288*6777b538SAndroid Build Coastguard Worker CheckError CheckError::PCheck(const char* condition,
289*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
290*6777b538SAndroid Build Coastguard Worker SystemErrorCode err_code = logging::GetLastSystemErrorCode();
291*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
292*6777b538SAndroid Build Coastguard Worker auto* const log_message = new Win32ErrorLogMessage(
293*6777b538SAndroid Build Coastguard Worker location.file_name(), location.line_number(), LOGGING_FATAL, err_code);
294*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
295*6777b538SAndroid Build Coastguard Worker auto* const log_message = new ErrnoLogMessage(
296*6777b538SAndroid Build Coastguard Worker location.file_name(), location.line_number(), LOGGING_FATAL, err_code);
297*6777b538SAndroid Build Coastguard Worker #endif
298*6777b538SAndroid Build Coastguard Worker log_message->stream() << "Check failed: " << condition << ". ";
299*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
300*6777b538SAndroid Build Coastguard Worker }
301*6777b538SAndroid Build Coastguard Worker
PCheck(const base::Location & location)302*6777b538SAndroid Build Coastguard Worker CheckError CheckError::PCheck(const base::Location& location) {
303*6777b538SAndroid Build Coastguard Worker return PCheck("", location);
304*6777b538SAndroid Build Coastguard Worker }
305*6777b538SAndroid Build Coastguard Worker
DPCheck(const char * condition,const base::Location & location)306*6777b538SAndroid Build Coastguard Worker CheckError CheckError::DPCheck(const char* condition,
307*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
308*6777b538SAndroid Build Coastguard Worker SystemErrorCode err_code = logging::GetLastSystemErrorCode();
309*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
310*6777b538SAndroid Build Coastguard Worker auto* const log_message = new DCheckWin32ErrorLogMessage(location, err_code);
311*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
312*6777b538SAndroid Build Coastguard Worker auto* const log_message = new DCheckErrnoLogMessage(location, err_code);
313*6777b538SAndroid Build Coastguard Worker #endif
314*6777b538SAndroid Build Coastguard Worker log_message->stream() << "Check failed: " << condition << ". ";
315*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
316*6777b538SAndroid Build Coastguard Worker }
317*6777b538SAndroid Build Coastguard Worker
DumpWillBeNotReachedNoreturn(const base::Location & location)318*6777b538SAndroid Build Coastguard Worker CheckError CheckError::DumpWillBeNotReachedNoreturn(
319*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
320*6777b538SAndroid Build Coastguard Worker auto* const log_message = new NotReachedLogMessage(
321*6777b538SAndroid Build Coastguard Worker location, GetDumpSeverity(),
322*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil::NoSpecifiedMilestoneInternal);
323*6777b538SAndroid Build Coastguard Worker log_message->stream() << "NOTREACHED hit. ";
324*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker
NotImplemented(const char * function,const base::Location & location)327*6777b538SAndroid Build Coastguard Worker CheckError CheckError::NotImplemented(const char* function,
328*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
329*6777b538SAndroid Build Coastguard Worker auto* const log_message = new LogMessage(
330*6777b538SAndroid Build Coastguard Worker location.file_name(), location.line_number(), LOGGING_ERROR);
331*6777b538SAndroid Build Coastguard Worker log_message->stream() << "Not implemented reached in " << function;
332*6777b538SAndroid Build Coastguard Worker return CheckError(log_message);
333*6777b538SAndroid Build Coastguard Worker }
334*6777b538SAndroid Build Coastguard Worker
stream()335*6777b538SAndroid Build Coastguard Worker std::ostream& CheckError::stream() {
336*6777b538SAndroid Build Coastguard Worker return log_message_->stream();
337*6777b538SAndroid Build Coastguard Worker }
338*6777b538SAndroid Build Coastguard Worker
~CheckError()339*6777b538SAndroid Build Coastguard Worker CheckError::~CheckError() {
340*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1409729): Consider splitting out CHECK from DCHECK so that
341*6777b538SAndroid Build Coastguard Worker // the destructor can be marked [[noreturn]] and we don't need to check
342*6777b538SAndroid Build Coastguard Worker // severity in the destructor.
343*6777b538SAndroid Build Coastguard Worker const bool is_fatal = log_message_->severity() == LOGGING_FATAL;
344*6777b538SAndroid Build Coastguard Worker // Note: This function ends up in crash stack traces. If its full name
345*6777b538SAndroid Build Coastguard Worker // changes, the crash server's magic signature logic needs to be updated.
346*6777b538SAndroid Build Coastguard Worker // See cl/306632920.
347*6777b538SAndroid Build Coastguard Worker
348*6777b538SAndroid Build Coastguard Worker // Reset before `ImmediateCrash()` to ensure the message is flushed.
349*6777b538SAndroid Build Coastguard Worker log_message_.reset();
350*6777b538SAndroid Build Coastguard Worker
351*6777b538SAndroid Build Coastguard Worker // Make sure we crash even if LOG(FATAL) has been overridden.
352*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1409729): Remove severity checking in the destructor when
353*6777b538SAndroid Build Coastguard Worker // LOG(FATAL) is [[noreturn]] and can't be overridden.
354*6777b538SAndroid Build Coastguard Worker if (is_fatal) {
355*6777b538SAndroid Build Coastguard Worker base::ImmediateCrash();
356*6777b538SAndroid Build Coastguard Worker }
357*6777b538SAndroid Build Coastguard Worker }
358*6777b538SAndroid Build Coastguard Worker
CheckError(LogMessage * log_message)359*6777b538SAndroid Build Coastguard Worker CheckError::CheckError(LogMessage* log_message) : log_message_(log_message) {}
360*6777b538SAndroid Build Coastguard Worker
NotReached(base::NotFatalUntil fatal_milestone,const base::Location & location)361*6777b538SAndroid Build Coastguard Worker NotReachedError NotReachedError::NotReached(base::NotFatalUntil fatal_milestone,
362*6777b538SAndroid Build Coastguard Worker const base::Location& location) {
363*6777b538SAndroid Build Coastguard Worker auto* const log_message = new NotReachedLogMessage(
364*6777b538SAndroid Build Coastguard Worker location, GetNotReachedSeverity(fatal_milestone), fatal_milestone);
365*6777b538SAndroid Build Coastguard Worker
366*6777b538SAndroid Build Coastguard Worker // TODO(pbos): Consider a better message for NotReached(), this is here to
367*6777b538SAndroid Build Coastguard Worker // match existing behavior + test expectations.
368*6777b538SAndroid Build Coastguard Worker log_message->stream() << "Check failed: false. ";
369*6777b538SAndroid Build Coastguard Worker return NotReachedError(log_message);
370*6777b538SAndroid Build Coastguard Worker }
371*6777b538SAndroid Build Coastguard Worker
TriggerNotReached()372*6777b538SAndroid Build Coastguard Worker void NotReachedError::TriggerNotReached() {
373*6777b538SAndroid Build Coastguard Worker // This triggers a NOTREACHED() error as the returned NotReachedError goes out
374*6777b538SAndroid Build Coastguard Worker // of scope.
375*6777b538SAndroid Build Coastguard Worker NotReached()
376*6777b538SAndroid Build Coastguard Worker << "NOTREACHED log messages are omitted in official builds. Sorry!";
377*6777b538SAndroid Build Coastguard Worker }
378*6777b538SAndroid Build Coastguard Worker
379*6777b538SAndroid Build Coastguard Worker NotReachedError::~NotReachedError() = default;
380*6777b538SAndroid Build Coastguard Worker
NotReachedNoreturnError(const base::Location & location)381*6777b538SAndroid Build Coastguard Worker NotReachedNoreturnError::NotReachedNoreturnError(const base::Location& location)
382*6777b538SAndroid Build Coastguard Worker : CheckError([location]() {
383*6777b538SAndroid Build Coastguard Worker auto* const log_message = new NotReachedLogMessage(
384*6777b538SAndroid Build Coastguard Worker location, LOGGING_FATAL,
385*6777b538SAndroid Build Coastguard Worker base::NotFatalUntil::NoSpecifiedMilestoneInternal);
386*6777b538SAndroid Build Coastguard Worker log_message->stream() << "NOTREACHED hit. ";
387*6777b538SAndroid Build Coastguard Worker return log_message;
388*6777b538SAndroid Build Coastguard Worker }()) {}
389*6777b538SAndroid Build Coastguard Worker
390*6777b538SAndroid Build Coastguard Worker // Note: This function ends up in crash stack traces. If its full name changes,
391*6777b538SAndroid Build Coastguard Worker // the crash server's magic signature logic needs to be updated. See
392*6777b538SAndroid Build Coastguard Worker // cl/306632920.
~NotReachedNoreturnError()393*6777b538SAndroid Build Coastguard Worker NotReachedNoreturnError::~NotReachedNoreturnError() {
394*6777b538SAndroid Build Coastguard Worker // Reset before `ImmediateCrash()` to ensure the message is flushed.
395*6777b538SAndroid Build Coastguard Worker log_message_.reset();
396*6777b538SAndroid Build Coastguard Worker
397*6777b538SAndroid Build Coastguard Worker // Make sure we die if we haven't.
398*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1409729): Replace this with NOTREACHED_NORETURN() once
399*6777b538SAndroid Build Coastguard Worker // LOG(FATAL) is [[noreturn]].
400*6777b538SAndroid Build Coastguard Worker base::ImmediateCrash();
401*6777b538SAndroid Build Coastguard Worker }
402*6777b538SAndroid Build Coastguard Worker
RawCheckFailure(const char * message)403*6777b538SAndroid Build Coastguard Worker void RawCheckFailure(const char* message) {
404*6777b538SAndroid Build Coastguard Worker RawLog(LOGGING_FATAL, message);
405*6777b538SAndroid Build Coastguard Worker __builtin_unreachable();
406*6777b538SAndroid Build Coastguard Worker }
407*6777b538SAndroid Build Coastguard Worker
408*6777b538SAndroid Build Coastguard Worker } // namespace logging
409