1 // Copyright 2020 The Chromium Authors
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 "partition_alloc/partition_alloc_base/check.h"
6 
7 #include "partition_alloc/partition_alloc_base/logging.h"
8 
9 namespace partition_alloc::internal::logging {
10 
11 // TODO(1151236): Make CheckError not to allocate memory. So we can use
12 // CHECK() inside PartitionAllocator when PartitionAllocator-Everywhere is
13 // enabled. (Also need to modify LogMessage).
14 
CheckError(const char * file,int line,LogSeverity severity,const char * condition)15 CheckError::CheckError(const char* file,
16                        int line,
17                        LogSeverity severity,
18                        const char* condition)
19     : log_message_(file, line, severity) {
20   log_message_.stream() << "Check failed: " << condition << ". ";
21 }
22 
CheckError(const char * file,int line,LogSeverity severity)23 CheckError::CheckError(const char* file, int line, LogSeverity severity)
24     : log_message_(file, line, severity) {}
25 
CheckError(const char * file,int line,LogSeverity severity,const char * condition,SystemErrorCode err_code)26 CheckError::CheckError(const char* file,
27                        int line,
28                        LogSeverity severity,
29                        const char* condition,
30                        SystemErrorCode err_code)
31     : errno_log_message_(file, line, severity, err_code), has_errno(true) {
32   errno_log_message_.stream() << "Check failed: " << condition << ". ";
33 }
34 
Check(const char * file,int line,const char * condition)35 check_error::Check::Check(const char* file, int line, const char* condition)
36     : CheckError(file, line, LOGGING_FATAL, condition) {}
37 
DCheck(const char * file,int line,const char * condition)38 check_error::DCheck::DCheck(const char* file, int line, const char* condition)
39     : CheckError(file, line, LOGGING_DCHECK, condition) {}
40 
PCheck(const char * file,int line,const char * condition)41 check_error::PCheck::PCheck(const char* file, int line, const char* condition)
42     : CheckError(file,
43                  line,
44                  LOGGING_FATAL,
45                  condition,
46                  logging::GetLastSystemErrorCode()) {}
47 
PCheck(const char * file,int line)48 check_error::PCheck::PCheck(const char* file, int line)
49     : PCheck(file, line, "") {}
50 
DPCheck(const char * file,int line,const char * condition)51 check_error::DPCheck::DPCheck(const char* file, int line, const char* condition)
52     : CheckError(file,
53                  line,
54                  LOGGING_DCHECK,
55                  condition,
56                  logging::GetLastSystemErrorCode()) {}
57 
NotImplemented(const char * file,int line,const char * function)58 check_error::NotImplemented::NotImplemented(const char* file,
59                                             int line,
60                                             const char* function)
61     : CheckError(file, line, LOGGING_ERROR) {
62   stream() << "Not implemented reached in " << function;
63 }
64 
stream()65 base::strings::CStringBuilder& CheckError::stream() {
66   return !has_errno ? log_message_.stream() : errno_log_message_.stream();
67 }
68 
~CheckError()69 CheckError::~CheckError() {
70   // Note: This function ends up in crash stack traces. If its full name
71   // changes, the crash server's magic signature logic needs to be updated.
72   // See cl/306632920.
73   if (!has_errno) {
74     log_message_.~LogMessage();
75   } else {
76 #if BUILDFLAG(IS_WIN)
77     errno_log_message_.~Win32ErrorLogMessage();
78 #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
79     errno_log_message_.~ErrnoLogMessage();
80 #endif  // BUILDFLAG(IS_WIN)
81   }
82 }
83 
RawCheckFailure(const char * message)84 void RawCheckFailure(const char* message) {
85   RawLog(LOGGING_FATAL, message);
86   PA_IMMEDIATE_CRASH();
87 }
88 
89 }  // namespace partition_alloc::internal::logging
90