1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #ifdef BASE_CHECK_H_
8*6777b538SAndroid Build Coastguard Worker #error "logging.h should not include check.h"
9*6777b538SAndroid Build Coastguard Worker #endif
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include <limits.h>
12*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker #include <algorithm>
15*6777b538SAndroid Build Coastguard Worker #include <atomic>
16*6777b538SAndroid Build Coastguard Worker #include <cstring>
17*6777b538SAndroid Build Coastguard Worker #include <ctime>
18*6777b538SAndroid Build Coastguard Worker #include <iomanip>
19*6777b538SAndroid Build Coastguard Worker #include <memory>
20*6777b538SAndroid Build Coastguard Worker #include <ostream>
21*6777b538SAndroid Build Coastguard Worker #include <string>
22*6777b538SAndroid Build Coastguard Worker #include <tuple>
23*6777b538SAndroid Build Coastguard Worker #include <utility>
24*6777b538SAndroid Build Coastguard Worker #include <vector>
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/base_switches.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/containers/stack.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/debug/alias.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/debug/crash_logging.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/debug/debugger.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/debug/stack_trace.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/debug/task_trace.h"
35*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
36*6777b538SAndroid Build Coastguard Worker #include "base/immediate_crash.h"
37*6777b538SAndroid Build Coastguard Worker #include "base/no_destructor.h"
38*6777b538SAndroid Build Coastguard Worker #include "base/not_fatal_until.h"
39*6777b538SAndroid Build Coastguard Worker #include "base/path_service.h"
40*6777b538SAndroid Build Coastguard Worker #include "base/pending_task.h"
41*6777b538SAndroid Build Coastguard Worker #include "base/posix/eintr_wrapper.h"
42*6777b538SAndroid Build Coastguard Worker #include "base/process/process_handle.h"
43*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
44*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
45*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
46*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
47*6777b538SAndroid Build Coastguard Worker #include "base/strings/sys_string_conversions.h"
48*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
49*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h"
50*6777b538SAndroid Build Coastguard Worker #include "base/task/common/task_annotator.h"
51*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_logging_settings.h"
52*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
53*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/base_tracing.h"
54*6777b538SAndroid Build Coastguard Worker #include "base/vlog.h"
55*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
56*6777b538SAndroid Build Coastguard Worker #include "build/chromeos_buildflags.h"
57*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_NACL)
60*6777b538SAndroid Build Coastguard Worker #include "base/auto_reset.h"
61*6777b538SAndroid Build Coastguard Worker #include "base/debug/crash_logging.h"
62*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(IS_NACL)
63*6777b538SAndroid Build Coastguard Worker
64*6777b538SAndroid Build Coastguard Worker #if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
65*6777b538SAndroid Build Coastguard Worker #include "base/debug/leak_annotations.h"
66*6777b538SAndroid Build Coastguard Worker #endif // defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
69*6777b538SAndroid Build Coastguard Worker #include <windows.h>
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker #include <io.h>
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker #include "base/win/win_util.h"
74*6777b538SAndroid Build Coastguard Worker
75*6777b538SAndroid Build Coastguard Worker typedef HANDLE FileHandle;
76*6777b538SAndroid Build Coastguard Worker // Windows warns on using write(). It prefers _write().
77*6777b538SAndroid Build Coastguard Worker #define write(fd, buf, count) _write(fd, buf, static_cast<unsigned int>(count))
78*6777b538SAndroid Build Coastguard Worker // Windows doesn't define STDERR_FILENO. Define it here.
79*6777b538SAndroid Build Coastguard Worker #define STDERR_FILENO 2
80*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
83*6777b538SAndroid Build Coastguard Worker #include <CoreFoundation/CoreFoundation.h>
84*6777b538SAndroid Build Coastguard Worker #include <mach-o/dyld.h>
85*6777b538SAndroid Build Coastguard Worker #include <mach/mach.h>
86*6777b538SAndroid Build Coastguard Worker #include <mach/mach_time.h>
87*6777b538SAndroid Build Coastguard Worker #include <os/log.h>
88*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_APPLE)
89*6777b538SAndroid Build Coastguard Worker
90*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
91*6777b538SAndroid Build Coastguard Worker #include <errno.h>
92*6777b538SAndroid Build Coastguard Worker #include <paths.h>
93*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
94*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
95*6777b538SAndroid Build Coastguard Worker #include <string.h>
96*6777b538SAndroid Build Coastguard Worker #include <sys/stat.h>
97*6777b538SAndroid Build Coastguard Worker #include <time.h>
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker #include "base/posix/safe_strerror.h"
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL)
102*6777b538SAndroid Build Coastguard Worker #include <sys/time.h> // timespec doesn't seem to be in <time.h>
103*6777b538SAndroid Build Coastguard Worker #endif
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker #define MAX_PATH PATH_MAX
106*6777b538SAndroid Build Coastguard Worker typedef FILE* FileHandle;
107*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
110*6777b538SAndroid Build Coastguard Worker #include <android/log.h>
111*6777b538SAndroid Build Coastguard Worker #include "base/android/jni_android.h"
112*6777b538SAndroid Build Coastguard Worker #endif
113*6777b538SAndroid Build Coastguard Worker
114*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_ASH)
115*6777b538SAndroid Build Coastguard Worker #include "base/files/scoped_file.h"
116*6777b538SAndroid Build Coastguard Worker #endif
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
119*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/scoped_fx_logger.h"
120*6777b538SAndroid Build Coastguard Worker #endif
121*6777b538SAndroid Build Coastguard Worker
122*6777b538SAndroid Build Coastguard Worker namespace logging {
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker namespace {
125*6777b538SAndroid Build Coastguard Worker
126*6777b538SAndroid Build Coastguard Worker int g_min_log_level = 0;
127*6777b538SAndroid Build Coastguard Worker
128*6777b538SAndroid Build Coastguard Worker // NOTE: Once |g_vlog_info| has been initialized, it might be in use
129*6777b538SAndroid Build Coastguard Worker // by another thread. Never delete the old VLogInfo, just create a second
130*6777b538SAndroid Build Coastguard Worker // one and overwrite. We need to use leak-san annotations on this intentional
131*6777b538SAndroid Build Coastguard Worker // leak.
132*6777b538SAndroid Build Coastguard Worker //
133*6777b538SAndroid Build Coastguard Worker // This can be read/written on multiple threads. In tests we don't see that
134*6777b538SAndroid Build Coastguard Worker // causing a problem as updates tend to happen early. Atomic ensures there are
135*6777b538SAndroid Build Coastguard Worker // no problems. To avoid some of the overhead of Atomic, we use
136*6777b538SAndroid Build Coastguard Worker // |load(std::memory_order_acquire)| and |store(...,
137*6777b538SAndroid Build Coastguard Worker // std::memory_order_release)| when reading or writing. This guarantees that the
138*6777b538SAndroid Build Coastguard Worker // referenced object is available at the time the |g_vlog_info| is read and that
139*6777b538SAndroid Build Coastguard Worker // |g_vlog_info| is updated atomically.
140*6777b538SAndroid Build Coastguard Worker //
141*6777b538SAndroid Build Coastguard Worker // Do not access this directly. You must use |GetVlogInfo|, |InitializeVlogInfo|
142*6777b538SAndroid Build Coastguard Worker // and/or |ExchangeVlogInfo|.
143*6777b538SAndroid Build Coastguard Worker std::atomic<VlogInfo*> g_vlog_info = nullptr;
144*6777b538SAndroid Build Coastguard Worker
GetVlogInfo()145*6777b538SAndroid Build Coastguard Worker VlogInfo* GetVlogInfo() {
146*6777b538SAndroid Build Coastguard Worker return g_vlog_info.load(std::memory_order_acquire);
147*6777b538SAndroid Build Coastguard Worker }
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker // Sets g_vlog_info if it is not already set. Checking that it's not already set
150*6777b538SAndroid Build Coastguard Worker // prevents logging initialization (which can come late in test setup) from
151*6777b538SAndroid Build Coastguard Worker // overwriting values set via ScopedVmoduleSwitches.
InitializeVlogInfo(VlogInfo * vlog_info)152*6777b538SAndroid Build Coastguard Worker bool InitializeVlogInfo(VlogInfo* vlog_info) {
153*6777b538SAndroid Build Coastguard Worker VlogInfo* previous_vlog_info = nullptr;
154*6777b538SAndroid Build Coastguard Worker return g_vlog_info.compare_exchange_strong(previous_vlog_info, vlog_info);
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker
ExchangeVlogInfo(VlogInfo * vlog_info)157*6777b538SAndroid Build Coastguard Worker VlogInfo* ExchangeVlogInfo(VlogInfo* vlog_info) {
158*6777b538SAndroid Build Coastguard Worker return g_vlog_info.exchange(vlog_info);
159*6777b538SAndroid Build Coastguard Worker }
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker // Creates a VlogInfo from the commandline if it has been initialized and if it
162*6777b538SAndroid Build Coastguard Worker // contains relevant switches, otherwise this returns |nullptr|.
VlogInfoFromCommandLine()163*6777b538SAndroid Build Coastguard Worker std::unique_ptr<VlogInfo> VlogInfoFromCommandLine() {
164*6777b538SAndroid Build Coastguard Worker if (!base::CommandLine::InitializedForCurrentProcess())
165*6777b538SAndroid Build Coastguard Worker return nullptr;
166*6777b538SAndroid Build Coastguard Worker base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
167*6777b538SAndroid Build Coastguard Worker if (!command_line->HasSwitch(switches::kV) &&
168*6777b538SAndroid Build Coastguard Worker !command_line->HasSwitch(switches::kVModule)) {
169*6777b538SAndroid Build Coastguard Worker return nullptr;
170*6777b538SAndroid Build Coastguard Worker }
171*6777b538SAndroid Build Coastguard Worker #if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
172*6777b538SAndroid Build Coastguard Worker // See comments on |g_vlog_info|.
173*6777b538SAndroid Build Coastguard Worker ScopedLeakSanitizerDisabler lsan_disabler;
174*6777b538SAndroid Build Coastguard Worker #endif // defined(LEAK_SANITIZER)
175*6777b538SAndroid Build Coastguard Worker return std::make_unique<VlogInfo>(
176*6777b538SAndroid Build Coastguard Worker command_line->GetSwitchValueASCII(switches::kV),
177*6777b538SAndroid Build Coastguard Worker command_line->GetSwitchValueASCII(switches::kVModule), &g_min_log_level);
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker
180*6777b538SAndroid Build Coastguard Worker // If the commandline is initialized for the current process this will
181*6777b538SAndroid Build Coastguard Worker // initialize g_vlog_info. If there are no VLOG switches, it will initialize it
182*6777b538SAndroid Build Coastguard Worker // to |nullptr|.
MaybeInitializeVlogInfo()183*6777b538SAndroid Build Coastguard Worker void MaybeInitializeVlogInfo() {
184*6777b538SAndroid Build Coastguard Worker if (base::CommandLine::InitializedForCurrentProcess()) {
185*6777b538SAndroid Build Coastguard Worker std::unique_ptr<VlogInfo> vlog_info = VlogInfoFromCommandLine();
186*6777b538SAndroid Build Coastguard Worker if (vlog_info) {
187*6777b538SAndroid Build Coastguard Worker // VlogInfoFromCommandLine is annotated with ScopedLeakSanitizerDisabler
188*6777b538SAndroid Build Coastguard Worker // so it's allowed to leak. If the object was installed, we release it.
189*6777b538SAndroid Build Coastguard Worker if (InitializeVlogInfo(vlog_info.get())) {
190*6777b538SAndroid Build Coastguard Worker vlog_info.release();
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker }
193*6777b538SAndroid Build Coastguard Worker }
194*6777b538SAndroid Build Coastguard Worker }
195*6777b538SAndroid Build Coastguard Worker
196*6777b538SAndroid Build Coastguard Worker const char* const log_severity_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
197*6777b538SAndroid Build Coastguard Worker static_assert(LOGGING_NUM_SEVERITIES == std::size(log_severity_names),
198*6777b538SAndroid Build Coastguard Worker "Incorrect number of log_severity_names");
199*6777b538SAndroid Build Coastguard Worker
log_severity_name(int severity)200*6777b538SAndroid Build Coastguard Worker const char* log_severity_name(int severity) {
201*6777b538SAndroid Build Coastguard Worker if (severity >= 0 && severity < LOGGING_NUM_SEVERITIES)
202*6777b538SAndroid Build Coastguard Worker return log_severity_names[severity];
203*6777b538SAndroid Build Coastguard Worker return "UNKNOWN";
204*6777b538SAndroid Build Coastguard Worker }
205*6777b538SAndroid Build Coastguard Worker
206*6777b538SAndroid Build Coastguard Worker // Specifies the process' logging sink(s), represented as a combination of
207*6777b538SAndroid Build Coastguard Worker // LoggingDestination values joined by bitwise OR.
208*6777b538SAndroid Build Coastguard Worker uint32_t g_logging_destination = LOG_DEFAULT;
209*6777b538SAndroid Build Coastguard Worker
210*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
211*6777b538SAndroid Build Coastguard Worker // Specifies the format of log header for chrome os.
212*6777b538SAndroid Build Coastguard Worker LogFormat g_log_format = LogFormat::LOG_FORMAT_SYSLOG;
213*6777b538SAndroid Build Coastguard Worker #endif
214*6777b538SAndroid Build Coastguard Worker
215*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
216*6777b538SAndroid Build Coastguard Worker // Retains system logging structures.
GetScopedFxLogger()217*6777b538SAndroid Build Coastguard Worker base::ScopedFxLogger& GetScopedFxLogger() {
218*6777b538SAndroid Build Coastguard Worker static base::NoDestructor<base::ScopedFxLogger> logger;
219*6777b538SAndroid Build Coastguard Worker return *logger;
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker #endif
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker // For LOGGING_ERROR and above, always print to stderr.
224*6777b538SAndroid Build Coastguard Worker const int kAlwaysPrintErrorLevel = LOGGING_ERROR;
225*6777b538SAndroid Build Coastguard Worker
226*6777b538SAndroid Build Coastguard Worker // Which log file to use? This is initialized by InitLogging or
227*6777b538SAndroid Build Coastguard Worker // will be lazily initialized to the default value when it is
228*6777b538SAndroid Build Coastguard Worker // first needed.
229*6777b538SAndroid Build Coastguard Worker using PathString = base::FilePath::StringType;
230*6777b538SAndroid Build Coastguard Worker PathString* g_log_file_name = nullptr;
231*6777b538SAndroid Build Coastguard Worker
232*6777b538SAndroid Build Coastguard Worker // This file is lazily opened and the handle may be nullptr
233*6777b538SAndroid Build Coastguard Worker FileHandle g_log_file = nullptr;
234*6777b538SAndroid Build Coastguard Worker
235*6777b538SAndroid Build Coastguard Worker // What should be prepended to each message?
236*6777b538SAndroid Build Coastguard Worker bool g_log_process_id = false;
237*6777b538SAndroid Build Coastguard Worker bool g_log_thread_id = false;
238*6777b538SAndroid Build Coastguard Worker bool g_log_timestamp = true;
239*6777b538SAndroid Build Coastguard Worker bool g_log_tickcount = false;
240*6777b538SAndroid Build Coastguard Worker const char* g_log_prefix = nullptr;
241*6777b538SAndroid Build Coastguard Worker
242*6777b538SAndroid Build Coastguard Worker // Should we pop up fatal debug messages in a dialog?
243*6777b538SAndroid Build Coastguard Worker bool show_error_dialogs = false;
244*6777b538SAndroid Build Coastguard Worker
245*6777b538SAndroid Build Coastguard Worker // An assert handler override specified by the client to be called instead of
246*6777b538SAndroid Build Coastguard Worker // the debug message dialog and process termination. Assert handlers are stored
247*6777b538SAndroid Build Coastguard Worker // in stack to allow overriding and restoring.
GetLogAssertHandlerStack()248*6777b538SAndroid Build Coastguard Worker base::stack<LogAssertHandlerFunction>& GetLogAssertHandlerStack() {
249*6777b538SAndroid Build Coastguard Worker static base::NoDestructor<base::stack<LogAssertHandlerFunction>> instance;
250*6777b538SAndroid Build Coastguard Worker return *instance;
251*6777b538SAndroid Build Coastguard Worker }
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker // A log message handler that gets notified of every log message we process.
254*6777b538SAndroid Build Coastguard Worker LogMessageHandlerFunction g_log_message_handler = nullptr;
255*6777b538SAndroid Build Coastguard Worker
TickCount()256*6777b538SAndroid Build Coastguard Worker uint64_t TickCount() {
257*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
258*6777b538SAndroid Build Coastguard Worker return GetTickCount();
259*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FUCHSIA)
260*6777b538SAndroid Build Coastguard Worker return static_cast<uint64_t>(
261*6777b538SAndroid Build Coastguard Worker zx_clock_get_monotonic() /
262*6777b538SAndroid Build Coastguard Worker static_cast<zx_time_t>(base::Time::kNanosecondsPerMicrosecond));
263*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE)
264*6777b538SAndroid Build Coastguard Worker return mach_absolute_time();
265*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_NACL)
266*6777b538SAndroid Build Coastguard Worker // NaCl sadly does not have _POSIX_TIMERS enabled in sys/features.h
267*6777b538SAndroid Build Coastguard Worker // So we have to use clock() for now.
268*6777b538SAndroid Build Coastguard Worker return clock();
269*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX)
270*6777b538SAndroid Build Coastguard Worker struct timespec ts;
271*6777b538SAndroid Build Coastguard Worker clock_gettime(CLOCK_MONOTONIC, &ts);
272*6777b538SAndroid Build Coastguard Worker
273*6777b538SAndroid Build Coastguard Worker uint64_t absolute_micro = static_cast<uint64_t>(ts.tv_sec) * 1000000 +
274*6777b538SAndroid Build Coastguard Worker static_cast<uint64_t>(ts.tv_nsec) / 1000;
275*6777b538SAndroid Build Coastguard Worker
276*6777b538SAndroid Build Coastguard Worker return absolute_micro;
277*6777b538SAndroid Build Coastguard Worker #endif
278*6777b538SAndroid Build Coastguard Worker }
279*6777b538SAndroid Build Coastguard Worker
DeleteFilePath(const PathString & log_name)280*6777b538SAndroid Build Coastguard Worker void DeleteFilePath(const PathString& log_name) {
281*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
282*6777b538SAndroid Build Coastguard Worker DeleteFile(log_name.c_str());
283*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_NACL)
284*6777b538SAndroid Build Coastguard Worker // Do nothing; unlink() isn't supported on NaCl.
285*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
286*6777b538SAndroid Build Coastguard Worker unlink(log_name.c_str());
287*6777b538SAndroid Build Coastguard Worker #else
288*6777b538SAndroid Build Coastguard Worker #error Unsupported platform
289*6777b538SAndroid Build Coastguard Worker #endif
290*6777b538SAndroid Build Coastguard Worker }
291*6777b538SAndroid Build Coastguard Worker
GetDefaultLogFile()292*6777b538SAndroid Build Coastguard Worker PathString GetDefaultLogFile() {
293*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
294*6777b538SAndroid Build Coastguard Worker // On Windows we use the same path as the exe.
295*6777b538SAndroid Build Coastguard Worker wchar_t module_name[MAX_PATH];
296*6777b538SAndroid Build Coastguard Worker GetModuleFileName(nullptr, module_name, MAX_PATH);
297*6777b538SAndroid Build Coastguard Worker
298*6777b538SAndroid Build Coastguard Worker PathString log_name = module_name;
299*6777b538SAndroid Build Coastguard Worker PathString::size_type last_backslash = log_name.rfind('\\', log_name.size());
300*6777b538SAndroid Build Coastguard Worker if (last_backslash != PathString::npos)
301*6777b538SAndroid Build Coastguard Worker log_name.erase(last_backslash + 1);
302*6777b538SAndroid Build Coastguard Worker log_name += FILE_PATH_LITERAL("debug.log");
303*6777b538SAndroid Build Coastguard Worker return log_name;
304*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
305*6777b538SAndroid Build Coastguard Worker // On other platforms we just use the current directory.
306*6777b538SAndroid Build Coastguard Worker return PathString("debug.log");
307*6777b538SAndroid Build Coastguard Worker #endif
308*6777b538SAndroid Build Coastguard Worker }
309*6777b538SAndroid Build Coastguard Worker
310*6777b538SAndroid Build Coastguard Worker // We don't need locks on Windows for atomically appending to files. The OS
311*6777b538SAndroid Build Coastguard Worker // provides this functionality.
312*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
313*6777b538SAndroid Build Coastguard Worker
314*6777b538SAndroid Build Coastguard Worker // Provides a lock to synchronize appending to the log file across
315*6777b538SAndroid Build Coastguard Worker // threads. This can be required to support NFS file systems even on OSes that
316*6777b538SAndroid Build Coastguard Worker // provide atomic append operations in most cases. It should be noted that this
317*6777b538SAndroid Build Coastguard Worker // lock is not not shared across processes. When using NFS filesystems
318*6777b538SAndroid Build Coastguard Worker // protection against clobbering between different processes will be best-effort
319*6777b538SAndroid Build Coastguard Worker // and provided by the OS. See
320*6777b538SAndroid Build Coastguard Worker // https://man7.org/linux/man-pages/man2/open.2.html.
321*6777b538SAndroid Build Coastguard Worker //
322*6777b538SAndroid Build Coastguard Worker // The lock also protects initializing and closing the log file which can
323*6777b538SAndroid Build Coastguard Worker // happen concurrently with logging on some platforms like ChromeOS that need to
324*6777b538SAndroid Build Coastguard Worker // redirect logging by calling BaseInitLoggingImpl() twice.
GetLoggingLock()325*6777b538SAndroid Build Coastguard Worker base::Lock& GetLoggingLock() {
326*6777b538SAndroid Build Coastguard Worker static base::NoDestructor<base::Lock> lock;
327*6777b538SAndroid Build Coastguard Worker return *lock;
328*6777b538SAndroid Build Coastguard Worker }
329*6777b538SAndroid Build Coastguard Worker
330*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
331*6777b538SAndroid Build Coastguard Worker
332*6777b538SAndroid Build Coastguard Worker // Called by logging functions to ensure that |g_log_file| is initialized
333*6777b538SAndroid Build Coastguard Worker // and can be used for writing. Returns false if the file could not be
334*6777b538SAndroid Build Coastguard Worker // initialized. |g_log_file| will be nullptr in this case.
InitializeLogFileHandle()335*6777b538SAndroid Build Coastguard Worker bool InitializeLogFileHandle() {
336*6777b538SAndroid Build Coastguard Worker if (g_log_file)
337*6777b538SAndroid Build Coastguard Worker return true;
338*6777b538SAndroid Build Coastguard Worker
339*6777b538SAndroid Build Coastguard Worker if (!g_log_file_name) {
340*6777b538SAndroid Build Coastguard Worker // Nobody has called InitLogging to specify a debug log file, so here we
341*6777b538SAndroid Build Coastguard Worker // initialize the log file name to a default.
342*6777b538SAndroid Build Coastguard Worker g_log_file_name = new PathString(GetDefaultLogFile());
343*6777b538SAndroid Build Coastguard Worker }
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker if ((g_logging_destination & LOG_TO_FILE) == 0)
346*6777b538SAndroid Build Coastguard Worker return true;
347*6777b538SAndroid Build Coastguard Worker
348*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
349*6777b538SAndroid Build Coastguard Worker // The FILE_APPEND_DATA access mask ensures that the file is atomically
350*6777b538SAndroid Build Coastguard Worker // appended to across accesses from multiple threads.
351*6777b538SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364399(v=vs.85).aspx
352*6777b538SAndroid Build Coastguard Worker // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
353*6777b538SAndroid Build Coastguard Worker g_log_file = CreateFile(g_log_file_name->c_str(), FILE_APPEND_DATA,
354*6777b538SAndroid Build Coastguard Worker FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
355*6777b538SAndroid Build Coastguard Worker OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
356*6777b538SAndroid Build Coastguard Worker if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == nullptr) {
357*6777b538SAndroid Build Coastguard Worker // We are intentionally not using FilePath or FileUtil here to reduce the
358*6777b538SAndroid Build Coastguard Worker // dependencies of the logging implementation. For e.g. FilePath and
359*6777b538SAndroid Build Coastguard Worker // FileUtil depend on shell32 and user32.dll. This is not acceptable for
360*6777b538SAndroid Build Coastguard Worker // some consumers of base logging like chrome_elf, etc.
361*6777b538SAndroid Build Coastguard Worker // Please don't change the code below to use FilePath.
362*6777b538SAndroid Build Coastguard Worker // try the current directory
363*6777b538SAndroid Build Coastguard Worker wchar_t system_buffer[MAX_PATH];
364*6777b538SAndroid Build Coastguard Worker system_buffer[0] = 0;
365*6777b538SAndroid Build Coastguard Worker DWORD len = ::GetCurrentDirectory(std::size(system_buffer), system_buffer);
366*6777b538SAndroid Build Coastguard Worker if (len == 0 || len > std::size(system_buffer))
367*6777b538SAndroid Build Coastguard Worker return false;
368*6777b538SAndroid Build Coastguard Worker
369*6777b538SAndroid Build Coastguard Worker *g_log_file_name = system_buffer;
370*6777b538SAndroid Build Coastguard Worker // Append a trailing backslash if needed.
371*6777b538SAndroid Build Coastguard Worker if (g_log_file_name->back() != L'\\')
372*6777b538SAndroid Build Coastguard Worker *g_log_file_name += FILE_PATH_LITERAL("\\");
373*6777b538SAndroid Build Coastguard Worker *g_log_file_name += FILE_PATH_LITERAL("debug.log");
374*6777b538SAndroid Build Coastguard Worker
375*6777b538SAndroid Build Coastguard Worker g_log_file = CreateFile(g_log_file_name->c_str(), FILE_APPEND_DATA,
376*6777b538SAndroid Build Coastguard Worker FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr,
377*6777b538SAndroid Build Coastguard Worker OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
378*6777b538SAndroid Build Coastguard Worker if (g_log_file == INVALID_HANDLE_VALUE || g_log_file == nullptr) {
379*6777b538SAndroid Build Coastguard Worker g_log_file = nullptr;
380*6777b538SAndroid Build Coastguard Worker return false;
381*6777b538SAndroid Build Coastguard Worker }
382*6777b538SAndroid Build Coastguard Worker }
383*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
384*6777b538SAndroid Build Coastguard Worker g_log_file = fopen(g_log_file_name->c_str(), "a");
385*6777b538SAndroid Build Coastguard Worker if (g_log_file == nullptr)
386*6777b538SAndroid Build Coastguard Worker return false;
387*6777b538SAndroid Build Coastguard Worker #else
388*6777b538SAndroid Build Coastguard Worker #error Unsupported platform
389*6777b538SAndroid Build Coastguard Worker #endif
390*6777b538SAndroid Build Coastguard Worker
391*6777b538SAndroid Build Coastguard Worker return true;
392*6777b538SAndroid Build Coastguard Worker }
393*6777b538SAndroid Build Coastguard Worker
CloseFile(FileHandle log)394*6777b538SAndroid Build Coastguard Worker void CloseFile(FileHandle log) {
395*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
396*6777b538SAndroid Build Coastguard Worker CloseHandle(log);
397*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
398*6777b538SAndroid Build Coastguard Worker fclose(log);
399*6777b538SAndroid Build Coastguard Worker #else
400*6777b538SAndroid Build Coastguard Worker #error Unsupported platform
401*6777b538SAndroid Build Coastguard Worker #endif
402*6777b538SAndroid Build Coastguard Worker }
403*6777b538SAndroid Build Coastguard Worker
CloseLogFileUnlocked()404*6777b538SAndroid Build Coastguard Worker void CloseLogFileUnlocked() {
405*6777b538SAndroid Build Coastguard Worker if (!g_log_file)
406*6777b538SAndroid Build Coastguard Worker return;
407*6777b538SAndroid Build Coastguard Worker
408*6777b538SAndroid Build Coastguard Worker CloseFile(g_log_file);
409*6777b538SAndroid Build Coastguard Worker g_log_file = nullptr;
410*6777b538SAndroid Build Coastguard Worker
411*6777b538SAndroid Build Coastguard Worker // If we initialized logging via an externally-provided file descriptor, we
412*6777b538SAndroid Build Coastguard Worker // won't have a log path set and shouldn't try to reopen the log file.
413*6777b538SAndroid Build Coastguard Worker if (!g_log_file_name)
414*6777b538SAndroid Build Coastguard Worker g_logging_destination &= ~LOG_TO_FILE;
415*6777b538SAndroid Build Coastguard Worker }
416*6777b538SAndroid Build Coastguard Worker
417*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
LogSeverityToFuchsiaLogSeverity(LogSeverity severity)418*6777b538SAndroid Build Coastguard Worker inline FuchsiaLogSeverity LogSeverityToFuchsiaLogSeverity(
419*6777b538SAndroid Build Coastguard Worker LogSeverity severity) {
420*6777b538SAndroid Build Coastguard Worker switch (severity) {
421*6777b538SAndroid Build Coastguard Worker case LOGGING_INFO:
422*6777b538SAndroid Build Coastguard Worker return FUCHSIA_LOG_INFO;
423*6777b538SAndroid Build Coastguard Worker case LOGGING_WARNING:
424*6777b538SAndroid Build Coastguard Worker return FUCHSIA_LOG_WARNING;
425*6777b538SAndroid Build Coastguard Worker case LOGGING_ERROR:
426*6777b538SAndroid Build Coastguard Worker return FUCHSIA_LOG_ERROR;
427*6777b538SAndroid Build Coastguard Worker case LOGGING_FATAL:
428*6777b538SAndroid Build Coastguard Worker // Don't use FX_LOG_FATAL, otherwise fx_logger_log() will abort().
429*6777b538SAndroid Build Coastguard Worker return FUCHSIA_LOG_ERROR;
430*6777b538SAndroid Build Coastguard Worker }
431*6777b538SAndroid Build Coastguard Worker if (severity > -3) {
432*6777b538SAndroid Build Coastguard Worker // LOGGING_VERBOSE levels 1 and 2.
433*6777b538SAndroid Build Coastguard Worker return FUCHSIA_LOG_DEBUG;
434*6777b538SAndroid Build Coastguard Worker }
435*6777b538SAndroid Build Coastguard Worker // LOGGING_VERBOSE levels 3 and higher, or incorrect levels.
436*6777b538SAndroid Build Coastguard Worker return FUCHSIA_LOG_TRACE;
437*6777b538SAndroid Build Coastguard Worker }
438*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_FUCHSIA)
439*6777b538SAndroid Build Coastguard Worker
WriteToFd(int fd,const char * data,size_t length)440*6777b538SAndroid Build Coastguard Worker void WriteToFd(int fd, const char* data, size_t length) {
441*6777b538SAndroid Build Coastguard Worker size_t bytes_written = 0;
442*6777b538SAndroid Build Coastguard Worker long rv;
443*6777b538SAndroid Build Coastguard Worker while (bytes_written < length) {
444*6777b538SAndroid Build Coastguard Worker rv = HANDLE_EINTR(write(fd, data + bytes_written, length - bytes_written));
445*6777b538SAndroid Build Coastguard Worker if (rv < 0) {
446*6777b538SAndroid Build Coastguard Worker // Give up, nothing we can do now.
447*6777b538SAndroid Build Coastguard Worker break;
448*6777b538SAndroid Build Coastguard Worker }
449*6777b538SAndroid Build Coastguard Worker bytes_written += static_cast<size_t>(rv);
450*6777b538SAndroid Build Coastguard Worker }
451*6777b538SAndroid Build Coastguard Worker }
452*6777b538SAndroid Build Coastguard Worker
SetLogFatalCrashKey(LogMessage * log_message)453*6777b538SAndroid Build Coastguard Worker void SetLogFatalCrashKey(LogMessage* log_message) {
454*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(IS_NACL)
455*6777b538SAndroid Build Coastguard Worker // In case of an out-of-memory condition, this code could be reentered when
456*6777b538SAndroid Build Coastguard Worker // constructing and storing the key. Using a static is not thread-safe, but if
457*6777b538SAndroid Build Coastguard Worker // multiple threads are in the process of a fatal crash at the same time, this
458*6777b538SAndroid Build Coastguard Worker // should work.
459*6777b538SAndroid Build Coastguard Worker static bool guarded = false;
460*6777b538SAndroid Build Coastguard Worker if (guarded)
461*6777b538SAndroid Build Coastguard Worker return;
462*6777b538SAndroid Build Coastguard Worker
463*6777b538SAndroid Build Coastguard Worker base::AutoReset<bool> guard(&guarded, true);
464*6777b538SAndroid Build Coastguard Worker
465*6777b538SAndroid Build Coastguard Worker // Note that we intentionally use LOG_FATAL here (old name for LOGGING_FATAL)
466*6777b538SAndroid Build Coastguard Worker // as that's understood and used by the crash backend.
467*6777b538SAndroid Build Coastguard Worker static auto* const crash_key = base::debug::AllocateCrashKeyString(
468*6777b538SAndroid Build Coastguard Worker "LOG_FATAL", base::debug::CrashKeySize::Size1024);
469*6777b538SAndroid Build Coastguard Worker base::debug::SetCrashKeyString(crash_key, log_message->BuildCrashString());
470*6777b538SAndroid Build Coastguard Worker
471*6777b538SAndroid Build Coastguard Worker #endif // !BUILDFLAG(IS_NACL)
472*6777b538SAndroid Build Coastguard Worker }
473*6777b538SAndroid Build Coastguard Worker
BuildCrashString(const char * file,int line,const char * message_without_prefix)474*6777b538SAndroid Build Coastguard Worker std::string BuildCrashString(const char* file,
475*6777b538SAndroid Build Coastguard Worker int line,
476*6777b538SAndroid Build Coastguard Worker const char* message_without_prefix) {
477*6777b538SAndroid Build Coastguard Worker // Only log last path component.
478*6777b538SAndroid Build Coastguard Worker if (file) {
479*6777b538SAndroid Build Coastguard Worker const char* slash = strrchr(file,
480*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
481*6777b538SAndroid Build Coastguard Worker '\\'
482*6777b538SAndroid Build Coastguard Worker #else
483*6777b538SAndroid Build Coastguard Worker '/'
484*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
485*6777b538SAndroid Build Coastguard Worker );
486*6777b538SAndroid Build Coastguard Worker if (slash) {
487*6777b538SAndroid Build Coastguard Worker file = slash + 1;
488*6777b538SAndroid Build Coastguard Worker }
489*6777b538SAndroid Build Coastguard Worker }
490*6777b538SAndroid Build Coastguard Worker
491*6777b538SAndroid Build Coastguard Worker return base::StringPrintf("%s:%d: %s", file, line, message_without_prefix);
492*6777b538SAndroid Build Coastguard Worker }
493*6777b538SAndroid Build Coastguard Worker
494*6777b538SAndroid Build Coastguard Worker // Invokes macro to record trace event when a log message is emitted.
TraceLogMessage(const char * file,int line,const std::string & message)495*6777b538SAndroid Build Coastguard Worker void TraceLogMessage(const char* file, int line, const std::string& message) {
496*6777b538SAndroid Build Coastguard Worker TRACE_EVENT_INSTANT("log", "LogMessage", [&](perfetto::EventContext ctx) {
497*6777b538SAndroid Build Coastguard Worker perfetto::protos::pbzero::LogMessage* log = ctx.event()->set_log_message();
498*6777b538SAndroid Build Coastguard Worker log->set_source_location_iid(base::trace_event::InternedSourceLocation::Get(
499*6777b538SAndroid Build Coastguard Worker &ctx, base::trace_event::TraceSourceLocation(/*function_name=*/nullptr,
500*6777b538SAndroid Build Coastguard Worker file, line)));
501*6777b538SAndroid Build Coastguard Worker log->set_body_iid(
502*6777b538SAndroid Build Coastguard Worker base::trace_event::InternedLogMessage::Get(&ctx, message));
503*6777b538SAndroid Build Coastguard Worker });
504*6777b538SAndroid Build Coastguard Worker }
505*6777b538SAndroid Build Coastguard Worker
506*6777b538SAndroid Build Coastguard Worker } // namespace
507*6777b538SAndroid Build Coastguard Worker
508*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(DCHECK_IS_CONFIGURABLE)
509*6777b538SAndroid Build Coastguard Worker // In DCHECK-enabled Chrome builds, allow the meaning of LOGGING_DCHECK to be
510*6777b538SAndroid Build Coastguard Worker // determined at run-time. We default it to ERROR, to avoid it triggering
511*6777b538SAndroid Build Coastguard Worker // crashes before the run-time has explicitly chosen the behaviour.
512*6777b538SAndroid Build Coastguard Worker BASE_EXPORT logging::LogSeverity LOGGING_DCHECK = LOGGING_ERROR;
513*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(DCHECK_IS_CONFIGURABLE)
514*6777b538SAndroid Build Coastguard Worker
515*6777b538SAndroid Build Coastguard Worker // This is never instantiated, it's just used for EAT_STREAM_PARAMETERS to have
516*6777b538SAndroid Build Coastguard Worker // an object of the correct type on the LHS of the unused part of the ternary
517*6777b538SAndroid Build Coastguard Worker // operator.
518*6777b538SAndroid Build Coastguard Worker std::ostream* g_swallow_stream;
519*6777b538SAndroid Build Coastguard Worker
BaseInitLoggingImpl(const LoggingSettings & settings)520*6777b538SAndroid Build Coastguard Worker bool BaseInitLoggingImpl(const LoggingSettings& settings) {
521*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_NACL)
522*6777b538SAndroid Build Coastguard Worker // Can log only to the system debug log and stderr.
523*6777b538SAndroid Build Coastguard Worker CHECK_EQ(settings.logging_dest & ~(LOG_TO_SYSTEM_DEBUG_LOG | LOG_TO_STDERR),
524*6777b538SAndroid Build Coastguard Worker 0u);
525*6777b538SAndroid Build Coastguard Worker #endif
526*6777b538SAndroid Build Coastguard Worker
527*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
528*6777b538SAndroid Build Coastguard Worker g_log_format = settings.log_format;
529*6777b538SAndroid Build Coastguard Worker #endif
530*6777b538SAndroid Build Coastguard Worker
531*6777b538SAndroid Build Coastguard Worker MaybeInitializeVlogInfo();
532*6777b538SAndroid Build Coastguard Worker
533*6777b538SAndroid Build Coastguard Worker g_logging_destination = settings.logging_dest;
534*6777b538SAndroid Build Coastguard Worker
535*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
536*6777b538SAndroid Build Coastguard Worker if (g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) {
537*6777b538SAndroid Build Coastguard Worker GetScopedFxLogger() = base::ScopedFxLogger::CreateForProcess();
538*6777b538SAndroid Build Coastguard Worker }
539*6777b538SAndroid Build Coastguard Worker #endif
540*6777b538SAndroid Build Coastguard Worker
541*6777b538SAndroid Build Coastguard Worker // Ignore file options unless logging to file is set.
542*6777b538SAndroid Build Coastguard Worker if ((g_logging_destination & LOG_TO_FILE) == 0)
543*6777b538SAndroid Build Coastguard Worker return true;
544*6777b538SAndroid Build Coastguard Worker
545*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
546*6777b538SAndroid Build Coastguard Worker base::AutoLock guard(GetLoggingLock());
547*6777b538SAndroid Build Coastguard Worker #endif
548*6777b538SAndroid Build Coastguard Worker
549*6777b538SAndroid Build Coastguard Worker // Calling InitLogging twice or after some log call has already opened the
550*6777b538SAndroid Build Coastguard Worker // default log file will re-initialize to the new options.
551*6777b538SAndroid Build Coastguard Worker CloseLogFileUnlocked();
552*6777b538SAndroid Build Coastguard Worker
553*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_WIN)
554*6777b538SAndroid Build Coastguard Worker if (settings.log_file) {
555*6777b538SAndroid Build Coastguard Worker CHECK(settings.log_file_path.empty(), base::NotFatalUntil::M127);
556*6777b538SAndroid Build Coastguard Worker g_log_file = settings.log_file;
557*6777b538SAndroid Build Coastguard Worker return true;
558*6777b538SAndroid Build Coastguard Worker }
559*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_WIN)
560*6777b538SAndroid Build Coastguard Worker
561*6777b538SAndroid Build Coastguard Worker CHECK(!settings.log_file_path.empty(), base::NotFatalUntil::M127)
562*6777b538SAndroid Build Coastguard Worker << "LOG_TO_FILE set but no log_file_path!";
563*6777b538SAndroid Build Coastguard Worker
564*6777b538SAndroid Build Coastguard Worker if (!g_log_file_name)
565*6777b538SAndroid Build Coastguard Worker g_log_file_name = new PathString();
566*6777b538SAndroid Build Coastguard Worker *g_log_file_name = settings.log_file_path;
567*6777b538SAndroid Build Coastguard Worker if (settings.delete_old == DELETE_OLD_LOG_FILE)
568*6777b538SAndroid Build Coastguard Worker DeleteFilePath(*g_log_file_name);
569*6777b538SAndroid Build Coastguard Worker
570*6777b538SAndroid Build Coastguard Worker return InitializeLogFileHandle();
571*6777b538SAndroid Build Coastguard Worker }
572*6777b538SAndroid Build Coastguard Worker
SetMinLogLevel(int level)573*6777b538SAndroid Build Coastguard Worker void SetMinLogLevel(int level) {
574*6777b538SAndroid Build Coastguard Worker g_min_log_level = std::min(LOGGING_FATAL, level);
575*6777b538SAndroid Build Coastguard Worker }
576*6777b538SAndroid Build Coastguard Worker
GetMinLogLevel()577*6777b538SAndroid Build Coastguard Worker int GetMinLogLevel() {
578*6777b538SAndroid Build Coastguard Worker return g_min_log_level;
579*6777b538SAndroid Build Coastguard Worker }
580*6777b538SAndroid Build Coastguard Worker
ShouldCreateLogMessage(int severity)581*6777b538SAndroid Build Coastguard Worker bool ShouldCreateLogMessage(int severity) {
582*6777b538SAndroid Build Coastguard Worker if (severity < g_min_log_level)
583*6777b538SAndroid Build Coastguard Worker return false;
584*6777b538SAndroid Build Coastguard Worker
585*6777b538SAndroid Build Coastguard Worker // Return true here unless we know ~LogMessage won't do anything.
586*6777b538SAndroid Build Coastguard Worker return g_logging_destination != LOG_NONE || g_log_message_handler ||
587*6777b538SAndroid Build Coastguard Worker severity >= kAlwaysPrintErrorLevel;
588*6777b538SAndroid Build Coastguard Worker }
589*6777b538SAndroid Build Coastguard Worker
590*6777b538SAndroid Build Coastguard Worker // Returns true when LOG_TO_STDERR flag is set, or |severity| is high.
591*6777b538SAndroid Build Coastguard Worker // If |severity| is high then true will be returned when no log destinations are
592*6777b538SAndroid Build Coastguard Worker // set, or only LOG_TO_FILE is set, since that is useful for local development
593*6777b538SAndroid Build Coastguard Worker // and debugging.
ShouldLogToStderr(int severity)594*6777b538SAndroid Build Coastguard Worker bool ShouldLogToStderr(int severity) {
595*6777b538SAndroid Build Coastguard Worker if (g_logging_destination & LOG_TO_STDERR)
596*6777b538SAndroid Build Coastguard Worker return true;
597*6777b538SAndroid Build Coastguard Worker
598*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_FUCHSIA)
599*6777b538SAndroid Build Coastguard Worker // Fuchsia will persist data logged to stdio by a component, so do not emit
600*6777b538SAndroid Build Coastguard Worker // logs to stderr unless explicitly configured to do so.
601*6777b538SAndroid Build Coastguard Worker return false;
602*6777b538SAndroid Build Coastguard Worker #else
603*6777b538SAndroid Build Coastguard Worker if (severity >= kAlwaysPrintErrorLevel)
604*6777b538SAndroid Build Coastguard Worker return (g_logging_destination & ~LOG_TO_FILE) == LOG_NONE;
605*6777b538SAndroid Build Coastguard Worker return false;
606*6777b538SAndroid Build Coastguard Worker #endif
607*6777b538SAndroid Build Coastguard Worker }
608*6777b538SAndroid Build Coastguard Worker
GetVlogVerbosity()609*6777b538SAndroid Build Coastguard Worker int GetVlogVerbosity() {
610*6777b538SAndroid Build Coastguard Worker return std::max(-1, LOGGING_INFO - GetMinLogLevel());
611*6777b538SAndroid Build Coastguard Worker }
612*6777b538SAndroid Build Coastguard Worker
GetVlogLevelHelper(const char * file,size_t N)613*6777b538SAndroid Build Coastguard Worker int GetVlogLevelHelper(const char* file, size_t N) {
614*6777b538SAndroid Build Coastguard Worker DCHECK_GT(N, 0U);
615*6777b538SAndroid Build Coastguard Worker
616*6777b538SAndroid Build Coastguard Worker // Note: |g_vlog_info| may change on a different thread during startup
617*6777b538SAndroid Build Coastguard Worker // (but will always be valid or nullptr).
618*6777b538SAndroid Build Coastguard Worker VlogInfo* vlog_info = GetVlogInfo();
619*6777b538SAndroid Build Coastguard Worker return vlog_info ?
620*6777b538SAndroid Build Coastguard Worker vlog_info->GetVlogLevel(base::StringPiece(file, N - 1)) :
621*6777b538SAndroid Build Coastguard Worker GetVlogVerbosity();
622*6777b538SAndroid Build Coastguard Worker }
623*6777b538SAndroid Build Coastguard Worker
SetLogItems(bool enable_process_id,bool enable_thread_id,bool enable_timestamp,bool enable_tickcount)624*6777b538SAndroid Build Coastguard Worker void SetLogItems(bool enable_process_id, bool enable_thread_id,
625*6777b538SAndroid Build Coastguard Worker bool enable_timestamp, bool enable_tickcount) {
626*6777b538SAndroid Build Coastguard Worker g_log_process_id = enable_process_id;
627*6777b538SAndroid Build Coastguard Worker g_log_thread_id = enable_thread_id;
628*6777b538SAndroid Build Coastguard Worker g_log_timestamp = enable_timestamp;
629*6777b538SAndroid Build Coastguard Worker g_log_tickcount = enable_tickcount;
630*6777b538SAndroid Build Coastguard Worker }
631*6777b538SAndroid Build Coastguard Worker
SetLogPrefix(const char * prefix)632*6777b538SAndroid Build Coastguard Worker void SetLogPrefix(const char* prefix) {
633*6777b538SAndroid Build Coastguard Worker DCHECK(!prefix ||
634*6777b538SAndroid Build Coastguard Worker base::ContainsOnlyChars(prefix, "abcdefghijklmnopqrstuvwxyz"));
635*6777b538SAndroid Build Coastguard Worker g_log_prefix = prefix;
636*6777b538SAndroid Build Coastguard Worker }
637*6777b538SAndroid Build Coastguard Worker
SetShowErrorDialogs(bool enable_dialogs)638*6777b538SAndroid Build Coastguard Worker void SetShowErrorDialogs(bool enable_dialogs) {
639*6777b538SAndroid Build Coastguard Worker show_error_dialogs = enable_dialogs;
640*6777b538SAndroid Build Coastguard Worker }
641*6777b538SAndroid Build Coastguard Worker
ScopedLogAssertHandler(LogAssertHandlerFunction handler)642*6777b538SAndroid Build Coastguard Worker ScopedLogAssertHandler::ScopedLogAssertHandler(
643*6777b538SAndroid Build Coastguard Worker LogAssertHandlerFunction handler) {
644*6777b538SAndroid Build Coastguard Worker GetLogAssertHandlerStack().push(std::move(handler));
645*6777b538SAndroid Build Coastguard Worker }
646*6777b538SAndroid Build Coastguard Worker
~ScopedLogAssertHandler()647*6777b538SAndroid Build Coastguard Worker ScopedLogAssertHandler::~ScopedLogAssertHandler() {
648*6777b538SAndroid Build Coastguard Worker GetLogAssertHandlerStack().pop();
649*6777b538SAndroid Build Coastguard Worker }
650*6777b538SAndroid Build Coastguard Worker
SetLogMessageHandler(LogMessageHandlerFunction handler)651*6777b538SAndroid Build Coastguard Worker void SetLogMessageHandler(LogMessageHandlerFunction handler) {
652*6777b538SAndroid Build Coastguard Worker g_log_message_handler = handler;
653*6777b538SAndroid Build Coastguard Worker }
654*6777b538SAndroid Build Coastguard Worker
GetLogMessageHandler()655*6777b538SAndroid Build Coastguard Worker LogMessageHandlerFunction GetLogMessageHandler() {
656*6777b538SAndroid Build Coastguard Worker return g_log_message_handler;
657*6777b538SAndroid Build Coastguard Worker }
658*6777b538SAndroid Build Coastguard Worker
659*6777b538SAndroid Build Coastguard Worker #if !defined(NDEBUG)
660*6777b538SAndroid Build Coastguard Worker // Displays a message box to the user with the error message in it.
661*6777b538SAndroid Build Coastguard Worker // Used for fatal messages, where we close the app simultaneously.
662*6777b538SAndroid Build Coastguard Worker // This is for developers only; we don't use this in circumstances
663*6777b538SAndroid Build Coastguard Worker // (like release builds) where users could see it, since users don't
664*6777b538SAndroid Build Coastguard Worker // understand these messages anyway.
DisplayDebugMessageInDialog(const std::string & str)665*6777b538SAndroid Build Coastguard Worker void DisplayDebugMessageInDialog(const std::string& str) {
666*6777b538SAndroid Build Coastguard Worker if (str.empty())
667*6777b538SAndroid Build Coastguard Worker return;
668*6777b538SAndroid Build Coastguard Worker
669*6777b538SAndroid Build Coastguard Worker if (!show_error_dialogs)
670*6777b538SAndroid Build Coastguard Worker return;
671*6777b538SAndroid Build Coastguard Worker
672*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
673*6777b538SAndroid Build Coastguard Worker // We intentionally don't implement a dialog on other platforms.
674*6777b538SAndroid Build Coastguard Worker // You can just look at stderr.
675*6777b538SAndroid Build Coastguard Worker if (base::win::IsUser32AndGdi32Available()) {
676*6777b538SAndroid Build Coastguard Worker MessageBoxW(nullptr, base::as_wcstr(base::UTF8ToUTF16(str)), L"Fatal error",
677*6777b538SAndroid Build Coastguard Worker MB_OK | MB_ICONHAND | MB_TOPMOST);
678*6777b538SAndroid Build Coastguard Worker } else {
679*6777b538SAndroid Build Coastguard Worker OutputDebugStringW(base::as_wcstr(base::UTF8ToUTF16(str)));
680*6777b538SAndroid Build Coastguard Worker }
681*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
682*6777b538SAndroid Build Coastguard Worker }
683*6777b538SAndroid Build Coastguard Worker #endif // !defined(NDEBUG)
684*6777b538SAndroid Build Coastguard Worker
LogMessage(const char * file,int line,LogSeverity severity)685*6777b538SAndroid Build Coastguard Worker LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
686*6777b538SAndroid Build Coastguard Worker : severity_(severity), file_(file), line_(line) {
687*6777b538SAndroid Build Coastguard Worker Init(file, line);
688*6777b538SAndroid Build Coastguard Worker }
689*6777b538SAndroid Build Coastguard Worker
LogMessage(const char * file,int line,const char * condition)690*6777b538SAndroid Build Coastguard Worker LogMessage::LogMessage(const char* file, int line, const char* condition)
691*6777b538SAndroid Build Coastguard Worker : severity_(LOGGING_FATAL), file_(file), line_(line) {
692*6777b538SAndroid Build Coastguard Worker Init(file, line);
693*6777b538SAndroid Build Coastguard Worker stream_ << "Check failed: " << condition << ". ";
694*6777b538SAndroid Build Coastguard Worker }
695*6777b538SAndroid Build Coastguard Worker
~LogMessage()696*6777b538SAndroid Build Coastguard Worker LogMessage::~LogMessage() {
697*6777b538SAndroid Build Coastguard Worker Flush();
698*6777b538SAndroid Build Coastguard Worker }
699*6777b538SAndroid Build Coastguard Worker
Flush()700*6777b538SAndroid Build Coastguard Worker void LogMessage::Flush() {
701*6777b538SAndroid Build Coastguard Worker size_t stack_start = stream_.str().length();
702*6777b538SAndroid Build Coastguard Worker #if !defined(OFFICIAL_BUILD) && !BUILDFLAG(IS_NACL) && !defined(__UCLIBC__) && \
703*6777b538SAndroid Build Coastguard Worker !BUILDFLAG(IS_AIX)
704*6777b538SAndroid Build Coastguard Worker // Include a stack trace on a fatal, unless a debugger is attached.
705*6777b538SAndroid Build Coastguard Worker if (severity_ == LOGGING_FATAL && !base::debug::BeingDebugged()) {
706*6777b538SAndroid Build Coastguard Worker base::debug::StackTrace stack_trace;
707*6777b538SAndroid Build Coastguard Worker stream_ << std::endl; // Newline to separate from log message.
708*6777b538SAndroid Build Coastguard Worker stack_trace.OutputToStream(&stream_);
709*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
710*6777b538SAndroid Build Coastguard Worker std::string java_stack = base::android::GetJavaStackTraceIfPresent();
711*6777b538SAndroid Build Coastguard Worker if (!java_stack.empty()) {
712*6777b538SAndroid Build Coastguard Worker stream_ << "Java stack (may interleave with native stack):\n";
713*6777b538SAndroid Build Coastguard Worker stream_ << java_stack << '\n';
714*6777b538SAndroid Build Coastguard Worker }
715*6777b538SAndroid Build Coastguard Worker #endif
716*6777b538SAndroid Build Coastguard Worker base::debug::TaskTrace task_trace;
717*6777b538SAndroid Build Coastguard Worker if (!task_trace.empty())
718*6777b538SAndroid Build Coastguard Worker task_trace.OutputToStream(&stream_);
719*6777b538SAndroid Build Coastguard Worker
720*6777b538SAndroid Build Coastguard Worker // Include the IPC context, if any.
721*6777b538SAndroid Build Coastguard Worker // TODO(chrisha): Integrate with symbolization once those tools exist!
722*6777b538SAndroid Build Coastguard Worker const auto* task = base::TaskAnnotator::CurrentTaskForThread();
723*6777b538SAndroid Build Coastguard Worker if (task && task->ipc_hash) {
724*6777b538SAndroid Build Coastguard Worker stream_ << "IPC message handler context: "
725*6777b538SAndroid Build Coastguard Worker << base::StringPrintf("0x%08X", task->ipc_hash) << std::endl;
726*6777b538SAndroid Build Coastguard Worker }
727*6777b538SAndroid Build Coastguard Worker
728*6777b538SAndroid Build Coastguard Worker // Include the crash keys, if any.
729*6777b538SAndroid Build Coastguard Worker base::debug::OutputCrashKeysToStream(stream_);
730*6777b538SAndroid Build Coastguard Worker }
731*6777b538SAndroid Build Coastguard Worker #endif
732*6777b538SAndroid Build Coastguard Worker stream_ << std::endl;
733*6777b538SAndroid Build Coastguard Worker std::string str_newline(stream_.str());
734*6777b538SAndroid Build Coastguard Worker TraceLogMessage(file_, line_, str_newline.substr(message_start_));
735*6777b538SAndroid Build Coastguard Worker
736*6777b538SAndroid Build Coastguard Worker // FATAL messages should always run the assert handler and crash, even if a
737*6777b538SAndroid Build Coastguard Worker // message handler marks them as otherwise handled.
738*6777b538SAndroid Build Coastguard Worker absl::Cleanup handle_fatal_message = [&] {
739*6777b538SAndroid Build Coastguard Worker if (severity_ == LOGGING_FATAL) {
740*6777b538SAndroid Build Coastguard Worker HandleFatal(stack_start, str_newline);
741*6777b538SAndroid Build Coastguard Worker }
742*6777b538SAndroid Build Coastguard Worker };
743*6777b538SAndroid Build Coastguard Worker
744*6777b538SAndroid Build Coastguard Worker if (severity_ == LOGGING_FATAL)
745*6777b538SAndroid Build Coastguard Worker SetLogFatalCrashKey(this);
746*6777b538SAndroid Build Coastguard Worker
747*6777b538SAndroid Build Coastguard Worker // Give any log message handler first dibs on the message.
748*6777b538SAndroid Build Coastguard Worker if (g_log_message_handler &&
749*6777b538SAndroid Build Coastguard Worker g_log_message_handler(severity_, file_, line_, message_start_,
750*6777b538SAndroid Build Coastguard Worker str_newline)) {
751*6777b538SAndroid Build Coastguard Worker // The handler took care of it, no further processing.
752*6777b538SAndroid Build Coastguard Worker return;
753*6777b538SAndroid Build Coastguard Worker }
754*6777b538SAndroid Build Coastguard Worker
755*6777b538SAndroid Build Coastguard Worker if ((g_logging_destination & LOG_TO_SYSTEM_DEBUG_LOG) != 0) {
756*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
757*6777b538SAndroid Build Coastguard Worker OutputDebugStringA(str_newline.c_str());
758*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE)
759*6777b538SAndroid Build Coastguard Worker // In LOG_TO_SYSTEM_DEBUG_LOG mode, log messages are always written to
760*6777b538SAndroid Build Coastguard Worker // stderr. If stderr is /dev/null, also log via os_log. If there's something
761*6777b538SAndroid Build Coastguard Worker // weird about stderr, assume that log messages are going nowhere and log
762*6777b538SAndroid Build Coastguard Worker // via os_log too. Messages logged via os_log show up in Console.app.
763*6777b538SAndroid Build Coastguard Worker //
764*6777b538SAndroid Build Coastguard Worker // Programs started by launchd, as UI applications normally are, have had
765*6777b538SAndroid Build Coastguard Worker // stderr connected to /dev/null since OS X 10.8. Prior to that, stderr was
766*6777b538SAndroid Build Coastguard Worker // a pipe to launchd, which logged what it received (see log_redirect_fd in
767*6777b538SAndroid Build Coastguard Worker // 10.7.5 launchd-392.39/launchd/src/launchd_core_logic.c).
768*6777b538SAndroid Build Coastguard Worker //
769*6777b538SAndroid Build Coastguard Worker // Another alternative would be to determine whether stderr is a pipe to
770*6777b538SAndroid Build Coastguard Worker // launchd and avoid logging via os_log only in that case. See 10.7.5
771*6777b538SAndroid Build Coastguard Worker // CF-635.21/CFUtilities.c also_do_stderr(). This would result in logging to
772*6777b538SAndroid Build Coastguard Worker // both stderr and os_log even in tests, where it's undesirable to log to
773*6777b538SAndroid Build Coastguard Worker // the system log at all.
774*6777b538SAndroid Build Coastguard Worker const bool log_to_system = []() {
775*6777b538SAndroid Build Coastguard Worker struct stat stderr_stat;
776*6777b538SAndroid Build Coastguard Worker if (fstat(fileno(stderr), &stderr_stat) == -1) {
777*6777b538SAndroid Build Coastguard Worker return true;
778*6777b538SAndroid Build Coastguard Worker }
779*6777b538SAndroid Build Coastguard Worker if (!S_ISCHR(stderr_stat.st_mode)) {
780*6777b538SAndroid Build Coastguard Worker return false;
781*6777b538SAndroid Build Coastguard Worker }
782*6777b538SAndroid Build Coastguard Worker
783*6777b538SAndroid Build Coastguard Worker struct stat dev_null_stat;
784*6777b538SAndroid Build Coastguard Worker if (stat(_PATH_DEVNULL, &dev_null_stat) == -1) {
785*6777b538SAndroid Build Coastguard Worker return true;
786*6777b538SAndroid Build Coastguard Worker }
787*6777b538SAndroid Build Coastguard Worker
788*6777b538SAndroid Build Coastguard Worker return !S_ISCHR(dev_null_stat.st_mode) ||
789*6777b538SAndroid Build Coastguard Worker stderr_stat.st_rdev == dev_null_stat.st_rdev;
790*6777b538SAndroid Build Coastguard Worker }();
791*6777b538SAndroid Build Coastguard Worker
792*6777b538SAndroid Build Coastguard Worker if (log_to_system) {
793*6777b538SAndroid Build Coastguard Worker // Log roughly the same way that CFLog() and NSLog() would. See 10.10.5
794*6777b538SAndroid Build Coastguard Worker // CF-1153.18/CFUtilities.c __CFLogCString().
795*6777b538SAndroid Build Coastguard Worker CFBundleRef main_bundle = CFBundleGetMainBundle();
796*6777b538SAndroid Build Coastguard Worker CFStringRef main_bundle_id_cf =
797*6777b538SAndroid Build Coastguard Worker main_bundle ? CFBundleGetIdentifier(main_bundle) : nullptr;
798*6777b538SAndroid Build Coastguard Worker std::string main_bundle_id =
799*6777b538SAndroid Build Coastguard Worker main_bundle_id_cf ? base::SysCFStringRefToUTF8(main_bundle_id_cf)
800*6777b538SAndroid Build Coastguard Worker : std::string("");
801*6777b538SAndroid Build Coastguard Worker
802*6777b538SAndroid Build Coastguard Worker const class OSLog {
803*6777b538SAndroid Build Coastguard Worker public:
804*6777b538SAndroid Build Coastguard Worker explicit OSLog(const char* subsystem)
805*6777b538SAndroid Build Coastguard Worker : os_log_(subsystem ? os_log_create(subsystem, "chromium_logging")
806*6777b538SAndroid Build Coastguard Worker : OS_LOG_DEFAULT) {}
807*6777b538SAndroid Build Coastguard Worker OSLog(const OSLog&) = delete;
808*6777b538SAndroid Build Coastguard Worker OSLog& operator=(const OSLog&) = delete;
809*6777b538SAndroid Build Coastguard Worker ~OSLog() {
810*6777b538SAndroid Build Coastguard Worker if (os_log_ != OS_LOG_DEFAULT) {
811*6777b538SAndroid Build Coastguard Worker os_release(os_log_);
812*6777b538SAndroid Build Coastguard Worker }
813*6777b538SAndroid Build Coastguard Worker }
814*6777b538SAndroid Build Coastguard Worker os_log_t get() const { return os_log_; }
815*6777b538SAndroid Build Coastguard Worker
816*6777b538SAndroid Build Coastguard Worker private:
817*6777b538SAndroid Build Coastguard Worker os_log_t os_log_;
818*6777b538SAndroid Build Coastguard Worker } log(main_bundle_id.empty() ? nullptr : main_bundle_id.c_str());
819*6777b538SAndroid Build Coastguard Worker const os_log_type_t os_log_type = [](LogSeverity severity) {
820*6777b538SAndroid Build Coastguard Worker switch (severity) {
821*6777b538SAndroid Build Coastguard Worker case LOGGING_INFO:
822*6777b538SAndroid Build Coastguard Worker return OS_LOG_TYPE_INFO;
823*6777b538SAndroid Build Coastguard Worker case LOGGING_WARNING:
824*6777b538SAndroid Build Coastguard Worker return OS_LOG_TYPE_DEFAULT;
825*6777b538SAndroid Build Coastguard Worker case LOGGING_ERROR:
826*6777b538SAndroid Build Coastguard Worker return OS_LOG_TYPE_ERROR;
827*6777b538SAndroid Build Coastguard Worker case LOGGING_FATAL:
828*6777b538SAndroid Build Coastguard Worker return OS_LOG_TYPE_FAULT;
829*6777b538SAndroid Build Coastguard Worker case LOGGING_VERBOSE:
830*6777b538SAndroid Build Coastguard Worker return OS_LOG_TYPE_DEBUG;
831*6777b538SAndroid Build Coastguard Worker default:
832*6777b538SAndroid Build Coastguard Worker return OS_LOG_TYPE_DEFAULT;
833*6777b538SAndroid Build Coastguard Worker }
834*6777b538SAndroid Build Coastguard Worker }(severity_);
835*6777b538SAndroid Build Coastguard Worker os_log_with_type(log.get(), os_log_type, "%{public}s",
836*6777b538SAndroid Build Coastguard Worker str_newline.c_str());
837*6777b538SAndroid Build Coastguard Worker }
838*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_ANDROID)
839*6777b538SAndroid Build Coastguard Worker android_LogPriority priority =
840*6777b538SAndroid Build Coastguard Worker (severity_ < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN;
841*6777b538SAndroid Build Coastguard Worker switch (severity_) {
842*6777b538SAndroid Build Coastguard Worker case LOGGING_INFO:
843*6777b538SAndroid Build Coastguard Worker priority = ANDROID_LOG_INFO;
844*6777b538SAndroid Build Coastguard Worker break;
845*6777b538SAndroid Build Coastguard Worker case LOGGING_WARNING:
846*6777b538SAndroid Build Coastguard Worker priority = ANDROID_LOG_WARN;
847*6777b538SAndroid Build Coastguard Worker break;
848*6777b538SAndroid Build Coastguard Worker case LOGGING_ERROR:
849*6777b538SAndroid Build Coastguard Worker priority = ANDROID_LOG_ERROR;
850*6777b538SAndroid Build Coastguard Worker break;
851*6777b538SAndroid Build Coastguard Worker case LOGGING_FATAL:
852*6777b538SAndroid Build Coastguard Worker priority = ANDROID_LOG_FATAL;
853*6777b538SAndroid Build Coastguard Worker break;
854*6777b538SAndroid Build Coastguard Worker }
855*6777b538SAndroid Build Coastguard Worker const char kAndroidLogTag[] = "chromium";
856*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
857*6777b538SAndroid Build Coastguard Worker // Split the output by new lines to prevent the Android system from
858*6777b538SAndroid Build Coastguard Worker // truncating the log.
859*6777b538SAndroid Build Coastguard Worker std::vector<std::string> lines = base::SplitString(
860*6777b538SAndroid Build Coastguard Worker str_newline, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
861*6777b538SAndroid Build Coastguard Worker // str_newline has an extra newline appended to it (at the top of this
862*6777b538SAndroid Build Coastguard Worker // function), so skip the last split element to avoid needlessly
863*6777b538SAndroid Build Coastguard Worker // logging an empty string.
864*6777b538SAndroid Build Coastguard Worker lines.pop_back();
865*6777b538SAndroid Build Coastguard Worker for (const auto& line : lines)
866*6777b538SAndroid Build Coastguard Worker __android_log_write(priority, kAndroidLogTag, line.c_str());
867*6777b538SAndroid Build Coastguard Worker #else
868*6777b538SAndroid Build Coastguard Worker // The Android system may truncate the string if it's too long.
869*6777b538SAndroid Build Coastguard Worker __android_log_write(priority, kAndroidLogTag, str_newline.c_str());
870*6777b538SAndroid Build Coastguard Worker #endif
871*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FUCHSIA)
872*6777b538SAndroid Build Coastguard Worker // LogMessage() will silently drop the message if the logger is not valid.
873*6777b538SAndroid Build Coastguard Worker // Skip the final character of |str_newline|, since LogMessage() will add
874*6777b538SAndroid Build Coastguard Worker // a newline.
875*6777b538SAndroid Build Coastguard Worker const auto message = base::StringPiece(str_newline).substr(message_start_);
876*6777b538SAndroid Build Coastguard Worker GetScopedFxLogger().LogMessage(file_, static_cast<uint32_t>(line_),
877*6777b538SAndroid Build Coastguard Worker message.substr(0, message.size() - 1),
878*6777b538SAndroid Build Coastguard Worker LogSeverityToFuchsiaLogSeverity(severity_));
879*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_FUCHSIA)
880*6777b538SAndroid Build Coastguard Worker }
881*6777b538SAndroid Build Coastguard Worker
882*6777b538SAndroid Build Coastguard Worker if (ShouldLogToStderr(severity_)) {
883*6777b538SAndroid Build Coastguard Worker // Not using fwrite() here, as there are crashes on Windows when CRT calls
884*6777b538SAndroid Build Coastguard Worker // malloc() internally, triggering an OOM crash. This likely means that the
885*6777b538SAndroid Build Coastguard Worker // process is close to OOM, but at least get the proper error message out,
886*6777b538SAndroid Build Coastguard Worker // and give the caller a chance to free() up some resources. For instance if
887*6777b538SAndroid Build Coastguard Worker // the calling code is:
888*6777b538SAndroid Build Coastguard Worker //
889*6777b538SAndroid Build Coastguard Worker // allocate_something();
890*6777b538SAndroid Build Coastguard Worker // if (!TryToDoSomething()) {
891*6777b538SAndroid Build Coastguard Worker // LOG(ERROR) << "Something went wrong";
892*6777b538SAndroid Build Coastguard Worker // free_something();
893*6777b538SAndroid Build Coastguard Worker // }
894*6777b538SAndroid Build Coastguard Worker WriteToFd(STDERR_FILENO, str_newline.data(), str_newline.size());
895*6777b538SAndroid Build Coastguard Worker }
896*6777b538SAndroid Build Coastguard Worker
897*6777b538SAndroid Build Coastguard Worker if ((g_logging_destination & LOG_TO_FILE) != 0) {
898*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
899*6777b538SAndroid Build Coastguard Worker // If the client app did not call InitLogging() and the lock has not
900*6777b538SAndroid Build Coastguard Worker // been created it will be done now on calling GetLoggingLock(). We do this
901*6777b538SAndroid Build Coastguard Worker // on demand, but if two threads try to do this at the same time, there will
902*6777b538SAndroid Build Coastguard Worker // be a race condition to create the lock. This is why InitLogging should be
903*6777b538SAndroid Build Coastguard Worker // called from the main thread at the beginning of execution.
904*6777b538SAndroid Build Coastguard Worker base::AutoLock guard(GetLoggingLock());
905*6777b538SAndroid Build Coastguard Worker #endif
906*6777b538SAndroid Build Coastguard Worker if (InitializeLogFileHandle()) {
907*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
908*6777b538SAndroid Build Coastguard Worker DWORD num_written;
909*6777b538SAndroid Build Coastguard Worker WriteFile(g_log_file,
910*6777b538SAndroid Build Coastguard Worker static_cast<const void*>(str_newline.c_str()),
911*6777b538SAndroid Build Coastguard Worker static_cast<DWORD>(str_newline.length()),
912*6777b538SAndroid Build Coastguard Worker &num_written,
913*6777b538SAndroid Build Coastguard Worker nullptr);
914*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
915*6777b538SAndroid Build Coastguard Worker std::ignore =
916*6777b538SAndroid Build Coastguard Worker fwrite(str_newline.data(), str_newline.size(), 1, g_log_file);
917*6777b538SAndroid Build Coastguard Worker fflush(g_log_file);
918*6777b538SAndroid Build Coastguard Worker #else
919*6777b538SAndroid Build Coastguard Worker #error Unsupported platform
920*6777b538SAndroid Build Coastguard Worker #endif
921*6777b538SAndroid Build Coastguard Worker }
922*6777b538SAndroid Build Coastguard Worker }
923*6777b538SAndroid Build Coastguard Worker }
924*6777b538SAndroid Build Coastguard Worker
BuildCrashString() const925*6777b538SAndroid Build Coastguard Worker std::string LogMessage::BuildCrashString() const {
926*6777b538SAndroid Build Coastguard Worker return logging::BuildCrashString(file(), line(),
927*6777b538SAndroid Build Coastguard Worker str().c_str() + message_start_);
928*6777b538SAndroid Build Coastguard Worker }
929*6777b538SAndroid Build Coastguard Worker
930*6777b538SAndroid Build Coastguard Worker // writes the common header info to the stream
Init(const char * file,int line)931*6777b538SAndroid Build Coastguard Worker void LogMessage::Init(const char* file, int line) {
932*6777b538SAndroid Build Coastguard Worker base::StringPiece filename(file);
933*6777b538SAndroid Build Coastguard Worker size_t last_slash_pos = filename.find_last_of("\\/");
934*6777b538SAndroid Build Coastguard Worker if (last_slash_pos != base::StringPiece::npos)
935*6777b538SAndroid Build Coastguard Worker filename.remove_prefix(last_slash_pos + 1);
936*6777b538SAndroid Build Coastguard Worker
937*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
938*6777b538SAndroid Build Coastguard Worker if (g_log_format == LogFormat::LOG_FORMAT_SYSLOG) {
939*6777b538SAndroid Build Coastguard Worker InitWithSyslogPrefix(
940*6777b538SAndroid Build Coastguard Worker filename, line, TickCount(), log_severity_name(severity_), g_log_prefix,
941*6777b538SAndroid Build Coastguard Worker g_log_process_id, g_log_thread_id, g_log_timestamp, g_log_tickcount);
942*6777b538SAndroid Build Coastguard Worker } else
943*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS)
944*6777b538SAndroid Build Coastguard Worker {
945*6777b538SAndroid Build Coastguard Worker // TODO(darin): It might be nice if the columns were fixed width.
946*6777b538SAndroid Build Coastguard Worker stream_ << '[';
947*6777b538SAndroid Build Coastguard Worker if (g_log_prefix)
948*6777b538SAndroid Build Coastguard Worker stream_ << g_log_prefix << ':';
949*6777b538SAndroid Build Coastguard Worker if (g_log_process_id)
950*6777b538SAndroid Build Coastguard Worker stream_ << base::GetUniqueIdForProcess() << ':';
951*6777b538SAndroid Build Coastguard Worker if (g_log_thread_id)
952*6777b538SAndroid Build Coastguard Worker stream_ << base::PlatformThread::CurrentId() << ':';
953*6777b538SAndroid Build Coastguard Worker if (g_log_timestamp) {
954*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
955*6777b538SAndroid Build Coastguard Worker SYSTEMTIME local_time;
956*6777b538SAndroid Build Coastguard Worker GetLocalTime(&local_time);
957*6777b538SAndroid Build Coastguard Worker stream_ << std::setfill('0')
958*6777b538SAndroid Build Coastguard Worker << std::setw(2) << local_time.wMonth
959*6777b538SAndroid Build Coastguard Worker << std::setw(2) << local_time.wDay
960*6777b538SAndroid Build Coastguard Worker << '/'
961*6777b538SAndroid Build Coastguard Worker << std::setw(2) << local_time.wHour
962*6777b538SAndroid Build Coastguard Worker << std::setw(2) << local_time.wMinute
963*6777b538SAndroid Build Coastguard Worker << std::setw(2) << local_time.wSecond
964*6777b538SAndroid Build Coastguard Worker << '.'
965*6777b538SAndroid Build Coastguard Worker << std::setw(3) << local_time.wMilliseconds
966*6777b538SAndroid Build Coastguard Worker << ':';
967*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
968*6777b538SAndroid Build Coastguard Worker timeval tv;
969*6777b538SAndroid Build Coastguard Worker gettimeofday(&tv, nullptr);
970*6777b538SAndroid Build Coastguard Worker time_t t = tv.tv_sec;
971*6777b538SAndroid Build Coastguard Worker struct tm local_time;
972*6777b538SAndroid Build Coastguard Worker localtime_r(&t, &local_time);
973*6777b538SAndroid Build Coastguard Worker struct tm* tm_time = &local_time;
974*6777b538SAndroid Build Coastguard Worker stream_ << std::setfill('0')
975*6777b538SAndroid Build Coastguard Worker << std::setw(2) << 1 + tm_time->tm_mon
976*6777b538SAndroid Build Coastguard Worker << std::setw(2) << tm_time->tm_mday
977*6777b538SAndroid Build Coastguard Worker << '/'
978*6777b538SAndroid Build Coastguard Worker << std::setw(2) << tm_time->tm_hour
979*6777b538SAndroid Build Coastguard Worker << std::setw(2) << tm_time->tm_min
980*6777b538SAndroid Build Coastguard Worker << std::setw(2) << tm_time->tm_sec
981*6777b538SAndroid Build Coastguard Worker << '.'
982*6777b538SAndroid Build Coastguard Worker << std::setw(6) << tv.tv_usec
983*6777b538SAndroid Build Coastguard Worker << ':';
984*6777b538SAndroid Build Coastguard Worker #else
985*6777b538SAndroid Build Coastguard Worker #error Unsupported platform
986*6777b538SAndroid Build Coastguard Worker #endif
987*6777b538SAndroid Build Coastguard Worker }
988*6777b538SAndroid Build Coastguard Worker if (g_log_tickcount)
989*6777b538SAndroid Build Coastguard Worker stream_ << TickCount() << ':';
990*6777b538SAndroid Build Coastguard Worker if (severity_ >= 0) {
991*6777b538SAndroid Build Coastguard Worker stream_ << log_severity_name(severity_);
992*6777b538SAndroid Build Coastguard Worker } else {
993*6777b538SAndroid Build Coastguard Worker stream_ << "VERBOSE" << -severity_;
994*6777b538SAndroid Build Coastguard Worker }
995*6777b538SAndroid Build Coastguard Worker stream_ << ":" << filename << "(" << line << ")] ";
996*6777b538SAndroid Build Coastguard Worker }
997*6777b538SAndroid Build Coastguard Worker message_start_ = stream_.str().length();
998*6777b538SAndroid Build Coastguard Worker }
999*6777b538SAndroid Build Coastguard Worker
HandleFatal(size_t stack_start,const std::string & str_newline) const1000*6777b538SAndroid Build Coastguard Worker void LogMessage::HandleFatal(size_t stack_start,
1001*6777b538SAndroid Build Coastguard Worker const std::string& str_newline) const {
1002*6777b538SAndroid Build Coastguard Worker char str_stack[1024];
1003*6777b538SAndroid Build Coastguard Worker base::strlcpy(str_stack, str_newline.data(), std::size(str_stack));
1004*6777b538SAndroid Build Coastguard Worker base::debug::Alias(&str_stack);
1005*6777b538SAndroid Build Coastguard Worker
1006*6777b538SAndroid Build Coastguard Worker if (!GetLogAssertHandlerStack().empty()) {
1007*6777b538SAndroid Build Coastguard Worker LogAssertHandlerFunction log_assert_handler =
1008*6777b538SAndroid Build Coastguard Worker GetLogAssertHandlerStack().top();
1009*6777b538SAndroid Build Coastguard Worker
1010*6777b538SAndroid Build Coastguard Worker if (log_assert_handler) {
1011*6777b538SAndroid Build Coastguard Worker log_assert_handler.Run(
1012*6777b538SAndroid Build Coastguard Worker file_, line_,
1013*6777b538SAndroid Build Coastguard Worker base::StringPiece(str_newline.c_str() + message_start_,
1014*6777b538SAndroid Build Coastguard Worker stack_start - message_start_),
1015*6777b538SAndroid Build Coastguard Worker base::StringPiece(str_newline.c_str() + stack_start));
1016*6777b538SAndroid Build Coastguard Worker }
1017*6777b538SAndroid Build Coastguard Worker } else {
1018*6777b538SAndroid Build Coastguard Worker // Don't use the string with the newline, get a fresh version to send to
1019*6777b538SAndroid Build Coastguard Worker // the debug message process. We also don't display assertions to the
1020*6777b538SAndroid Build Coastguard Worker // user in release mode. The enduser can't do anything with this
1021*6777b538SAndroid Build Coastguard Worker // information, and displaying message boxes when the application is
1022*6777b538SAndroid Build Coastguard Worker // hosed can cause additional problems.
1023*6777b538SAndroid Build Coastguard Worker #ifndef NDEBUG
1024*6777b538SAndroid Build Coastguard Worker if (!base::debug::BeingDebugged()) {
1025*6777b538SAndroid Build Coastguard Worker // Displaying a dialog is unnecessary when debugging and can complicate
1026*6777b538SAndroid Build Coastguard Worker // debugging.
1027*6777b538SAndroid Build Coastguard Worker DisplayDebugMessageInDialog(stream_.str());
1028*6777b538SAndroid Build Coastguard Worker }
1029*6777b538SAndroid Build Coastguard Worker #endif
1030*6777b538SAndroid Build Coastguard Worker
1031*6777b538SAndroid Build Coastguard Worker // Crash the process to generate a dump.
1032*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/1409729): Move ImmediateCrash() to an absl::Cleanup to
1033*6777b538SAndroid Build Coastguard Worker // make sure it runs unconditionally. Currently LogAssertHandlers can abort
1034*6777b538SAndroid Build Coastguard Worker // a FATAL message and tests rely on this. HandleFatal() should be
1035*6777b538SAndroid Build Coastguard Worker // [[noreturn]].
1036*6777b538SAndroid Build Coastguard Worker base::ImmediateCrash();
1037*6777b538SAndroid Build Coastguard Worker }
1038*6777b538SAndroid Build Coastguard Worker }
1039*6777b538SAndroid Build Coastguard Worker
~LogMessageFatal()1040*6777b538SAndroid Build Coastguard Worker LogMessageFatal::~LogMessageFatal() {
1041*6777b538SAndroid Build Coastguard Worker Flush();
1042*6777b538SAndroid Build Coastguard Worker base::ImmediateCrash();
1043*6777b538SAndroid Build Coastguard Worker }
1044*6777b538SAndroid Build Coastguard Worker
1045*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
1046*6777b538SAndroid Build Coastguard Worker // This has already been defined in the header, but defining it again as DWORD
1047*6777b538SAndroid Build Coastguard Worker // ensures that the type used in the header is equivalent to DWORD. If not,
1048*6777b538SAndroid Build Coastguard Worker // the redefinition is a compile error.
1049*6777b538SAndroid Build Coastguard Worker typedef DWORD SystemErrorCode;
1050*6777b538SAndroid Build Coastguard Worker #endif
1051*6777b538SAndroid Build Coastguard Worker
GetLastSystemErrorCode()1052*6777b538SAndroid Build Coastguard Worker SystemErrorCode GetLastSystemErrorCode() {
1053*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
1054*6777b538SAndroid Build Coastguard Worker return ::GetLastError();
1055*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
1056*6777b538SAndroid Build Coastguard Worker return errno;
1057*6777b538SAndroid Build Coastguard Worker #endif
1058*6777b538SAndroid Build Coastguard Worker }
1059*6777b538SAndroid Build Coastguard Worker
SystemErrorCodeToString(SystemErrorCode error_code)1060*6777b538SAndroid Build Coastguard Worker BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code) {
1061*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
1062*6777b538SAndroid Build Coastguard Worker LPWSTR msgbuf = nullptr;
1063*6777b538SAndroid Build Coastguard Worker DWORD len = ::FormatMessageW(
1064*6777b538SAndroid Build Coastguard Worker FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
1065*6777b538SAndroid Build Coastguard Worker FORMAT_MESSAGE_IGNORE_INSERTS,
1066*6777b538SAndroid Build Coastguard Worker nullptr, error_code, 0, reinterpret_cast<LPWSTR>(&msgbuf), 0, nullptr);
1067*6777b538SAndroid Build Coastguard Worker if (len) {
1068*6777b538SAndroid Build Coastguard Worker std::u16string message = base::WideToUTF16(msgbuf);
1069*6777b538SAndroid Build Coastguard Worker ::LocalFree(msgbuf);
1070*6777b538SAndroid Build Coastguard Worker msgbuf = nullptr;
1071*6777b538SAndroid Build Coastguard Worker // Messages returned by system end with line breaks.
1072*6777b538SAndroid Build Coastguard Worker return base::UTF16ToUTF8(base::CollapseWhitespace(message, true)) +
1073*6777b538SAndroid Build Coastguard Worker base::StringPrintf(" (0x%lX)", error_code);
1074*6777b538SAndroid Build Coastguard Worker }
1075*6777b538SAndroid Build Coastguard Worker return base::StringPrintf("Error (0x%lX) while retrieving error. (0x%lX)",
1076*6777b538SAndroid Build Coastguard Worker GetLastError(), error_code);
1077*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
1078*6777b538SAndroid Build Coastguard Worker return base::safe_strerror(error_code) +
1079*6777b538SAndroid Build Coastguard Worker base::StringPrintf(" (%d)", error_code);
1080*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
1081*6777b538SAndroid Build Coastguard Worker }
1082*6777b538SAndroid Build Coastguard Worker
1083*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
Win32ErrorLogMessage(const char * file,int line,LogSeverity severity,SystemErrorCode err)1084*6777b538SAndroid Build Coastguard Worker Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file,
1085*6777b538SAndroid Build Coastguard Worker int line,
1086*6777b538SAndroid Build Coastguard Worker LogSeverity severity,
1087*6777b538SAndroid Build Coastguard Worker SystemErrorCode err)
1088*6777b538SAndroid Build Coastguard Worker : LogMessage(file, line, severity), err_(err) {}
1089*6777b538SAndroid Build Coastguard Worker
~Win32ErrorLogMessage()1090*6777b538SAndroid Build Coastguard Worker Win32ErrorLogMessage::~Win32ErrorLogMessage() {
1091*6777b538SAndroid Build Coastguard Worker AppendError();
1092*6777b538SAndroid Build Coastguard Worker }
1093*6777b538SAndroid Build Coastguard Worker
AppendError()1094*6777b538SAndroid Build Coastguard Worker void Win32ErrorLogMessage::AppendError() {
1095*6777b538SAndroid Build Coastguard Worker stream() << ": " << SystemErrorCodeToString(err_);
1096*6777b538SAndroid Build Coastguard Worker // We're about to crash (CHECK). Put |err_| on the stack (by placing it in a
1097*6777b538SAndroid Build Coastguard Worker // field) and use Alias in hopes that it makes it into crash dumps.
1098*6777b538SAndroid Build Coastguard Worker DWORD last_error = err_;
1099*6777b538SAndroid Build Coastguard Worker base::debug::Alias(&last_error);
1100*6777b538SAndroid Build Coastguard Worker }
1101*6777b538SAndroid Build Coastguard Worker
~Win32ErrorLogMessageFatal()1102*6777b538SAndroid Build Coastguard Worker Win32ErrorLogMessageFatal::~Win32ErrorLogMessageFatal() {
1103*6777b538SAndroid Build Coastguard Worker AppendError();
1104*6777b538SAndroid Build Coastguard Worker Flush();
1105*6777b538SAndroid Build Coastguard Worker base::ImmediateCrash();
1106*6777b538SAndroid Build Coastguard Worker }
1107*6777b538SAndroid Build Coastguard Worker
1108*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
ErrnoLogMessage(const char * file,int line,LogSeverity severity,SystemErrorCode err)1109*6777b538SAndroid Build Coastguard Worker ErrnoLogMessage::ErrnoLogMessage(const char* file,
1110*6777b538SAndroid Build Coastguard Worker int line,
1111*6777b538SAndroid Build Coastguard Worker LogSeverity severity,
1112*6777b538SAndroid Build Coastguard Worker SystemErrorCode err)
1113*6777b538SAndroid Build Coastguard Worker : LogMessage(file, line, severity), err_(err) {}
1114*6777b538SAndroid Build Coastguard Worker
~ErrnoLogMessage()1115*6777b538SAndroid Build Coastguard Worker ErrnoLogMessage::~ErrnoLogMessage() {
1116*6777b538SAndroid Build Coastguard Worker AppendError();
1117*6777b538SAndroid Build Coastguard Worker }
1118*6777b538SAndroid Build Coastguard Worker
AppendError()1119*6777b538SAndroid Build Coastguard Worker void ErrnoLogMessage::AppendError() {
1120*6777b538SAndroid Build Coastguard Worker stream() << ": " << SystemErrorCodeToString(err_);
1121*6777b538SAndroid Build Coastguard Worker // We're about to crash (CHECK). Put |err_| on the stack (by placing it in a
1122*6777b538SAndroid Build Coastguard Worker // field) and use Alias in hopes that it makes it into crash dumps.
1123*6777b538SAndroid Build Coastguard Worker int last_error = err_;
1124*6777b538SAndroid Build Coastguard Worker base::debug::Alias(&last_error);
1125*6777b538SAndroid Build Coastguard Worker }
1126*6777b538SAndroid Build Coastguard Worker
~ErrnoLogMessageFatal()1127*6777b538SAndroid Build Coastguard Worker ErrnoLogMessageFatal::~ErrnoLogMessageFatal() {
1128*6777b538SAndroid Build Coastguard Worker AppendError();
1129*6777b538SAndroid Build Coastguard Worker Flush();
1130*6777b538SAndroid Build Coastguard Worker base::ImmediateCrash();
1131*6777b538SAndroid Build Coastguard Worker }
1132*6777b538SAndroid Build Coastguard Worker
1133*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_WIN)
1134*6777b538SAndroid Build Coastguard Worker
CloseLogFile()1135*6777b538SAndroid Build Coastguard Worker void CloseLogFile() {
1136*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
1137*6777b538SAndroid Build Coastguard Worker base::AutoLock guard(GetLoggingLock());
1138*6777b538SAndroid Build Coastguard Worker #endif
1139*6777b538SAndroid Build Coastguard Worker CloseLogFileUnlocked();
1140*6777b538SAndroid Build Coastguard Worker }
1141*6777b538SAndroid Build Coastguard Worker
1142*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS_ASH)
DuplicateLogFILE()1143*6777b538SAndroid Build Coastguard Worker FILE* DuplicateLogFILE() {
1144*6777b538SAndroid Build Coastguard Worker if ((g_logging_destination & LOG_TO_FILE) == 0 || !InitializeLogFileHandle())
1145*6777b538SAndroid Build Coastguard Worker return nullptr;
1146*6777b538SAndroid Build Coastguard Worker
1147*6777b538SAndroid Build Coastguard Worker int log_fd = fileno(g_log_file);
1148*6777b538SAndroid Build Coastguard Worker if (log_fd == -1)
1149*6777b538SAndroid Build Coastguard Worker return nullptr;
1150*6777b538SAndroid Build Coastguard Worker base::ScopedFD dup_fd(dup(log_fd));
1151*6777b538SAndroid Build Coastguard Worker if (dup_fd == -1)
1152*6777b538SAndroid Build Coastguard Worker return nullptr;
1153*6777b538SAndroid Build Coastguard Worker FILE* duplicate = fdopen(dup_fd.get(), "a");
1154*6777b538SAndroid Build Coastguard Worker if (!duplicate)
1155*6777b538SAndroid Build Coastguard Worker return nullptr;
1156*6777b538SAndroid Build Coastguard Worker std::ignore = dup_fd.release();
1157*6777b538SAndroid Build Coastguard Worker return duplicate;
1158*6777b538SAndroid Build Coastguard Worker }
1159*6777b538SAndroid Build Coastguard Worker #endif
1160*6777b538SAndroid Build Coastguard Worker
1161*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
DuplicateLogFileHandle()1162*6777b538SAndroid Build Coastguard Worker HANDLE DuplicateLogFileHandle() {
1163*6777b538SAndroid Build Coastguard Worker // `g_log_file` should only be valid, or nullptr, but be very careful that we
1164*6777b538SAndroid Build Coastguard Worker // do not duplicate INVALID_HANDLE_VALUE as it aliases the process handle.
1165*6777b538SAndroid Build Coastguard Worker if (!(g_logging_destination & LOG_TO_FILE) || !g_log_file ||
1166*6777b538SAndroid Build Coastguard Worker g_log_file == INVALID_HANDLE_VALUE) {
1167*6777b538SAndroid Build Coastguard Worker return nullptr;
1168*6777b538SAndroid Build Coastguard Worker }
1169*6777b538SAndroid Build Coastguard Worker HANDLE duplicate = nullptr;
1170*6777b538SAndroid Build Coastguard Worker if (!::DuplicateHandle(::GetCurrentProcess(), g_log_file,
1171*6777b538SAndroid Build Coastguard Worker ::GetCurrentProcess(), &duplicate, 0,
1172*6777b538SAndroid Build Coastguard Worker /*bInheritHandle=*/TRUE, DUPLICATE_SAME_ACCESS)) {
1173*6777b538SAndroid Build Coastguard Worker return nullptr;
1174*6777b538SAndroid Build Coastguard Worker }
1175*6777b538SAndroid Build Coastguard Worker return duplicate;
1176*6777b538SAndroid Build Coastguard Worker }
1177*6777b538SAndroid Build Coastguard Worker #endif
1178*6777b538SAndroid Build Coastguard Worker
1179*6777b538SAndroid Build Coastguard Worker // Used for testing. Declared in test/scoped_logging_settings.h.
ScopedLoggingSettings()1180*6777b538SAndroid Build Coastguard Worker ScopedLoggingSettings::ScopedLoggingSettings()
1181*6777b538SAndroid Build Coastguard Worker : min_log_level_(g_min_log_level),
1182*6777b538SAndroid Build Coastguard Worker logging_destination_(g_logging_destination),
1183*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
1184*6777b538SAndroid Build Coastguard Worker log_format_(g_log_format),
1185*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS_ASH)
1186*6777b538SAndroid Build Coastguard Worker enable_process_id_(g_log_process_id),
1187*6777b538SAndroid Build Coastguard Worker enable_thread_id_(g_log_thread_id),
1188*6777b538SAndroid Build Coastguard Worker enable_timestamp_(g_log_timestamp),
1189*6777b538SAndroid Build Coastguard Worker enable_tickcount_(g_log_tickcount),
1190*6777b538SAndroid Build Coastguard Worker log_prefix_(g_log_prefix),
1191*6777b538SAndroid Build Coastguard Worker message_handler_(g_log_message_handler) {
1192*6777b538SAndroid Build Coastguard Worker if (g_log_file_name) {
1193*6777b538SAndroid Build Coastguard Worker log_file_name_ = *g_log_file_name;
1194*6777b538SAndroid Build Coastguard Worker }
1195*6777b538SAndroid Build Coastguard Worker
1196*6777b538SAndroid Build Coastguard Worker // Duplicating |g_log_file| is complex & unnecessary for this test helpers'
1197*6777b538SAndroid Build Coastguard Worker // use-cases, and so long as |g_log_file_name| is set, it will be re-opened
1198*6777b538SAndroid Build Coastguard Worker // automatically anyway, when required, so just close the existing one.
1199*6777b538SAndroid Build Coastguard Worker if (g_log_file) {
1200*6777b538SAndroid Build Coastguard Worker CHECK(g_log_file_name) << "Un-named |log_file| is not supported.";
1201*6777b538SAndroid Build Coastguard Worker CloseLogFileUnlocked();
1202*6777b538SAndroid Build Coastguard Worker }
1203*6777b538SAndroid Build Coastguard Worker }
1204*6777b538SAndroid Build Coastguard Worker
~ScopedLoggingSettings()1205*6777b538SAndroid Build Coastguard Worker ScopedLoggingSettings::~ScopedLoggingSettings() {
1206*6777b538SAndroid Build Coastguard Worker // Re-initialize logging via the normal path. This will clean up old file
1207*6777b538SAndroid Build Coastguard Worker // name and handle state, including re-initializing the VLOG internal state.
1208*6777b538SAndroid Build Coastguard Worker CHECK(InitLogging({.logging_dest = logging_destination_,
1209*6777b538SAndroid Build Coastguard Worker .log_file_path = log_file_name_,
1210*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
1211*6777b538SAndroid Build Coastguard Worker .log_format = log_format_
1212*6777b538SAndroid Build Coastguard Worker #endif
1213*6777b538SAndroid Build Coastguard Worker })) << "~ScopedLoggingSettings() failed to restore settings.";
1214*6777b538SAndroid Build Coastguard Worker
1215*6777b538SAndroid Build Coastguard Worker // Restore plain data settings.
1216*6777b538SAndroid Build Coastguard Worker SetMinLogLevel(min_log_level_);
1217*6777b538SAndroid Build Coastguard Worker SetLogItems(enable_process_id_, enable_thread_id_, enable_timestamp_,
1218*6777b538SAndroid Build Coastguard Worker enable_tickcount_);
1219*6777b538SAndroid Build Coastguard Worker SetLogPrefix(log_prefix_);
1220*6777b538SAndroid Build Coastguard Worker SetLogMessageHandler(message_handler_);
1221*6777b538SAndroid Build Coastguard Worker }
1222*6777b538SAndroid Build Coastguard Worker
1223*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS)
SetLogFormat(LogFormat log_format) const1224*6777b538SAndroid Build Coastguard Worker void ScopedLoggingSettings::SetLogFormat(LogFormat log_format) const {
1225*6777b538SAndroid Build Coastguard Worker g_log_format = log_format;
1226*6777b538SAndroid Build Coastguard Worker }
1227*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS_ASH)
1228*6777b538SAndroid Build Coastguard Worker
RawLog(int level,const char * message)1229*6777b538SAndroid Build Coastguard Worker void RawLog(int level, const char* message) {
1230*6777b538SAndroid Build Coastguard Worker if (level >= g_min_log_level && message) {
1231*6777b538SAndroid Build Coastguard Worker const size_t message_len = strlen(message);
1232*6777b538SAndroid Build Coastguard Worker WriteToFd(STDERR_FILENO, message, message_len);
1233*6777b538SAndroid Build Coastguard Worker
1234*6777b538SAndroid Build Coastguard Worker if (message_len > 0 && message[message_len - 1] != '\n') {
1235*6777b538SAndroid Build Coastguard Worker long rv;
1236*6777b538SAndroid Build Coastguard Worker do {
1237*6777b538SAndroid Build Coastguard Worker rv = HANDLE_EINTR(write(STDERR_FILENO, "\n", 1));
1238*6777b538SAndroid Build Coastguard Worker if (rv < 0) {
1239*6777b538SAndroid Build Coastguard Worker // Give up, nothing we can do now.
1240*6777b538SAndroid Build Coastguard Worker break;
1241*6777b538SAndroid Build Coastguard Worker }
1242*6777b538SAndroid Build Coastguard Worker } while (rv != 1);
1243*6777b538SAndroid Build Coastguard Worker }
1244*6777b538SAndroid Build Coastguard Worker }
1245*6777b538SAndroid Build Coastguard Worker
1246*6777b538SAndroid Build Coastguard Worker if (level == LOGGING_FATAL)
1247*6777b538SAndroid Build Coastguard Worker base::ImmediateCrash();
1248*6777b538SAndroid Build Coastguard Worker }
1249*6777b538SAndroid Build Coastguard Worker
1250*6777b538SAndroid Build Coastguard Worker // This was defined at the beginning of this file.
1251*6777b538SAndroid Build Coastguard Worker #undef write
1252*6777b538SAndroid Build Coastguard Worker
1253*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
IsLoggingToFileEnabled()1254*6777b538SAndroid Build Coastguard Worker bool IsLoggingToFileEnabled() {
1255*6777b538SAndroid Build Coastguard Worker return g_logging_destination & LOG_TO_FILE;
1256*6777b538SAndroid Build Coastguard Worker }
1257*6777b538SAndroid Build Coastguard Worker
GetLogFileFullPath()1258*6777b538SAndroid Build Coastguard Worker std::wstring GetLogFileFullPath() {
1259*6777b538SAndroid Build Coastguard Worker if (g_log_file_name)
1260*6777b538SAndroid Build Coastguard Worker return *g_log_file_name;
1261*6777b538SAndroid Build Coastguard Worker return std::wstring();
1262*6777b538SAndroid Build Coastguard Worker }
1263*6777b538SAndroid Build Coastguard Worker #endif
1264*6777b538SAndroid Build Coastguard Worker
1265*6777b538SAndroid Build Coastguard Worker // Used for testing. Declared in test/scoped_logging_settings.h.
1266*6777b538SAndroid Build Coastguard Worker ScopedVmoduleSwitches::ScopedVmoduleSwitches() = default;
1267*6777b538SAndroid Build Coastguard Worker
CreateVlogInfoWithSwitches(const std::string & vmodule_switch)1268*6777b538SAndroid Build Coastguard Worker VlogInfo* ScopedVmoduleSwitches::CreateVlogInfoWithSwitches(
1269*6777b538SAndroid Build Coastguard Worker const std::string& vmodule_switch) {
1270*6777b538SAndroid Build Coastguard Worker // Try get a VlogInfo on which to base this.
1271*6777b538SAndroid Build Coastguard Worker // First ensure that VLOG has been initialized.
1272*6777b538SAndroid Build Coastguard Worker MaybeInitializeVlogInfo();
1273*6777b538SAndroid Build Coastguard Worker
1274*6777b538SAndroid Build Coastguard Worker // Getting this now and setting it later is racy, however if a
1275*6777b538SAndroid Build Coastguard Worker // ScopedVmoduleSwitches is being used on multiple threads that requires
1276*6777b538SAndroid Build Coastguard Worker // further coordination and avoids this race.
1277*6777b538SAndroid Build Coastguard Worker VlogInfo* base_vlog_info = GetVlogInfo();
1278*6777b538SAndroid Build Coastguard Worker if (!base_vlog_info) {
1279*6777b538SAndroid Build Coastguard Worker // Base is |nullptr|, so just create it from scratch.
1280*6777b538SAndroid Build Coastguard Worker return new VlogInfo(/*v_switch_=*/"", vmodule_switch, &g_min_log_level);
1281*6777b538SAndroid Build Coastguard Worker }
1282*6777b538SAndroid Build Coastguard Worker return base_vlog_info->WithSwitches(vmodule_switch);
1283*6777b538SAndroid Build Coastguard Worker }
1284*6777b538SAndroid Build Coastguard Worker
InitWithSwitches(const std::string & vmodule_switch)1285*6777b538SAndroid Build Coastguard Worker void ScopedVmoduleSwitches::InitWithSwitches(
1286*6777b538SAndroid Build Coastguard Worker const std::string& vmodule_switch) {
1287*6777b538SAndroid Build Coastguard Worker // Make sure we are only initialized once.
1288*6777b538SAndroid Build Coastguard Worker CHECK(!scoped_vlog_info_);
1289*6777b538SAndroid Build Coastguard Worker {
1290*6777b538SAndroid Build Coastguard Worker #if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
1291*6777b538SAndroid Build Coastguard Worker // See comments on |g_vlog_info|.
1292*6777b538SAndroid Build Coastguard Worker ScopedLeakSanitizerDisabler lsan_disabler;
1293*6777b538SAndroid Build Coastguard Worker #endif // defined(LEAK_SANITIZER)
1294*6777b538SAndroid Build Coastguard Worker scoped_vlog_info_ = CreateVlogInfoWithSwitches(vmodule_switch);
1295*6777b538SAndroid Build Coastguard Worker }
1296*6777b538SAndroid Build Coastguard Worker previous_vlog_info_ = ExchangeVlogInfo(scoped_vlog_info_);
1297*6777b538SAndroid Build Coastguard Worker }
1298*6777b538SAndroid Build Coastguard Worker
~ScopedVmoduleSwitches()1299*6777b538SAndroid Build Coastguard Worker ScopedVmoduleSwitches::~ScopedVmoduleSwitches() {
1300*6777b538SAndroid Build Coastguard Worker VlogInfo* replaced_vlog_info = ExchangeVlogInfo(previous_vlog_info_);
1301*6777b538SAndroid Build Coastguard Worker // Make sure something didn't replace our scoped VlogInfo while we weren't
1302*6777b538SAndroid Build Coastguard Worker // looking.
1303*6777b538SAndroid Build Coastguard Worker CHECK_EQ(replaced_vlog_info, scoped_vlog_info_);
1304*6777b538SAndroid Build Coastguard Worker }
1305*6777b538SAndroid Build Coastguard Worker
1306*6777b538SAndroid Build Coastguard Worker } // namespace logging
1307