Using the Debug service

The Debug service sets property breakpoints: it watches one property of one node and acts when the value meets a condition.

It is separate from the Overwatch service because the two do different kinds of thing. Overwatch reports on a running application. A breakpoint intervenes in one — it can halt the process in an attached debugger, or run a console command from inside the assignment that changed a property. That is why it has its own configuration key, ServiceDebugEnabled, and why the commands are named debug.* rather than overwatch.*.

Note

ServiceDebugEnabled is independent of ServiceOverwatchEnabled: the debug commands are available with the Overwatch service switched off, and can be switched off while Overwatch runs.

The one part that does depend on Overwatch is the screenshot action, which captures through whichever service owns the framebuffer. With Overwatch disabled, that action reports that no capture source is available; the other six commands are unaffected. To capture the frames leading up to a breakpoint instead, attach capture.stop with debug.breakcommand and let the capture service ring hold the run-up.

debug.breakprop <path> <property> <op> <value> [once] [hitcount:N] [actions]
                                                                 Add a property breakpoint.
debug.breakpoints                                            Get property breakpoints
                                                                 as JSON.
debug.removebreakpoint <id>                                  Remove a breakpoint by ID.
debug.enablebreakpoint <id> <0|1>                            Activate or deactivate a
                                                                 breakpoint.
debug.breakcommand <id> <command>                            Run a console command when
                                                                 a breakpoint triggers.
debug.clearbreakpoints                                       Remove all breakpoints.
debug.breakpointscreenshot                                   Fetch the capture a
                                                                 breakpoint took.

These commands use the debug. prefix rather than overwatch., because they do something different in kind from the rest of this service: the Overwatch commands report on the application, while a breakpoint intervenes in it. They are enabled by the separate ServiceDebugEnabled setting, so an application can expose the introspection surface without also allowing a debugger trap and a console command run from inside a property write. See Configuring Kanzi Monitor.

A property breakpoint watches one property of one node and acts when its value meets a condition. Unlike a performance watcher, which is evaluated once per frame, a breakpoint is evaluated by a Kanzi property notification handler — inside the assignment that changed the value. With the break action and a debugger attached, execution therefore stops on the code that wrote the property, which is what makes it useful for finding who set a value rather than only that it was set.

<op> is one of eq, neq, below, above, beloweq, aboveeq, or the equivalent symbol (==, !=, <, >, <=, >=). float and int properties accept all of them; bool, string, Vector2, Vector3 and Vector4 accept eq and neq only. Vector values are comma-separated, and a missing component is read as 0.

The property name may be unqualified: Opacity resolves to Node.Opacity. Because a node path may contain spaces, debug.breakprop parses its arguments from the right — the property, operator and value are always single tokens, so whatever precedes them is the path, unquoted:

debug.breakprop /Screen/RootPage/Viewport 2D/Image Opacity below 0.5 break

Quoting the path is unnecessary for that reason, but it is accepted — one layer of matching single or double quotes is stripped, the same way overwatch.props strips it, so a path copied from a command that needed quotes works here too. An unbalanced quote is left in place rather than guessed at, so the resulting Node not found names exactly what was asked for.

Warning

Only the path accepts quotes — the value does not. debug.breakprop /A/B Text eq "Hello" creates a breakpoint whose target is the seven-character string "Hello", quotes included. It is listed as armed and never fires, with no error, because any string is a valid target for a string property. Write the target unquoted, and note that there is no way to express a target containing a space.

overwatch.setprop is not the precedent here despite appearances: it does not use this quote stripping at all, it uses a different argument reader that treats a leading quote as running to the end of the line. So overwatch.setprop "/A/B Opacity 5 reports a missing property name, where debug.breakprop keeps the quote in the path. The two commands agree on unquoted spaced paths and disagree on malformed quoting.

Actions can be given as one comma-separated token or as separate words, and one breakpoint can carry several either way — log,screenshot and log screenshot are the same request. The separate-word form is limited to three trailing arguments in total, counting once and hitcount:N: ... 0.5 log screenshot once hitcount:3 is four and is rejected with the usage line, while the comma-packed ... 0.5 log,screenshot once hitcount:3 is three and parses. Pack the actions into one token when a breakpoint needs both modifiers as well. They run in a fixed order, with break last, so every diagnostic is in place before execution stops.

Note

Kanzi Monitor 1.42 on Kanzi 4.2 adds two further actions, gfxlog and gfxframe, which turn on graphics API call logging. They are not available on the Kanzi 4.1 baseline, which has no call logging to drive (KZMON-276 removed the old commands; KZMON-541 reinstates them on 4.2). debug.breakprop rejects those names with an explanation rather than as unknown.

Action

Effect

break

Traps into an attached debugger. Without one, this is skipped and logged — raising a trap with nothing to catch it would terminate the application.

log

Logs the triggering value and leaves the application running. A tracepoint.

On a property that changes every frame, such as an animated one, this fills the log buffer and evicts everything else in it. Pair it with hitcount:N or once.

screenshot

Captures the default framebuffer on the next render, fetched with debug.breakpointscreenshot. Breakpoint captures have their own slot, so they never consume an overwatch.screenshot result.

command

Runs a console command. Attach the command with debug.breakcommand, which enables this action; it cannot be given to debug.breakprop, whose argument order has no room for free text.

hitcount:N triggers on every Nth matching change rather than every one, and once deactivates the breakpoint after its first trigger, leaving it listed but inert. N must be a non-negative whole number, and the target value must be readable as the property’s type — both are rejected outright rather than quietly becoming 0, which would leave the listing showing a condition the breakpoint is not testing. To break the tenth time a layout width is written, and stop there:

debug.breakprop /Screen/RootPage/Grid LayoutWidth above 100 once hitcount:10 break

To log every write of a state without stopping, and capture what the screen looked like:

debug.breakprop /Screen/RootPage Focused eq true log,screenshot

Note

The property needs no value beforehand. Registering the breakpoint creates the node’s property storage entry for it, so you can break on a property nothing has written yet and catch the first write to it — often the write worth catching.

The node itself must exist, because there is nothing to register the handler on otherwise. If no property type can be resolved for the name at all, the breakpoint is still created but reported with "notification": false, and never fires. debug.breakpoints shows the same flag, and the Monitor Web UI labels such a breakpoint Dormant — check the name against overwatch.props, then remove and add it again.

Note

The node path is resolved against every enumerated view root, matching each root’s own canonical path, so every path overwatch.nodes reports round-trips — including on a host with several roots, such as a service-hosted application with one view adapter per client. A path that names no node returns Node not found rather than silently answering for the first root. overwatch.props and overwatch.setprop share the same resolver (KZMON-620).

Note

The condition is evaluated on whichever thread wrote the property, and the actions run there too. A command action therefore runs outside the normal console request path, and its output goes to the application log rather than to a client.

Available commands

Command

Description

debug.breakprop

Adds a property breakpoint. Usage: debug.breakprop <path> <property> <op> <value> [once] [hitcount:N] [actions]

debug.breakpoints

Gets property breakpoints as JSON. notification: false marks a breakpoint that cannot fire.

debug.removebreakpoint

Removes a property breakpoint. Usage: debug.removebreakpoint <id>

debug.enablebreakpoint

Activates or deactivates a breakpoint, resetting its hit count when activating. Usage: debug.enablebreakpoint <id> <0|1>

debug.breakcommand

Attaches a console command to a breakpoint and enables its command action. Usage: debug.breakcommand <id> <command>

debug.clearbreakpoints

Removes all property breakpoints.

debug.breakpointscreenshot

Fetches the screenshot a breakpoint’s screenshot action captured.

See also