We designed, wrote and named a debugger after Peter Deutsch’s DDT, an ancestor of gdb. The semantics was a good fit but the syntax was arcane. An instance of DDT recognized just one domain and did its work by holding the domain key to that domain. The domain key gives DDT all of the authority normally wielded over a subject program. DDT runs outside the address space of its subject. We will call the person who is debugging the code with DDT the user in this note. There is an order on the DDT object to produce a synthetic domain key that will serve most purposes.
DDT can start, stop and single step the program. The 370 has convenient hardware to set break points without modifying memory, and several other execution surveillance hooks. These are supported by the kernel and available via the domain key. DDT makes these functions available to the user in a convenient way.
There are two ways that a DDT can come into existence for a domain. The fundamental way is by a creator that would take as arguments:
Alternatively a production domain is likely to have a Virtual Domain Keeper (VDK) whose invocation causes a DDT instance to be created upon a domain fault. The window that this DDT gets depends on how the VDK was created. No programmer with authority to examine this code and state may be immediately available and at a terminal. Keykos is persistent and the situation would last until a suitable programmer appeared.
This hard nose attitude toward security was ameliorated by a strong bias towards unit test. The programmer could debug his new code assuming that the objects that it employed were older, well tested and performed to spec. Most objects upon which new application are built have orders (methods) to query state without changing it. DDT has commands to invoke objects available to the subject code. When foundation objects appeared to be broken one recourse is to send mail to the implementer of the object along with the start key to the domain holding the state in dispute. The programmer with legitimate access to the suspect domain would have access to its domain creator and, with synergy, derive the domain key, create a DDT and peer inside, perhaps to find a bug or explain why the state was valid.
This pattern was often too inconvenient and we invented families of domain creators for each of which there is a can opener. A can opener will try to open a domain by invoking each domain creator in the family. If it succeeds it instals a DDT and reports the real type (brander) of the opened object.
DDT can place the domain is a state where it stops upon each key invocation. A canned command sequence will then display the message of the invocation. Single stepping the domain at that point allows display of the returned message.
DDT includes a rudimentary yet general command system. It can invoke a directory that it was born with which might be the user’s personal directory. DDT provides a few general slots to keys for use that the user may wish.
The introduction to a note on layering covers some of the debugging patterns we used.