tree: 5dcd9e2eaa318a4e7d6c4bfc87c519c2f19a379c [search]
  1. automation_instruction.cc
  2. automation_instruction.h
  3. automation_instruction_unittests.cc
  4. BUILD.bazel
  5. BUILD.gn
  6. decode_exception.cc
  7. decode_exception.h
  8. decode_exception_unittests.cc
  9. filter_utils.cc
  10. filter_utils.h
  11. filter_utils_unittests.cc
  12. message_reader.cc
  13. message_reader.h
  14. message_unittests.cc
  15. message_writer.cc
  16. message_writer.h
  17. protocol.cc
  18. protocol.h
  19. protocol_unittests.cc
  20. README.md
  21. records.cc
  22. records.h
  23. unwinder_support.cc
  24. unwinder_support.h
src/developer/debug/ipc/README.md

Debug IPC (ipc)

This directory contains the shared wire protocol (debug_ipc) between debug_agent (../debug_agent) and zxdb (../zxdb). External programs should not depend on this directory directly. Debugger clients should use the client library in ../zxdb/client instead.

debug_ipc uses a self-contained binary format so debug_agent can talk to a host machine without high-level runtime dependencies while debugging low-level system state.

Protocol Format

MessageWriter and MessageReader encode wire primitives with these rules:

  • Structs use fixed-size fields in little-endian byte order so little-endian hosts and targets can copy them directly with memcpy.
  • Vectors encode a 32-bit element count followed by each serialized element.
  • Strings encode a 32-bit byte length followed by raw 8-bit characters without a null terminator.

Interface

Public headers expose these protocol constants, records, and helpers:

  • debug_ipc::kCurrentProtocolVersion, debug_ipc::kMinimumProtocolVersion, debug_ipc::kTimestampDefault: Protocol version bounds and default timestamp constants (protocol.h).
  • debug_ipc::MsgHeader, debug_ipc::IsDebugIpcMessageType, debug_ipc::IsDebugIpcNotificationType: Wire message header (MsgHeader::Type) and C++20 concepts for request/reply and notification types (protocol.h).
  • Request and Reply messages (protocol.h): HelloRequest, StatusRequest, KillRequest, AttachRequest, DetachRequest, PauseRequest, ResumeRequest, ProcessTreeRequest, ThreadsRequest, ReadMemoryRequest, and their matching *Reply structs. Also defines AddOrChangeBreakpointRequest, RemoveBreakpointRequest, SysInfoRequest, ThreadStatusRequest, AddressSpaceRequest, ModulesRequest, UpdateFilterRequest, WriteMemoryRequest, and LoadInfoHandleTableRequest. Also defines UpdateGlobalSettingsRequest, SaveMinidumpRequest, ReadRegistersRequest, WriteRegistersRequest, RunBinaryRequest, RunComponentRequest, and RunTestRequest.
  • Notification messages (protocol.h): NotifyProcessStarting, NotifyProcessExiting, NotifyThreadStarting, NotifyThreadExiting, NotifyException, NotifyModules, NotifyIO, NotifyLog, NotifyComponentDiscovered, NotifyComponentStarting, NotifyComponentExiting, NotifyTestExited, NotifyFilterCreated.
  • Protocol records (records.h): ExceptionType, ExceptionStrategy, ProcessThreadId, ExceptionRecord, ComponentInfo, TaskType, ProcessTreeRecord, StackFrame, ThreadRecord, AddressRegion, ProcessRecord, MemoryBlock, ProcessBreakpointSettings, and Stop. Also defines BreakpointType, BreakpointSettings, BreakpointStats, Module, AttachConfig, InfoHandleVmo, InfoHandle, FilterConfig, Filter (Filter::Identifier, Filter::Originator), MatchedTask, and FilterMatch.
  • Serialization (message_reader.h, message_writer.h): debug_ipc::MessageReader, debug_ipc::MessageWriter, debug_ipc::Serialize, debug_ipc::Deserialize.
  • Filter utilities (filter_utils.h): debug_ipc::FilterMatches, debug_ipc::ResolveFilterType, debug_ipc::GetFilterForId, debug_ipc::GenerateFilterIdValue, debug_ipc::GetAttachConfigsForFilterMatches.
  • Exception decoding (decode_exception.h): debug_ipc::X64DebugRegs, debug_ipc::DecodeX64Exception, debug_ipc::DecodeArm64Exception, debug_ipc::DecodeRiscv64Exception.
  • Breakpoint automation (automation_instruction.h): debug_ipc::AutomationOperandKind, debug_ipc::AutomationOperand, debug_ipc::AutomationConditionKind, debug_ipc::AutomationCondition, debug_ipc::AutomationInstructionKind, debug_ipc::AutomationInstruction.
  • Unwinder conversions (unwinder_support.h): debug_ipc::ConvertRegisters, debug_ipc::ConvertFrames, debug_ipc::ConvertTrust.

Invariants

Callers and protocol definitions must preserve these invariants:

  • protocol.h and records.h pack all wire structs to 8-byte alignment via #pragma pack(push, 8).
  • The ABI compatibility window spans [kMinimumProtocolVersion, kCurrentProtocolVersion]. Version-gated fields serialize conditionally (if (ver >= ...)), and messages with kSupportedSinceVersion return an empty byte vector on older versions.
  • The first 4 bytes of every serialized message store the total byte size (including MsgHeader), which MessageWriter::MessageComplete() writes on completion.
  • HelloReply starts with a fixed 64-bit signature (0x7a7864624950433e, ASCII "zxdbIPC>"). Readers deserialize HelloReply at version 0 first to read the version, and then deserialize again at the negotiated version.
  • Notification messages always set transaction_id to 0 in MsgHeader and satisfy IsDebugIpcNotificationType by providing a timestamp field.
  • Filter::Identifier stores Filter::Originator in bits 24 to 31 and a client-assigned 24-bit ID in bits 0 to 23. Both kInvalidFilterId and kDebugAgentInternalBreakpointId equal static_cast<uint32_t>(-1).
  • When multiple filters match one task in GetAttachConfigsForFilterMatches, the highest AttachConfig::Priority (kStrong > kWeak > kMinimal) wins.
  • In BreakpointSettings::locations, if any ProcessBreakpointSettings entry specifies a non-zero thread KOID, it must be the only entry.

Side Effects

These functions produce the following state and callback side effects:

  • ResolveFilterType truncates its pattern string argument in place to 31 characters (Zircon's process name limit) for kProcessName and kProcessNameSubstr.
  • GenerateFilterIdValue advances a function-local static random number engine (std::independent_bits_engine) to generate 24-bit IDs and asserts that the upper 8 bits are zero.
  • MessageWriter::MessageComplete() writes the buffer size into the first 4 bytes and moves the internal buffer out, leaving the writer empty.
  • MessageReader::SerializeBytes advances the read offset or sets the sticky has_error_ flag when fewer bytes remain than requested.
  • DecodeX64Exception and DecodeArm64Exception call fetch_debug_regs or fetch_esr callbacks on demand to disambiguate hardware breakpoints, watchpoints, and single-step traps.

Verification

Run these commands to build and test ipc:

  • Build: fx build //src/developer/debug/ipc
  • Test: fx test zxdb_tests