// Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef PARTITION_ALLOC_PARTITION_ALLOC_BASE_LOGGING_H_ #define PARTITION_ALLOC_PARTITION_ALLOC_BASE_LOGGING_H_ #include <cassert> #include <cstddef> #include <cstdint> #include "partition_alloc/build_config.h" #include "partition_alloc/buildflags.h" #include "partition_alloc/partition_alloc_base/compiler_specific.h" #include "partition_alloc/partition_alloc_base/component_export.h" #include "partition_alloc/partition_alloc_base/log_message.h" // TODO(crbug.com/40158212): Need to update the description, because logging for // PA standalone library was minimized. // // Optional message capabilities // ----------------------------- // Assertion failed messages and fatal errors are displayed in a dialog box // before the application exits. However, running this UI creates a message // loop, which causes application messages to be processed and potentially // dispatched to existing application windows. Since the application is in a // bad state when this assertion dialog is displayed, these messages may not // get processed and hang the dialog, or the application might go crazy. // // Therefore, it can be beneficial to display the error dialog in a separate // process from the main application. When the logging system needs to display // a fatal error dialog box, it will look for a program called // "DebugMessage.exe" in the same directory as the application executable. It // will run this application with the message as the command line, and will // not include the name of the application as is traditional for easier // parsing. // // The code for DebugMessage.exe is only one line. In WinMain, do: // MessageBox(NULL, GetCommandLineW(), L"Fatal Error", 0); // // If DebugMessage.exe is not found, the logging code will use a normal // MessageBox, potentially causing the problems discussed above. // Instructions // ------------ // // Make a bunch of macros for logging. The way to log things is to stream // things to PA_LOG(<a particular severity level>). E.g., // // PA_LOG(INFO) << "Found " << num_cookies << " cookies"; // // You can also do conditional logging: // // PA_LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; // // The CHECK(condition) macro is active in both debug and release builds and // effectively performs a PA_LOG(FATAL) which terminates the process and // generates a crashdump unless a debugger is attached. // // There are also "debug mode" logging macros like the ones above: // // PA_DLOG(INFO) << "Found cookies"; // // PA_DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; // // All "debug mode" logging is compiled away to nothing for non-debug mode // compiles. PA_LOG_IF and development flags also work well together // because the code can be compiled away sometimes. // // We also have // // PA_LOG_ASSERT(assertion); // PA_DLOG_ASSERT(assertion); // // which is syntactic sugar for PA_{,D}LOG_IF(FATAL, assert fails) << assertion; // // There are "verbose level" logging macros. They look like // // PA_VLOG(1) << "I'm printed when you run the program with --v=1 or more"; // PA_VLOG(2) << "I'm printed when you run the program with --v=2 or more"; // // These always log at the INFO log level (when they log at all). // // There's also PA_VLOG_IS_ON(n) "verbose level" condition macro. To be used as // // if (PA_VLOG_IS_ON(2)) { // // do some logging preparation and logging // // that can't be accomplished with just PA_VLOG(2) << ...; // } // // There is also a PA_VLOG_IF "verbose level" condition macro for sample // cases, when some extra computation and preparation for logs is not // needed. // // PA_VLOG_IF(1, (size > 1024)) // << "I'm printed when size is more than 1024 and when you run the " // "program with --v=1 or more"; // // We also override the standard 'assert' to use 'PA_DLOG_ASSERT'. // // Lastly, there is: // // PA_PLOG(ERROR) << "Couldn't do foo"; // PA_DPLOG(ERROR) << "Couldn't do foo"; // PA_PLOG_IF(ERROR, cond) << "Couldn't do foo"; // PA_DPLOG_IF(ERROR, cond) << "Couldn't do foo"; // PA_PCHECK(condition) << "Couldn't do foo"; // PA_DPCHECK(condition) << "Couldn't do foo"; // // which append the last system error to the message in string form (taken from // GetLastError() on Windows and errno on POSIX). // // The supported severity levels for macros that allow you to specify one // are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. // // Very important: logging a message at the FATAL severity level causes // the program to terminate (after the message is logged). // // There is the special severity of DFATAL, which logs FATAL in DCHECK-enabled // builds, ERROR in normal mode. // // Output is formatted as per the following example: // [VERBOSE1:drm_device_handle.cc(90)] Succeeded // authenticating /dev/dri/card0 in 0 ms with 1 attempt(s) // // The colon separated fields inside the brackets are as follows: // 1. The log level // 2. The filename and line number where the log was instantiated // // Additional logging-related information can be found here: // https://chromium.googlesource.com/chromium/src/+/main/docs/linux/debugging.md#Logging namespace partition_alloc::internallogging // namespace partition_alloc::internal::logging #endif // PARTITION_ALLOC_PARTITION_ALLOC_BASE_LOGGING_H_