1 // Copyright 2014 The Chromium 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 #ifndef BASE_MAC_MACH_LOGGING_H_
6 #define BASE_MAC_MACH_LOGGING_H_
7 
8 #include <mach/mach.h>
9 
10 #include "base/base_export.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "build/build_config.h"
14 
15 // Use the MACH_LOG family of macros along with a mach_error_t (kern_return_t)
16 // containing a Mach error. The error value will be decoded so that logged
17 // messages explain the error.
18 //
19 // Use the BOOTSTRAP_LOG family of macros specifically for errors that occur
20 // while interoperating with the bootstrap subsystem. These errors will first
21 // be looked up as bootstrap error messages. If no match is found, they will
22 // be treated as generic Mach errors, as in MACH_LOG.
23 //
24 // Examples:
25 //
26 //   kern_return_t kr = mach_timebase_info(&info);
27 //   if (kr != KERN_SUCCESS) {
28 //     MACH_LOG(ERROR, kr) << "mach_timebase_info";
29 //   }
30 //
31 //   kr = vm_deallocate(task, address, size);
32 //   MACH_DCHECK(kr == KERN_SUCCESS, kr) << "vm_deallocate";
33 
34 namespace logging {
35 
36 class BASE_EXPORT MachLogMessage : public logging::LogMessage {
37  public:
38   MachLogMessage(const char* file_path,
39                  int line,
40                  LogSeverity severity,
41                  mach_error_t mach_err);
42   ~MachLogMessage();
43 
44  private:
45   mach_error_t mach_err_;
46 
47   DISALLOW_COPY_AND_ASSIGN(MachLogMessage);
48 };
49 
50 }  // namespace logging
51 
52 #if defined(NDEBUG)
53 #define MACH_DVLOG_IS_ON(verbose_level) 0
54 #else
55 #define MACH_DVLOG_IS_ON(verbose_level) VLOG_IS_ON(verbose_level)
56 #endif
57 
58 #define MACH_LOG_STREAM(severity, mach_err) \
59     COMPACT_GOOGLE_LOG_EX_ ## severity(MachLogMessage, mach_err).stream()
60 #define MACH_VLOG_STREAM(verbose_level, mach_err) \
61     logging::MachLogMessage(__FILE__, __LINE__, \
62                             -verbose_level, mach_err).stream()
63 
64 #define MACH_LOG(severity, mach_err) \
65     LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), LOG_IS_ON(severity))
66 #define MACH_LOG_IF(severity, condition, mach_err) \
67     LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
68                 LOG_IS_ON(severity) && (condition))
69 
70 #define MACH_VLOG(verbose_level, mach_err) \
71     LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
72                 VLOG_IS_ON(verbose_level))
73 #define MACH_VLOG_IF(verbose_level, condition, mach_err) \
74     LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
75                 VLOG_IS_ON(verbose_level) && (condition))
76 
77 #define MACH_CHECK(condition, mach_err) \
78     LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), !(condition)) \
79     << "Check failed: " # condition << ". "
80 
81 #define MACH_DLOG(severity, mach_err) \
82     LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), DLOG_IS_ON(severity))
83 #define MACH_DLOG_IF(severity, condition, mach_err) \
84     LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
85                 DLOG_IS_ON(severity) && (condition))
86 
87 #define MACH_DVLOG(verbose_level, mach_err) \
88     LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
89                 MACH_DVLOG_IS_ON(verbose_level))
90 #define MACH_DVLOG_IF(verbose_level, condition, mach_err) \
91     LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
92                 MACH_DVLOG_IS_ON(verbose_level) && (condition))
93 
94 #define MACH_DCHECK(condition, mach_err)        \
95   LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), \
96               DCHECK_IS_ON() && !(condition))   \
97       << "Check failed: " #condition << ". "
98 
99 #if !defined(OS_IOS)
100 
101 namespace logging {
102 
103 class BASE_EXPORT BootstrapLogMessage : public logging::LogMessage {
104  public:
105   BootstrapLogMessage(const char* file_path,
106                       int line,
107                       LogSeverity severity,
108                       kern_return_t bootstrap_err);
109   ~BootstrapLogMessage();
110 
111  private:
112   kern_return_t bootstrap_err_;
113 
114   DISALLOW_COPY_AND_ASSIGN(BootstrapLogMessage);
115 };
116 
117 }  // namespace logging
118 
119 #define BOOTSTRAP_DVLOG_IS_ON MACH_DVLOG_IS_ON
120 
121 #define BOOTSTRAP_LOG_STREAM(severity, bootstrap_err) \
122     COMPACT_GOOGLE_LOG_EX_ ## severity(BootstrapLogMessage, \
123                                        bootstrap_err).stream()
124 #define BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err) \
125     logging::BootstrapLogMessage(__FILE__, __LINE__, \
126                                  -verbose_level, bootstrap_err).stream()
127 
128 #define BOOTSTRAP_LOG(severity, bootstrap_err) \
129     LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, \
130                                      bootstrap_err), LOG_IS_ON(severity))
131 #define BOOTSTRAP_LOG_IF(severity, condition, bootstrap_err) \
132     LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
133                 LOG_IS_ON(severity) && (condition))
134 
135 #define BOOTSTRAP_VLOG(verbose_level, bootstrap_err) \
136     LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
137                 VLOG_IS_ON(verbose_level))
138 #define BOOTSTRAP_VLOG_IF(verbose_level, condition, bootstrap_err) \
139     LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
140                 VLOG_IS_ON(verbose_level) && (condition))
141 
142 #define BOOTSTRAP_CHECK(condition, bootstrap_err) \
143     LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), !(condition)) \
144     << "Check failed: " # condition << ". "
145 
146 #define BOOTSTRAP_DLOG(severity, bootstrap_err) \
147     LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
148                 DLOG_IS_ON(severity))
149 #define BOOTSTRAP_DLOG_IF(severity, condition, bootstrap_err) \
150     LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
151                 DLOG_IS_ON(severity) && (condition))
152 
153 #define BOOTSTRAP_DVLOG(verbose_level, bootstrap_err) \
154     LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
155                 BOOTSTRAP_DVLOG_IS_ON(verbose_level))
156 #define BOOTSTRAP_DVLOG_IF(verbose_level, condition, bootstrap_err) \
157     LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
158                 BOOTSTRAP_DVLOG_IS_ON(verbose_level) && (condition))
159 
160 #define BOOTSTRAP_DCHECK(condition, bootstrap_err)        \
161   LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), \
162               DCHECK_IS_ON() && !(condition))             \
163       << "Check failed: " #condition << ". "
164 
165 #endif  // !OS_IOS
166 
167 #endif  // BASE_MAC_MACH_LOGGING_H_
168