blob: a27f8807522b7f1e1f96e930d19bacef6bab5946 [file] [view]
<!--* freshness: { reviewed: '2026-10-12' } *-->
# Shared Debugger Logging (`logging`)
## Overview
`//src/developer/debug/shared/logging` provides the logging infrastructure
shared by `zxdb` and `debug_agent`. It supports severity-based general logging
with pluggable backends, category-filtered hierarchical debug logging with
duration tracking, and source-location capture.
## Interface
Public headers expose these macros, enums, and classes:
- `LOGS(severity)`, `DEBUG_LOG(category)`, `DEBUG_LOG_WITH_LOCATION(category,
location)`: Macros that emit severity logs and category-filtered scoped debug
logs (`logging.h`, `debug.h`).
- `FROM_HERE`, `FROM_HERE_NO_FUNC`, `STRINGIFY(x, y)`, `STRINGIFY_INTERNAL(x,
y)`: Source location and preprocessor stringification macros
(`file_line_function.h`).
- `debug::LogSeverity`: Severity enum (`kInfo`, `kWarn`, `kError`)
(`logging.h`).
- `debug::LogStatement`: Scoped log accumulator (`LogStatement`,
`~LogStatement`, `stream`) (`logging.h`).
- `debug::LogBackend`: Pluggable sink interface for general log statements
(`WriteLog`, `Set`, `Unset`, `~LogBackend`) (`logging.h`).
- `debug::LogCategory`: Category enum (`debug.h`) for `kAgent`, `kArchArm64`,
`kArchx64`, `kBreakpoint`, `kJob`, `kMessageLoop`, `kProcess`, `kRemoteAPI`,
`kSession`, `kSetting`, `kTest`, `kTiming`, `kThread`, and `kWatchpoint`. Also
includes `kWorkerPool`, `kDebugAdapter`, `kBuildIDIndex`, `kProcessSymbols`,
`kModuleSymbols`, `kSystemSymbols`, `kDownloadManager`, `kAll`, and `kNone`.
- `debug::SetDebugLogging(bool activate)`, `debug::IsDebugLoggingActive()`,
`debug::SetLogCategories(std::initializer_list<LogCategory> categories)`:
Functions that control debug logging activation and active category filters
(`debug.h`).
- `debug::DebugLogStatement`: Scoped hierarchical debug log entry with duration
tracking (`DebugLogStatement`, `~DebugLogStatement`, `stream`, `origin`,
`category`, `start_time`) (`debug.h`).
- `debug::FileLineFunction`: Value type holding source file, line number, and
function name (`FileLineFunction`, `is_valid`, `file`, `line`, `function`,
`ToString`, `operator<`, `operator==`, `operator!=`) (`file_line_function.h`).
## Invariants
Callers and implementations must preserve these invariants:
- `FileLineFunction` stores raw `const char*` pointers for file and function
names without taking ownership. Callers must ensure string literals outlive
the `FileLineFunction` instance.
- `FileLineFunction::is_valid()` requires a non-null `file_` pointer and `line_
> 0`.
- `FileLineFunction` comparison operators (`<`, `==`, `!=`) compare the line
number and `file_` pointer address (not string content) and ignore
`function_`.
- `DEBUG_LOG_WITH_LOCATION` declares a block-scoped `DebugLogStatement` tied to
`__LINE__`. Nested debug logs in the same scope form a parent-child tree that
flushes when the root `DebugLogStatement` destructs.
- A `LogCategory` is active when `fuchsia_logging` `Trace` severity is active,
or when `Debug` severity is active and the active set contains `kAll` or that
category.
- `PushLogEntry` and `PopLogEntry` lock `gLogMutex` before mutating the global
debug log tree. `LogBackend::Set`, `LogBackend::Unset`, and `SetLogCategories`
update global state without a mutex.
## Side Effects
These logging primitives produce the following global and I/O side effects:
- `LogStatement::~LogStatement()` sends the formatted string to `log_backend`
via `WriteLog()` and writes to `fuchsia_logging::LogMessage` when
`log_enable_syslog` is `true`.
- `LogBackend::Set()` and `LogBackend::Unset()` update the module-global
`log_backend` pointer and `log_enable_syslog` flag.
- `SetDebugLogging()` re-initializes process-wide Fuchsia syslog settings via
`fuchsia_logging::LogSettingsBuilder::BuildAndInitialize()`.
- `SetLogCategories()` updates the static active `LogCategory` set in
`debug.cc`.
- `DebugLogStatement` construction and destruction update the global log tree
(`gRootSlot`, `gCurrentSlot`) under `gLogMutex`. When the root statement
destructs, it writes the tree via `FX_LOGS(DEBUG)` on Fuchsia or `fprintf` to
`stderr` on host platforms.
## Verification
Run this command to build `shared/logging`:
- Build: `fx build //src/developer/debug/shared/logging`