Debugging Wrapper

The /lib/dbug.hoon agent wrapper adds support to view the state of a Gall agent. It is applied to an existing Gall agent as a single drop-in line, %- agent:dbug.

Before we look at the code, let's consider the functionality it exposes. By supplying %- agent:dbug, an associated +dbug generator can be invoked against the agent state.

For instance, using the %azimuth agent, we can expose the current state of the agent:

> :azimuth +dbug
[ %7
  url=~.
  net=%default
  refresh=~m5
  whos={}
  nas=[%0 points={} operators={} dns=<||>]
  own={}
  spo={}
  logs=~
  sap=[%0 id=[hash=0x0 number=0] nas=[%0 points={} operators={} dns=<||>] owners={} sponsors={}]
]

> :azimuth +dbug %bowl
>   [ [our=~zod src=~zod dap=%azimuth]
  [wex={} sup={}]
  act=3
    eny
  0v1rn.n49dr.2u8t5.h7be5.6dcq7.9hon5.6m3pr.3hcb8.u7tmv.qddpq.kent7.1ftc7.9tao6.hfsht.4i0c3.ak3t7.t8d8j.nn4eb.b7eh3.4d5pr.t8ftg
  now=~2023.2.3..20.03.23..f60e
  byk=[p=~zod q=%base r=[%da p=~2023.1.26..02.41.25..926a]]
]

> :azimuth +dbug [%incoming ~]
>   no matching subscriptions

> :azimuth +dbug [%state '(lent whos)']
>   0

There are four actions exposed by the wrapper via the +dbug generator:

  1. :app +dbug exposes the entire state, just dumping the current agent state.

  2. :app +dbug %bowl shows the agent's $bowl. The Gall $bowl consists of:

  3. :app +dbug [%state 'hoon'] exposes data in the state, including evaluated Hoon like (lent values).

  4. :app +dbug [?(%incoming outgoing) specifics] reveals details about the subscriptions.

The Code

/gen/dbug.hoon
/lib/dbug.hoon

As we examine this code, there are two particularly interesting aspects:

  1. How /lib/dbug.hoon modifies an agent's arms by adding functionality over the top of them.

  2. How /gen/dbug.hoon utilizes the modified arms with an elegant and simple invocation.

There is also extensive use of $tank/$tang formatted error messaging.

How the library works

By applying this door builder using %- censig, the +on-poke and +on-peek arms can be modified. (In fact, all of the arms can be modified but most of the arms are pass-throughs to the modified agent.)

+on-poke

++on-poke

The +on-poke arm has several branches added to it after a check to see whether it is being used through the +dbug generator. If it isn't (as determined by the associated $mark), then the poke is passed through to the base agent.

The following ?- wuthep handles the input arguments: %state is the most interesting code in this library. The code first checks whether the base agent has a /dbug/state peek endpoint already (in which case it passes it through), otherwise it evaluates the requested Hoon expression against the agent's state (obtained via +on-save:ag).

This branch includes the use of a rare =? tiswut conditional leg change and the reversed =/ tisfas, =; tismic. There is also some direct compilation of $cords taking place:

  • +sell is a $vase pretty-printer.

  • +slop conses two $vases together as a cell.

  • +slap compiles a Hoon expression and produces a $vase of the result.

  • +ream parses a $cord to a Hoon expression.

+on-peek

++on-peek

The +on-peek arm adds several peek endpoints which expose the state (via +on-save:ag) and the subscriptions.

How the generator works

The generator explicitly injects the %dbug mark in its return +cask ([mark noun]). This is a valid if uncommon operation, and it works here because the mark is never used as a transforming gate but only as a marker to see whether the arms need to pass through the values. The no-argument input is routed through the %state with an empty $cord.

Library authors should consider augmenting developer capabilities by exposing appropriate functionality using a wrapper agent similar to /lib/dbug.

Last updated