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/basictypes.h"
12#include "base/logging.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
34namespace logging {
35
36class 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
101namespace logging {
102
103class 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