• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 "base/apple/mach_logging.h"
6 
7 #include <iomanip>
8 #include <string>
9 
10 #include "base/immediate_crash.h"
11 #include "base/scoped_clear_last_error.h"
12 #include "base/strings/stringprintf.h"
13 #include "build/build_config.h"
14 
15 #if BUILDFLAG(USE_BLINK)
16 #if BUILDFLAG(IS_IOS)
17 #include "base/ios/sim_header_shims.h"
18 #else
19 #include <servers/bootstrap.h>
20 #endif  // BUILDFLAG(IS_IOS)
21 #endif  // BUILDFLAG(USE_BLINK)
22 
23 namespace {
24 
FormatMachErrorNumber(mach_error_t mach_err)25 std::string FormatMachErrorNumber(mach_error_t mach_err) {
26   // For the os/kern subsystem, give the error number in decimal as in
27   // <mach/kern_return.h>. Otherwise, give it in hexadecimal to make it easier
28   // to visualize the various bits. See <mach/error.h>.
29   if (mach_err >= 0 && mach_err < KERN_RETURN_MAX) {
30     return base::StringPrintf(" (%d)", mach_err);
31   }
32   return base::StringPrintf(" (0x%08x)", mach_err);
33 }
34 
35 }  // namespace
36 
37 namespace logging {
38 
MachLogMessage(const char * file_path,int line,LogSeverity severity,mach_error_t mach_err)39 MachLogMessage::MachLogMessage(const char* file_path,
40                                int line,
41                                LogSeverity severity,
42                                mach_error_t mach_err)
43     : LogMessage(file_path, line, severity), mach_err_(mach_err) {}
44 
~MachLogMessage()45 MachLogMessage::~MachLogMessage() {
46   AppendError();
47 }
48 
AppendError()49 void MachLogMessage::AppendError() {
50   // Don't let actions from this method affect the system error after returning.
51   base::ScopedClearLastError scoped_clear_last_error;
52 
53   stream() << ": " << mach_error_string(mach_err_)
54            << FormatMachErrorNumber(mach_err_);
55 }
56 
~MachLogMessageFatal()57 MachLogMessageFatal::~MachLogMessageFatal() {
58   AppendError();
59   Flush();
60   base::ImmediateCrash();
61 }
62 
63 #if BUILDFLAG(USE_BLINK)
64 
BootstrapLogMessage(const char * file_path,int line,LogSeverity severity,kern_return_t bootstrap_err)65 BootstrapLogMessage::BootstrapLogMessage(const char* file_path,
66                                          int line,
67                                          LogSeverity severity,
68                                          kern_return_t bootstrap_err)
69     : LogMessage(file_path, line, severity), bootstrap_err_(bootstrap_err) {}
70 
~BootstrapLogMessage()71 BootstrapLogMessage::~BootstrapLogMessage() {
72   AppendError();
73 }
74 
AppendError()75 void BootstrapLogMessage::AppendError() {
76   // Don't let actions from this method affect the system error after returning.
77   base::ScopedClearLastError scoped_clear_last_error;
78 
79   stream() << ": " << bootstrap_strerror(bootstrap_err_);
80 
81   switch (bootstrap_err_) {
82     case BOOTSTRAP_SUCCESS:
83     case BOOTSTRAP_NOT_PRIVILEGED:
84     case BOOTSTRAP_NAME_IN_USE:
85     case BOOTSTRAP_UNKNOWN_SERVICE:
86     case BOOTSTRAP_SERVICE_ACTIVE:
87     case BOOTSTRAP_BAD_COUNT:
88     case BOOTSTRAP_NO_MEMORY:
89     case BOOTSTRAP_NO_CHILDREN: {
90       // Show known bootstrap errors in decimal because that's how they're
91       // defined in <servers/bootstrap.h>.
92       stream() << " (" << bootstrap_err_ << ")";
93       break;
94     }
95 
96     default: {
97       // bootstrap_strerror passes unknown errors to mach_error_string, so
98       // format them as they would be if they were handled by
99       // MachErrorMessage.
100       stream() << FormatMachErrorNumber(bootstrap_err_);
101       break;
102     }
103   }
104 }
105 
~BootstrapLogMessageFatal()106 BootstrapLogMessageFatal::~BootstrapLogMessageFatal() {
107   AppendError();
108   Flush();
109   base::ImmediateCrash();
110 }
111 
112 #endif  // BUILDFLAG(USE_BLINK)
113 
114 }  // namespace logging
115