A debuglet is the small WebAssembly program an executor runs for one measurement. Debuglets are WASI Preview 1 command modules. Their output becomes the measurement output that a client reads with dbl logs or the API.
make wasm SAMPLE_DIR=examples/debuglets/go/hello-local
dbl run --wasm examples/debuglets/go/hello-local/debuglet.wasm --waitThe examples show supported patterns. Build Go debuglets for GOOS=wasip1 GOARCH=wasm and import github.com/netsec-ethz/debuglet/pkg/debuglet when you need Debuglet network operations.
A debuglet has no host filesystem or ordinary host sockets. The executor provides the network operations allowed by the submitted and operator policies. It enforces the job's time and bandwidth budgets. Legacy Connect* calls end the debuglet on host failures. The recoverable socket API below lets a diagnostic handle transport failures and continue within the same budgets.
The stable host ABI is debuglet-go-wasi-imports-v1. The Go package hides its low-level imports behind familiar connection types. Use the package API and examples rather than binding the ABI directly.
Use Dial or DialTimeout when the diagnostic needs to recover from a timeout,
reset or refused connection. They return a Socket implementing
io.ReadWriteCloser; its Write returns (n, err). Existing Connect* functions
return the original Conn and keep their existing behavior.
s, err := debuglet.DialTimeout("tcp", "example.com:80", time.Second)
if err != nil {
fmt.Println("connect:", err)
return
}
defer s.Close()
if err := s.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
fmt.Println("deadline:", err)
return
}
n, err := s.Read(buf)
consume(buf[:n]) // Always process bytes before the accompanying error.
switch {
case errors.Is(err, debuglet.ErrTimeout):
fmt.Println("no response before the deadline")
case errors.Is(err, debuglet.ErrReset):
fmt.Println("peer reset the connection")
case err != nil && !errors.Is(err, io.EOF):
fmt.Println("read:", err)
}Networks are tcp, tls, udp and ip4:icmp, subject to the same destination,
transport and bandwidth policies as the legacy calls. ErrTimeout, ErrReset,
ErrClosed, ErrRefused and ErrDenied are distinguishable with errors.Is.
No arbitrary host error text or filesystem paths cross this interface.
Reads can return bytes and an error together, including io.EOF. Empty UDP
or ICMP datagrams return (0, nil). Writes retain their partial count on failure
and never retry automatically; oversized datagrams return ErrTooLarge without
sending. A zero deadline clears that socket deadline, without extending the
run's lifetime. Invalid guest memory and never-issued handles still trap.
Build and test debuglets against the Debuglet release you plan to use. The executor records the debuglet ABI in its installation manifest. A debuglet must target an ABI the executor supports.
Recoverable sockets require the optional debuglet_io_v1 host module. A host
without it rejects the guest at linking, naming the missing module. Existing
ABI-v1 guests remain supported without recompilation. The baseline ABI label
alone does not advertise this extension; use a release that includes it. The
extension contract records its wire signatures.