Skip to content

Report malformed remote protocol data instead of defaulting to zero #1176

Description

@xusheng6

Follow-up to #1164 / #1166.

#1166 stops the crash by parsing remote stub data with a non-throwing helper that returns 0 on malformed input. That means a corrupt packet silently becomes a valid-looking answer — a bad thread id turns into thread 0, and we then show the user the wrong thread's registers with no indication anything is wrong. Accepted deliberately to keep the fix local during feature freeze.

The session should instead end deliberately, reporting the offending field and data. An attempt at that was dropped from #1166 (commit f7a1961); review of it showed what a real implementation needs:

  • Wider catch boundary than ExecuteAdapterAndWait. NotifyStopped runs after it returns and refreshes caches; HandleSpontaneousAdapterStop has no boundary; WorkerThreadMain runs tasks bare, so an escape is std::terminate; InvokeBackendCommand reaches monitor-command decoding directly from the API/FFI.
  • Real transport teardown. A synthetic TargetExited only updates BN-side state. The teardown lives in the adapter (m_socket->Kill(), delete m_rspConnector, InvalidateCache). Also m_adapter is never reset on any session end today, so CreateDebugAdapter reuses it.
  • RAII on the stop channel. An exception between setting and clearing m_inAdapterWait leaves a stale pending stop that swallows later adapter events.
  • Ignore unrecognized stop-reply fields. PacketToUnorderedMap parses every key:value as hex, but the spec requires unknown pairs be ignored and defines non-hex values we advertise support for (replaylog:begin, exec:<hex pathname>, fork/vfork pPID.TID). Parsing only the keys we consume is both spec-correct and smaller.

Outstanding regardless of the exception work:

  • esrevenadapter.cpp still uses raw std::stoull (:1797, :2249, :2251) and std::stoi (:2309) — the call sites Malformed remote stub data can crash via unguarded std::stoi/stoull #1164 describes.
  • PacketToUnorderedMap: T05thread:1:garbage; splits into three tokens and falls through to packet_map[key] = 0; values are truncated to 16 chars before validation, so trailing garbage disappears.
  • GdbMiAdapter::ReadMemory checks from_chars().ec but not full consumption, so "aZ" parses as 0x0a; odd-length replies truncate; hard errors return an all-zero buffer indistinguishable from valid memory.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions