Skip to content

Runtime and Debug Tools

Oleksandr Geronime edited this page Jun 29, 2026 · 4 revisions

Runtime and Debug Tools

Engineering and debug tool only. The Runtime registry is disabled in release builds (SERP_BUILD_RUNTIME=OFF by default). Never use it in production code paths or enable it in release configurations.

The Runtime subsystem provides a named method registry and three debug adapter backends. It lets you invoke any registered method by name — from the command line, from a shell script, or from the VS Code Runtime Inspector — without writing any client code.


Overview

Your service registers method callbacks by name
              │
              ▼
       serp::Runtime (registry)
              │
    ┌─────────┼──────────────┐
    ▼         ▼              ▼
RuntimeConsole  RuntimeDbus  RuntimeGrpc
(stdin/stdout)  (Linux IPC)  (gRPC port)
                                │
                                ▼
                       VS Code Runtime Inspector

Build Flags

SERP_BUILD_RUNTIME=ON                  # Enable core registry (required for all below)
SERP_BUILD_RUNTIME_CONSOLE=ON          # + stdin/stdout REPL
SERP_BUILD_RUNTIME_DBUS=ON             # + DBus adapter (Linux only)
SERP_BUILD_RUNTIME_GRPC=ON             # + gRPC adapter (any platform)
SERP_ENABLE_RUNTIME_METHOD_BINDINGS=ON # Auto-register all generated service methods

Enable at configure time:

cmake -S . -B build/debug \
    -DCMAKE_BUILD_TYPE=Debug \
    -DSERP_BUILD_RUNTIME=ON \
    -DSERP_BUILD_RUNTIME_GRPC=ON \
    -DSERP_ENABLE_RUNTIME_METHOD_BINDINGS=ON

Core API

Registering a Method

#include <serp/runtime/Runtime.hpp>

auto token = serp::Runtime::registerGuardedCallback(
    "ClimateService.SetTemperature",  // method name (must be unique)
    lifetimeToken,                    // weak_ptr — auto-unregisters when expired
    [this](std::vector<std::string> args) -> std::string {
        double temp = std::stod(args[0]);
        int zone    = std::stoi(args[1]);
        setTemperature(zone, temp);
        return "ok";
    }
);

registerGuardedCallback ties the registration lifetime to lifetimeToken. When the token expires (its referenced object is destroyed), the callback is automatically unregistered. This prevents dangling calls to destroyed services.

Keep the returned token alive for as long as the registration should remain active. Destroying token removes the registration.

Calling a Method Programmatically

std::string result = serp::Runtime::callMethod(
    "ClimateService.SetTemperature",
    {"22.5", "1"},              // args as strings
    std::chrono::seconds(5)     // timeout
);

callMethod blocks until the callback returns or the timeout elapses. It is intended for test drivers and internal tooling — not for production service-to-service calls.

Listing Registered Methods

auto methods = serp::Runtime::listMethods();
for (const auto& name : methods) {
    logInfo()->info(name);
}

Auto-Registration with SERP_ENABLE_RUNTIME_METHOD_BINDINGS

When this flag is ON, the code generator emits registration calls in the generated base classes. Every method defined in SerpIDL is automatically registered under "ServiceName.MethodName" when the service initializes. You do not need to call registerGuardedCallback manually for generated methods.

This is the recommended setup for development builds when using the VS Code Runtime Inspector.


Adapter 1: RuntimeConsole

A stdin/stdout REPL. Useful when running a service in a terminal and you want to invoke methods interactively without any external tooling.

Setup:

#include <serp/runtime/RuntimeConsole.hpp>

auto console = std::make_shared<serp::RuntimeConsole>();
console->start();

REPL commands:

Command Description
help Show available commands
list List all registered method names
<method> <arg1> <arg2> ... Call a method with space-separated arguments
exit Shut down the REPL

Example session:

> list
ClimateService.SetTemperature
ClimateService.GetTemperature
NavigationService.SetDestination

> ClimateService.SetTemperature 22.5 1
ok

> ClimateService.GetTemperature 1
22.5

Adapter 2: RuntimeDbus (Linux)

Exposes the Runtime registry over DBus. Other processes (or command-line tools) can call registered methods via standard DBus tooling.

Setup:

#include <serp/runtime/RuntimeDbus.hpp>

auto dbus = std::make_shared<serp::RuntimeDbus>();
dbus->start();
Property Value
DBus name serp.Runtime
Object path /serp/Runtime
Interface serp.Runtime1

List methods via DBus:

gdbus call \
    --session \
    --dest serp.Runtime \
    --object-path /serp/Runtime \
    --method serp.Runtime1.ListMethods

Call a method via DBus:

gdbus call \
    --session \
    --dest serp.Runtime \
    --object-path /serp/Runtime \
    --method serp.Runtime1.TryCallMethod \
    "ClimateService.SetTemperature" '["22.5", "1"]'

Returns the string result of the registered callback, or an error string if the method is not found or the call times out.


Adapter 3: RuntimeGrpc (macOS / cross-platform)

Exposes the Runtime registry over a gRPC server. This is the backend used by the VS Code Runtime Inspector on macOS and other non-Linux platforms.

Setup:

#include <serp/runtime/RuntimeGrpc.hpp>

auto grpc = std::make_shared<serp::RuntimeGrpc>();
grpc->start();   // listens on 0.0.0.0:50060 by default

Override the listen address:

SERP_RUNTIME_GRPC_ADDRESS=127.0.0.1:50061 ./my_app

Or set it in code before calling start().

List methods via grpcurl:

grpcurl -plaintext localhost:50060 serp.Runtime1/ListMethods

Call a method via grpcurl:

grpcurl -plaintext \
    -d '{"name":"ClimateService.SetTemperature","args":["22.5","1"]}' \
    localhost:50060 serp.Runtime1/TryCallMethod

Subscribe to live method invocation events:

grpcurl -plaintext localhost:50060 serp.Runtime1/Subscribe

Subscribe is a server-streaming RPC. It emits one message each time any registered method is called, including the method name, arguments, and result. Useful for observing a running system in real time.


VS Code Runtime Inspector

The SERP VS Code extension includes a Runtime Inspector panel that connects to RuntimeGrpc (macOS/Linux) or RuntimeDbus (Linux) and provides:

  • A browsable list of all registered methods.
  • A form-based interface for providing arguments and invoking methods with a single click.
  • A live call log showing every method invocation and its result.

To use it:

  1. Build your app with SERP_BUILD_RUNTIME=ON, SERP_BUILD_RUNTIME_GRPC=ON, and SERP_ENABLE_RUNTIME_METHOD_BINDINGS=ON.
  2. Run your app.
  3. Open the Runtime Inspector panel in VS Code (SERP extension sidebar).
  4. The extension connects automatically to localhost:50060 (or the address configured in extension settings).

No client code or test harness is required — the inspector drives your service directly.


Security Considerations

The Runtime gRPC server binds to 0.0.0.0 by default, which makes it reachable from other machines on the same network. In development environments this is typically fine, but:

  • Restrict to 127.0.0.1 if the machine is on a shared network.
  • Never enable the Runtime in a release or production build.
  • Use SERP_BUILD_RUNTIME=OFF (the default) for all production CMake configurations.

Runtime Access in AI Sessions

AI debug sessions use the same runtime infrastructure via the serp_runtime_call and serp_runtime_listMethods MCP tools. This enables automated investigation on a live system: the AI lists available methods, calls them, observes results, forms a hypothesis, and iterates — without human relay between each step. See AI-Driven Development for the full debug workflow.


See Also

Clone this wiki locally