| <!--* freshness: { reviewed: '2026-10-12' } *--> | |
| # Zxdb Common Library (`zxdb/common`) | |
| ## Overview | |
| `//src/developer/debug/zxdb/common` is the lowest layer (Layer 1) of `zxdb`. It | |
| provides foundational error types (`Err`, `ErrOr`), address ranges, binary/LEB | |
| extractors, filesystem/network helpers, `Curl`, and callback joiners without | |
| depending on any other `zxdb` layer. | |
| ## Interface | |
| Public headers expose these foundational types and utilities: | |
| - `zxdb::Err`, `zxdb::ErrType`, `zxdb::ErrOr<T>`, `zxdb::ErrTypeToString`, | |
| `zxdb::ErrToUnwinderError`: Error status and value-or-error wrappers (`err.h`, | |
| `err_or.h`). | |
| - `zxdb::AddressRange`, `zxdb::AddressRangeBeginCmp`, | |
| `zxdb::AddressRangeEndAddrCmp`, `zxdb::AddressRanges`: Half-open memory | |
| address interval and canonical non-overlapping range set (`address_range.h`, | |
| `address_ranges.h`). | |
| - `zxdb::TaggedData`, `zxdb::TaggedDataBuilder`: Byte buffers paired with | |
| per-byte validity tags (`Tag::kValid`, `Tag::kUnknown`) for memory dumps with | |
| unreadable regions (`tagged_data.h`, `tagged_data_builder.h`). | |
| - `zxdb::DataExtractor`: Bounds-checked cursor for reading primitive types, byte | |
| slices, and SLEB128/ULEB128 integers from binary buffers (`data_extractor.h`). | |
| - `zxdb::AppendULeb`: Appends ULEB128-encoded integers to a byte vector | |
| (`leb128.h`). | |
| - `zxdb::JoinCallbacksBase`, `zxdb::JoinCallbacks<T>`, | |
| `zxdb::JoinCallbacks<void>`, `zxdb::JoinErrCallbacks`: Fan-in primitives that | |
| aggregate multiple asynchronous callbacks into one completion callback | |
| (`join_callbacks.h`). | |
| - `zxdb::MakeErrPromise<ResultType>`: Builds a `fpromise::promise` that resolves | |
| immediately to a `zxdb::Err` (`promise.h`). | |
| - `zxdb::CacheDir`: Size-bounded directory manager that prunes | |
| least-recently-used files on access notifications (`cache_dir.h`). | |
| - `zxdb::Curl`: Reference-counted `libcurl` wrapper for synchronous and | |
| asynchronous HTTP/HTTPS transfers (`curl.h`). | |
| - `zxdb::ScopedTempFile`: RAII temporary file creator and deleter | |
| (`scoped_temp_file.h`). | |
| - `zxdb::FuzzyMatcher`: Subsequence line matcher over text streams | |
| (`fuzzy_matcher.h`). | |
| - `WorkerPool`: Multi-threaded task queue (`PostTask`) backed by `std::thread` | |
| workers (`worker_pool.h`). | |
| - `zxdb::int128_t`, `zxdb::uint128_t`, `zxdb::to_string`, `zxdb::to_hex_string`, | |
| `zxdb::to_bin_string<T>`: 128-bit integer types and numeric string formatters | |
| (`int128_t.h`, `string_util.h`). | |
| - `zxdb::CheckedAdd`: Overflow-checked integer addition (`checked_math.h`). | |
| - `zxdb::Reversed`, `zxdb::RefPtrTo`: Range-for reverse iterator adapter and | |
| `fxl::RefPtr<T>` conversion helper (`adapters.h`, `ref_ptr_to.h`). | |
| - `zxdb::ExtractLastFileComponent`, `zxdb::IsPathAbsolute`, | |
| `zxdb::PathEndsWith`, `zxdb::CatPathComponents`, `zxdb::NormalizePath`, | |
| `zxdb::GetFileModificationTime`, `zxdb::PathStartsWith`, | |
| `zxdb::PathRelativeTo`, `zxdb::ExpandAndNormalizePath`: Host filesystem path | |
| manipulation and metadata helpers (`file_util.h`). | |
| - `zxdb::GetSelfPath`, `zxdb::GetEnviron`: Host executable path and process | |
| environment accessors (`host_util.h`). | |
| - `zxdb::ParseHostPort`, `zxdb::Ipv6HostPortIsMissingBrackets`: Host and port | |
| string parsers (`inet_util.h`). | |
| ## Invariants | |
| Callers and implementations must preserve these invariants: | |
| - `zxdb::AddressRanges` stores ranges in canonical form: sorted by start | |
| address, non-overlapping (adjacent ranges stay separate), and non-empty. | |
| - `zxdb::ErrOr<T>` requires that any `Err` passed to its error constructor or | |
| returned by `err()` has `has_error() == true` (`ErrType != kNone`). | |
| - Create `zxdb::Curl` instances with `fxl::MakeRefCounted<Curl>()`, and bracket | |
| all `Curl` usage with `Curl::GlobalInit()` and `Curl::GlobalCleanup()`. | |
| - `zxdb::DataExtractor` never advances its cursor past the buffer end. Failed | |
| reads leave the cursor unchanged, while `Advance` and `Seek` clamp to the | |
| buffer end. | |
| - `zxdb::TaggedData` leaves `tags_` empty when all bytes are valid. Otherwise, | |
| `tags_.size()` equals `bytes_.size()`. | |
| - Create all `zxdb::JoinCallbacksBase` sub-callbacks via `AddCallback()` before | |
| calling `Ready()` or `Abandon()`. `JoinCallbacks<T>` preserves `AddCallback()` | |
| creation order in the result vector. | |
| - `zxdb::PathRelativeTo` requires both input paths to be absolute, and | |
| `zxdb::PathStartsWith` returns `false` if either input path is relative. | |
| ## Side Effects | |
| These utilities produce the following disk, network, and thread side effects: | |
| - `zxdb::CacheDir::NotifyFileAccess` updates file modification times and deletes | |
| least-recently-used files when directory size exceeds `max_size_`. | |
| - `zxdb::Curl::GlobalInit` and `GlobalCleanup` mutate thread-unsafe global | |
| `libcurl` state. `Curl::Perform` runs synchronous or message-loop-driven | |
| HTTP/HTTPS transfers. | |
| - `zxdb::ScopedTempFile` creates and opens a temporary file in `/tmp` on | |
| construction and unlinks it on destruction. | |
| - `zxdb::FuzzyMatcher::MatchesLine` consumes lines from its internal | |
| `std::stringstream`, advancing matcher state across calls. | |
| - `zxdb::TaggedDataBuilder::TakeData` and `zxdb::ErrOr<T>::take_value` move | |
| internal data out of the object. | |
| - `WorkerPool` spawns OS worker threads on construction and blocks to join them | |
| on destruction. | |
| - `zxdb::GetFileModificationTime`, `zxdb::ExpandAndNormalizePath`, | |
| `zxdb::GetSelfPath`, and `zxdb::GetEnviron` query the host filesystem and | |
| process environment. | |
| ## Verification | |
| Run these commands to build and test `zxdb/common`: | |
| - Build: `fx build //src/developer/debug/zxdb/common` | |
| - Test: `fx test zxdb_tests` |