Summary

  • RFC 909 proposed a network Loader Debugger Protocol in July 1984. A host could load, dump, inspect and control a target such as a packet switch, PAD or gateway. Its authors warned that a breakpoint that stopped the target while instructions crossed the network could prevent it from meeting real-time service demands.
  • The proposal split target implementations into a small loader/dumper, a basic debugger and a full debugger. At the full level, conditional breakpoint commands could live and run on the target itself. That reduced dependence on a round trip at the critical moment while making debugging logic part of the machine's operating burden.

The instrument must not become the outage

The image of a debugger is a machine stopped at an exact line. For a programmer working on an isolated test box, that pause is useful. For a gateway serving live traffic, it can be the fault. Christopher Welles and Walter Milliken put the problem plainly in RFC 909: if a breakpoint halts the target while the host sends further breakpoint instructions, the target may fail to serve the real-time demands of its application. A tool meant to diagnose a network machine could interrupt the network machine.

Their July 1984 document called the tool the Loader Debugger Protocol, or LDP. It was an application-layer proposal for loading programs, dumping state and debugging target machines across a network. The targets named in the text include packet switch nodes, packet assembly/disassembly devices and gateways. A host machine controlled the session. The specification ran to more than forty commands, with separate classes for protocol exchange, data transfer, management, control and breakpoints. This was not a tiny “peek into memory” service. It offered a remote operator a substantial control surface.

The paper did not assume every target could afford that surface. A boot loader may have little code space; its essential jobs are to receive or move data, start execution and report an exception. A full debugger needs much more machinery. LDP therefore described three cumulative implementation levels. LOADER_DUMPER supplied the small base. BASIC_DEBUGGER added control and ordinary breakpoints. FULL_DEBUGGER added finite-state-machine breakpoint commands, with watchpoints optional. The target announced its level in HELLO_REPLY after the host established a transport connection. The operator could discover the actual service offered before sending commands the machine had never implemented.

A breakpoint with instructions already aboard

A normal breakpoint in the RFC stops its target object and reports status to the host. The human or program at the host can then issue more commands. The target has already paused. The full debugger's alternative was an FSM breakpoint: the host preloaded conditional command lists into the target. When the selected address was executed, the target checked its local state and ran the appropriate list. The list could examine data, use a counter or pointers, change the breakpoint's state and report an event without waiting for a fresh command to cross the network at that instant.

That local decision did not make debugging free. The target had to store the command lists and the state variable, and execute them on the event path. The RFC acknowledged possible limits on the number of breakpoints, states, conditions and list sizes. A breakpoint could still stop or control an object; the proposal did not promise that every debug action would leave all traffic untouched. Its sharper design move was to move the time-critical decision to the place where the event occurred. The remote host prepared the rule; the target applied it while it still had the facts in hand.

The association was precise: each breakpoint or watchpoint belonged to one debugger connection and one address. That mattered because the protocol also wanted to support several users debugging the same target. A target with multiple connections had to keep their commands and objects apart. Remote inspection was no longer a single omniscient console plugged into a box. It was a set of sessions competing for limited state inside the box being observed.

A dead host can hold the only door

RFC 909 exposed another availability trap in session management. The target waited passively while a host opened the transport connection, sent HELLO, received HELLO_REPLY and eventually closed the connection. On closure the target should release its session resources. But a host might crash midway. If the target supported only one connection and could not recognize a half-dead session, the dead debugger could monopolize the single control slot. The authors proposed detecting failed connections or allowing a new connection to displace an inactive one. Even that escape required a way to listen for new connections while the old channel existed.

The transport was a supporting choice, not the article's hero. RFC 909 recommended the Reliable Data Protocol of RFC 908 and allowed TCP at greater resource cost. It required reliable, sequenced messages and separation between connections. A transport message could contain several LDP commands, but each command had to fit wholly within one message. Those rules carried instructions to the target; they could not decide whether a breakpoint should run locally, whether a dead session should keep its slot, or which target feature level was actually present.

RFC 909 was published as an experimental proposal. Its text is evidence of a design problem and a specified answer, not a census of deployed gateways. The problem remains striking within its own 1984 setting: the more power a remote debugger gains over a live network machine, the more carefully that power must be made to coexist with the machine's ordinary work. Freezing a gateway may make the fault easy to inspect. It also makes the debugger part of what everyone else experiences.

Sources