#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "base/logging.h"
#ifdef BASE_CHECK_H_
#error "logging.h should not include check.h"
#endif
#include <limits.h>
#include <stdint.h>
#include <algorithm>
#include <atomic>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <memory>
#include <ostream>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
#include "base/base_export.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/containers/stack.h"
#include "base/debug/alias.h"
#include "base/debug/crash_logging.h"
#include "base/debug/debugger.h"
#include "base/debug/stack_trace.h"
#include "base/debug/task_trace.h"
#include "base/functional/callback.h"
#include "base/immediate_crash.h"
#include "base/no_destructor.h"
#include "base/not_fatal_until.h"
#include "base/path_service.h"
#include "base/pending_task.h"
#include "base/posix/eintr_wrapper.h"
#include "base/process/process_handle.h"
#include "base/scoped_clear_last_error.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/common/task_annotator.h"
#include "base/test/scoped_logging_settings.h"
#include "base/threading/platform_thread.h"
#include "base/trace_event/base_tracing.h"
#include "base/vlog.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "third_party/abseil-cpp/absl/base/internal/raw_logging.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#if !BUILDFLAG(IS_NACL)
#include "base/auto_reset.h"
#include "base/debug/crash_logging.h"
#endif
#if defined(LEAK_SANITIZER) && !BUILDFLAG(IS_NACL)
#include "base/debug/leak_annotations.h"
#endif
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include <io.h>
#include "base/win/win_util.h"
typedef HANDLE FileHandle;
#define write …
#define STDERR_FILENO …
#endif
#if BUILDFLAG(IS_APPLE)
#include <CoreFoundation/CoreFoundation.h>
#include <mach-o/dyld.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <os/log.h>
#endif
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <errno.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include "base/posix/safe_strerror.h"
#if BUILDFLAG(IS_NACL)
#include <sys/time.h>
#endif
#define MAX_PATH …
FileHandle;
#endif
#if BUILDFLAG(IS_ANDROID)
#include <android/log.h>
#include "base/android/jni_android.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "base/files/scoped_file.h"
#endif
#if BUILDFLAG(IS_FUCHSIA)
#include "base/fuchsia/scoped_fx_logger.h"
#endif
namespace logging {
namespace {
int g_min_log_level = …;
std::atomic<VlogInfo*> g_vlog_info = …;
VlogInfo* GetVlogInfo() { … }
bool InitializeVlogInfo(VlogInfo* vlog_info) { … }
VlogInfo* ExchangeVlogInfo(VlogInfo* vlog_info) { … }
std::unique_ptr<VlogInfo> VlogInfoFromCommandLine() { … }
void MaybeInitializeVlogInfo() { … }
const char* const log_severity_names[] = …;
static_assert …;
const char* log_severity_name(int severity) { … }
uint32_t g_logging_destination = …;
#if BUILDFLAG(IS_CHROMEOS)
LogFormat g_log_format = LogFormat::LOG_FORMAT_SYSLOG;
#endif
#if BUILDFLAG(IS_FUCHSIA)
base::ScopedFxLogger& GetScopedFxLogger() {
static base::NoDestructor<base::ScopedFxLogger> logger;
return *logger;
}
#endif
const int kAlwaysPrintErrorLevel = …;
PathString;
PathString* g_log_file_name = …;
FileHandle g_log_file = …;
bool g_log_process_id = …;
bool g_log_thread_id = …;
bool g_log_timestamp = …;
bool g_log_tickcount = …;
const char* g_log_prefix = …;
bool show_error_dialogs = …;
base::stack<LogAssertHandlerFunction>& GetLogAssertHandlerStack() { … }
LogMessageHandlerFunction g_log_message_handler = …;
uint64_t TickCount() { … }
void DeleteFilePath(const PathString& log_name) { … }
PathString GetDefaultLogFile() { … }
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
base::Lock& GetLoggingLock() { … }
#endif
bool InitializeLogFileHandle() { … }
void CloseFile(FileHandle log) { … }
void CloseLogFileUnlocked() { … }
#if BUILDFLAG(IS_FUCHSIA)
inline FuchsiaLogSeverity LogSeverityToFuchsiaLogSeverity(
LogSeverity severity) {
switch (severity) {
case LOGGING_INFO:
return FUCHSIA_LOG_INFO;
case LOGGING_WARNING:
return FUCHSIA_LOG_WARNING;
case LOGGING_ERROR:
return FUCHSIA_LOG_ERROR;
case LOGGING_FATAL:
return FUCHSIA_LOG_ERROR;
}
if (severity > -3) {
return FUCHSIA_LOG_DEBUG;
}
return FUCHSIA_LOG_TRACE;
}
#endif
void WriteToFd(int fd, const char* data, size_t length) { … }
void SetLogFatalCrashKey(LogMessage* log_message) { … }
std::string BuildCrashString(const char* file,
int line,
const char* message_without_prefix) { … }
void TraceLogMessage(const char* file, int line, const std::string& message) { … }
}
#if BUILDFLAG(DCHECK_IS_CONFIGURABLE)
BASE_EXPORT logging::LogSeverity LOGGING_DCHECK = LOGGING_ERROR;
#endif
std::ostream* g_swallow_stream;
bool BaseInitLoggingImpl(const LoggingSettings& settings) { … }
void SetMinLogLevel(int level) { … }
int GetMinLogLevel() { … }
bool ShouldCreateLogMessage(int severity) { … }
bool ShouldLogToStderr(int severity) { … }
int GetVlogVerbosity() { … }
int GetVlogLevelHelper(const char* file, size_t N) { … }
void SetLogItems(bool enable_process_id, bool enable_thread_id,
bool enable_timestamp, bool enable_tickcount) { … }
void SetLogPrefix(const char* prefix) { … }
void SetShowErrorDialogs(bool enable_dialogs) { … }
namespace {
[[noreturn]] void AbslAbortHook(const char* file,
int line,
const char* buf_start,
const char* prefix_end,
const char* buf_end) { … }
}
void RegisterAbslAbortHook() { … }
ScopedLogAssertHandler::ScopedLogAssertHandler(
LogAssertHandlerFunction handler) { … }
ScopedLogAssertHandler::~ScopedLogAssertHandler() { … }
void SetLogMessageHandler(LogMessageHandlerFunction handler) { … }
LogMessageHandlerFunction GetLogMessageHandler() { … }
#if !defined(NDEBUG)
void DisplayDebugMessageInDialog(const std::string& str) { … }
#endif
LogMessage::LogMessage(const char* file, int line, LogSeverity severity)
: … { … }
LogMessage::LogMessage(const char* file, int line, const char* condition)
: … { … }
LogMessage::~LogMessage() { … }
void LogMessage::Flush() { … }
std::string LogMessage::BuildCrashString() const { … }
void LogMessage::Init(const char* file, int line) { … }
void LogMessage::HandleFatal(size_t stack_start,
const std::string& str_newline) const { … }
LogMessageFatal::~LogMessageFatal() { … }
#if BUILDFLAG(IS_WIN)
typedef DWORD SystemErrorCode;
#endif
SystemErrorCode GetLastSystemErrorCode() { … }
BASE_EXPORT std::string SystemErrorCodeToString(SystemErrorCode error_code) { … }
#if BUILDFLAG(IS_WIN)
Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file,
int line,
LogSeverity severity,
SystemErrorCode err)
: LogMessage(file, line, severity), err_(err) {}
Win32ErrorLogMessage::~Win32ErrorLogMessage() {
AppendError();
}
void Win32ErrorLogMessage::AppendError() {
base::ScopedClearLastError scoped_clear_last_error;
stream() << ": " << SystemErrorCodeToString(err_);
DWORD last_error = err_;
base::debug::Alias(&last_error);
}
Win32ErrorLogMessageFatal::~Win32ErrorLogMessageFatal() {
AppendError();
Flush();
base::ImmediateCrash();
}
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
ErrnoLogMessage::ErrnoLogMessage(const char* file,
int line,
LogSeverity severity,
SystemErrorCode err)
: … { … }
ErrnoLogMessage::~ErrnoLogMessage() { … }
void ErrnoLogMessage::AppendError() { … }
ErrnoLogMessageFatal::~ErrnoLogMessageFatal() { … }
#endif
void CloseLogFile() { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
FILE* DuplicateLogFILE() {
if ((g_logging_destination & LOG_TO_FILE) == 0 || !InitializeLogFileHandle())
return nullptr;
int log_fd = fileno(g_log_file);
if (log_fd == -1)
return nullptr;
base::ScopedFD dup_fd(dup(log_fd));
if (dup_fd == -1)
return nullptr;
FILE* duplicate = fdopen(dup_fd.get(), "a");
if (!duplicate)
return nullptr;
std::ignore = dup_fd.release();
return duplicate;
}
#endif
#if BUILDFLAG(IS_WIN)
HANDLE DuplicateLogFileHandle() {
if (!(g_logging_destination & LOG_TO_FILE) || !g_log_file ||
g_log_file == INVALID_HANDLE_VALUE) {
return nullptr;
}
HANDLE duplicate = nullptr;
if (!::DuplicateHandle(::GetCurrentProcess(), g_log_file,
::GetCurrentProcess(), &duplicate, 0,
TRUE, DUPLICATE_SAME_ACCESS)) {
return nullptr;
}
return duplicate;
}
#endif
ScopedLoggingSettings::ScopedLoggingSettings()
: … { … }
ScopedLoggingSettings::~ScopedLoggingSettings() { … }
#if BUILDFLAG(IS_CHROMEOS)
void ScopedLoggingSettings::SetLogFormat(LogFormat log_format) const {
g_log_format = log_format;
}
#endif
void RawLog(int level, const char* message) { … }
#undef write
#if BUILDFLAG(IS_WIN)
bool IsLoggingToFileEnabled() {
return g_logging_destination & LOG_TO_FILE;
}
std::wstring GetLogFileFullPath() {
if (g_log_file_name)
return *g_log_file_name;
return std::wstring();
}
#endif
ScopedVmoduleSwitches::ScopedVmoduleSwitches() = default;
VlogInfo* ScopedVmoduleSwitches::CreateVlogInfoWithSwitches(
const std::string& vmodule_switch) { … }
void ScopedVmoduleSwitches::InitWithSwitches(
const std::string& vmodule_switch) { … }
ScopedVmoduleSwitches::~ScopedVmoduleSwitches() { … }
}