1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189

base / apple / mach_logging.h [blame]

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_APPLE_MACH_LOGGING_H_
#define BASE_APPLE_MACH_LOGGING_H_

#include <mach/mach.h>

#include "base/base_export.h"
#include "base/logging.h"
#include "build/blink_buildflags.h"
#include "build/build_config.h"

// Use the MACH_LOG family of macros along with a mach_error_t (kern_return_t)
// containing a Mach error. The error value will be decoded so that logged
// messages explain the error.
//
// Use the BOOTSTRAP_LOG family of macros specifically for errors that occur
// while interoperating with the bootstrap subsystem. These errors will first
// be looked up as bootstrap error messages. If no match is found, they will
// be treated as generic Mach errors, as in MACH_LOG.
//
// Examples:
//
//   kern_return_t kr = mach_timebase_info(&info);
//   if (kr != KERN_SUCCESS) {
//     MACH_LOG(ERROR, kr) << "mach_timebase_info";
//   }
//
//   kr = vm_deallocate(task, address, size);
//   MACH_DCHECK(kr == KERN_SUCCESS, kr) << "vm_deallocate";

namespace logging {

class BASE_EXPORT MachLogMessage : public logging::LogMessage {
 public:
  MachLogMessage(const char* file_path,
                 int line,
                 LogSeverity severity,
                 mach_error_t mach_err);

  MachLogMessage(const MachLogMessage&) = delete;
  MachLogMessage& operator=(const MachLogMessage&) = delete;

  ~MachLogMessage() override;

 protected:
  void AppendError();

 private:
  mach_error_t mach_err_;
};

class BASE_EXPORT MachLogMessageFatal final : public MachLogMessage {
 public:
  using MachLogMessage::MachLogMessage;
  [[noreturn]] ~MachLogMessageFatal() override;
};

}  // namespace logging

#if DCHECK_IS_ON()
#define MACH_DVLOG_IS_ON(verbose_level) VLOG_IS_ON(verbose_level)
#else
#define MACH_DVLOG_IS_ON(verbose_level) 0
#endif

#define MACH_LOG_STREAM(severity, mach_err) \
    COMPACT_GOOGLE_LOG_EX_ ## severity(MachLogMessage, mach_err).stream()
#define MACH_VLOG_STREAM(verbose_level, mach_err) \
    logging::MachLogMessage(__FILE__, __LINE__, \
                            -verbose_level, mach_err).stream()

#define MACH_LOG(severity, mach_err) \
    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), LOG_IS_ON(severity))
#define MACH_LOG_IF(severity, condition, mach_err) \
    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
                LOG_IS_ON(severity) && (condition))

#define MACH_VLOG(verbose_level, mach_err) \
    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
                VLOG_IS_ON(verbose_level))
#define MACH_VLOG_IF(verbose_level, condition, mach_err) \
    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
                VLOG_IS_ON(verbose_level) && (condition))

#define MACH_CHECK(condition, mach_err) \
    LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), !(condition)) \
    << "Check failed: " # condition << ". "

#define MACH_DLOG(severity, mach_err) \
    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), DLOG_IS_ON(severity))
#define MACH_DLOG_IF(severity, condition, mach_err) \
    LAZY_STREAM(MACH_LOG_STREAM(severity, mach_err), \
                DLOG_IS_ON(severity) && (condition))

#define MACH_DVLOG(verbose_level, mach_err) \
    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
                MACH_DVLOG_IS_ON(verbose_level))
#define MACH_DVLOG_IF(verbose_level, condition, mach_err) \
    LAZY_STREAM(MACH_VLOG_STREAM(verbose_level, mach_err), \
                MACH_DVLOG_IS_ON(verbose_level) && (condition))

#define MACH_DCHECK(condition, mach_err)        \
  LAZY_STREAM(MACH_LOG_STREAM(FATAL, mach_err), \
              DCHECK_IS_ON() && !(condition))   \
      << "Check failed: " #condition << ". "

#if BUILDFLAG(USE_BLINK)

namespace logging {

class BASE_EXPORT BootstrapLogMessage : public logging::LogMessage {
 public:
  BootstrapLogMessage(const char* file_path,
                      int line,
                      LogSeverity severity,
                      kern_return_t bootstrap_err);

  BootstrapLogMessage(const BootstrapLogMessage&) = delete;
  BootstrapLogMessage& operator=(const BootstrapLogMessage&) = delete;

  ~BootstrapLogMessage() override;

 protected:
  void AppendError();

 private:
  kern_return_t bootstrap_err_;
};

class BASE_EXPORT BootstrapLogMessageFatal final : public BootstrapLogMessage {
 public:
  using BootstrapLogMessage::BootstrapLogMessage;
  [[noreturn]] ~BootstrapLogMessageFatal() override;
};

}  // namespace logging

#define BOOTSTRAP_DVLOG_IS_ON MACH_DVLOG_IS_ON

#define BOOTSTRAP_LOG_STREAM(severity, bootstrap_err) \
    COMPACT_GOOGLE_LOG_EX_ ## severity(BootstrapLogMessage, \
                                       bootstrap_err).stream()
#define BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err) \
    logging::BootstrapLogMessage(__FILE__, __LINE__, \
                                 -verbose_level, bootstrap_err).stream()

#define BOOTSTRAP_LOG(severity, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, \
                                     bootstrap_err), LOG_IS_ON(severity))
#define BOOTSTRAP_LOG_IF(severity, condition, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
                LOG_IS_ON(severity) && (condition))

#define BOOTSTRAP_VLOG(verbose_level, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
                VLOG_IS_ON(verbose_level))
#define BOOTSTRAP_VLOG_IF(verbose_level, condition, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
                VLOG_IS_ON(verbose_level) && (condition))

#define BOOTSTRAP_CHECK(condition, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), !(condition)) \
    << "Check failed: " # condition << ". "

#define BOOTSTRAP_DLOG(severity, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
                DLOG_IS_ON(severity))
#define BOOTSTRAP_DLOG_IF(severity, condition, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_LOG_STREAM(severity, bootstrap_err), \
                DLOG_IS_ON(severity) && (condition))

#define BOOTSTRAP_DVLOG(verbose_level, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
                BOOTSTRAP_DVLOG_IS_ON(verbose_level))
#define BOOTSTRAP_DVLOG_IF(verbose_level, condition, bootstrap_err) \
    LAZY_STREAM(BOOTSTRAP_VLOG_STREAM(verbose_level, bootstrap_err), \
                BOOTSTRAP_DVLOG_IS_ON(verbose_level) && (condition))

#define BOOTSTRAP_DCHECK(condition, bootstrap_err)        \
  LAZY_STREAM(BOOTSTRAP_LOG_STREAM(FATAL, bootstrap_err), \
              DCHECK_IS_ON() && !(condition))             \
      << "Check failed: " #condition << ". "

#endif  //  BUILDFLAG(USE_BLINK)

#endif  // BASE_APPLE_MACH_LOGGING_H_