Envoy Logo

boe debug

The debug command runs Envoy with local Go or Rust extensions built for debugging, and attaches a debug server to the Envoy process so you can set breakpoints in the extension code from your IDE.

Extensions run inside the Envoy process (they are loaded as shared libraries), so the debugger has to attach to Envoy, not to the boe CLI. This command builds the local extensions without optimizations and with full debug information, starts Envoy, and attaches a debug server to it, listening on 127.0.0.1:2345 by default. Debug builds are stored separately in the cache and are never used by boe run.

Only local extensions (--local) are supported: Go extensions, composer sub-extensions, or Rust extensions. Go and Rust extensions can’t be debugged in the same session. All other flags behave as in boe run.

  • Go extensions are debugged with Delve. boe debug builds its own patched Delve the first time it runs, so it does not need to be installed. Use --rebuild-dlv to force rebuilding it.
  • Rust extensions are debugged with the platform’s native debug server, which speaks the GDB remote protocol: gdbserver on Linux (it must be installed), and LLDB’s debugserver on macOS (from the Xcode Command Line Tools). The debug server is only attached to Envoy while a debugger is connected, so Envoy keeps running normally between debug sessions and you can reconnect at any time. Connect with GDB on Linux and with LLDB on macOS: LLDB can’t resolve breakpoints in extensions when connected to gdbserver.

While the debugger is stopped at a breakpoint all Envoy workers are paused, so in-flight requests may time out.

Breakpoints are resolved using the exact source paths recorded when building the extension, which are the paths given in --local. If those paths go through a symlink (for example, /tmp is a symlink to /private/tmp on macOS) and your IDE sets breakpoints using the resolved path, they will not be hit. boe debug warns about this and prints the path mapping to add to the IDE configuration.

Examples

Debug the opa extension from the composer bundle:

boe debug --local ~/src/built-on-envoy/extensions/composer/opa \
    --config '{"policies":[{"inline":"package envoy.authz\ndefault allow := true"}]}'

Debug a Rust extension:

boe debug --local ~/src/built-on-envoy/extensions/ip-restriction \
    --config '{"deny_addresses":["192.168.1.50"]}'

Debug a Go extension using a custom port for the debug server:

boe debug --local ./my-go-extension --debug-port 40000

Once the debug server is listening, attach your IDE to 127.0.0.1:2345: as a remote Delve session for Go extensions, or as a GDB remote (gdb-remote) session for Rust extensions. From the command line, use dlv connect 127.0.0.1:2345 for Go, or, for Rust, gdb -ex 'target remote 127.0.0.1:2345' on Linux and lldb -o 'gdb-remote 127.0.0.1:2345' on macOS. Run detach before quitting the debugger: quitting without detaching kills Envoy. See the Debugging guide for IDE configurations and caveats.

Usage details

boe debug [flags]
boe debug --help

Flags

NameDescriptionTypeDefaultEnv VarRequired
--envoy-versionEnvoy version to use (e.g., 1.31.0, dev, dev-latest)string-ENVOY_VERSIONNo
--envoy-pathPath to a custom Envoy binary. Skips Envoy download and version selection.string-ENVOY_PATHNo
--log-levelEnvoy component log level.stringall:errorENVOY_LOG_LEVELNo
--log-formatEnvoy log format.string-ENVOY_LOG_FORMATNo
--run-idRun identifier for this invocation. Overrides the default timestamp-based ID.string-BOE_RUN_IDNo
--listen-portPort for Envoy listener to accept incoming traffic.uint3210000-No
--admin-portPort for Envoy admin interface.uint329901BOE_ADMIN_PORTNo
--extensionExtensions to enable (in the format: “name” or “name:version”).[]string--No
--localPath to a directory containing a local Extension to enable.[]string--No
--devWhether to allow downloading dev versions of extensions (with -dev suffix). By default, only stable versions are allowed.boolfalse-No
--configOptional JSON config string for extensions. Applied in order to combined —extension and —local flags.[]string--No
--filter-typeSet the filter type for an extension. Applied positionally to the combined —extension and —local flags. Accepted values: http, network, listener, udp_listener.[]string--No
--native-http-filter-beforeOptional YAML/JSON native HTTP filter list (or @filepath) per extension position. Overrides manifest nativeHttpFilters.before.[]string--No
--native-http-filter-afterOptional YAML/JSON native HTTP filter list (or @filepath) per extension position. Overrides manifest nativeHttpFilters.after.[]string--No
--clusterOptional additional Envoy cluster provided in the host:tlsPort pattern.[]string--No
--cluster-insecureOptional additional Envoy cluster (with TLS transport disabled) provided in the host:port pattern.[]string--No
--cluster-jsonOptional additional Envoy cluster providing the complete cluster config in JSON format.[]string--No
--test-upstream-hostHostname for the test upstream cluster. Mutually exclusive with —test-upstream-cluster. Defaults to “httpbin.org”.string--No
--test-upstream-clusterName of an existing configured cluster to use as the test upstream. The cluster must be configured via —cluster, —cluster-insecure, or —cluster-json. Mutually exclusive with —test-upstream-host.string--No
--listener-certPath to a PEM-encoded certificate chain used to terminate TLS on the Envoy listener. Requires —listener-key.string--No
--listener-keyPath to the PEM-encoded private key for the listener certificate. Requires —listener-cert.string--No
--dockerRun Envoy as a Docker container instead of using func-e.boolfalseBOE_RUN_DOCKERNo
--pullPull policy for the BOE Docker image (missing, always, never). Only applicable when running with —docker.stringmissing-No
--docker-image-versionOverride the BOE Docker image tag to use when running with —docker. By default, the image version matches the BOE version.string--No
--registryOCI registry URL for the extensions.stringghcr.io/tetratelabs/built-on-envoyBOE_REGISTRYNo
--insecureAllow connecting to an insecure (HTTP) registry.boolfalseBOE_REGISTRY_INSECURENo
--usernameUsername for the OCI registry.string-BOE_REGISTRY_USERNAMENo
--passwordPassword for the OCI registry.string-BOE_REGISTRY_PASSWORDNo
--debug-portPort for the debug server attached to Envoy.uint322345BOE_DEBUG_PORTNo
--debug-server-pathPath to the debug server binary: dlv for Go extensions (instead of the patched Delve that boe builds; unpatched versions may not be able to list goroutines), or gdbserver (Linux) or debugserver (macOS) for Rust extensions.string-BOE_DEBUG_SERVER_PATHNo
--rebuild-dlvRebuild the patched Delve used for Go extensions even if it is already in the cache.bool-BOE_REBUILD_DLVNo