Debugging with breakpoints and snapshots

Introduction

YAKINDU Statechart Tools' Professional Edition includes two simulator features that increase your productivity considerably when debugging statecharts:

  • You can attach breakpoints to states and transitions. If a statechart simulation reaches a transition or state with a breakpoint, it suspends execution of the simulation. A breakpoint can be amended with a condition. Such a breakpoint will suspend the simulation only if that condition is fulfilled, i.e., evaluates to true.
  • You can create snapshots of your statechart simulation. A snapshot contains everything making up your state machine simulation at any point in time. It describes the state of the state machine. Snapshots can be saved and restored later in order to continue the simulation from exactly the point the snapshot was taken.

The light switch example

Throughout this chapter we will be using the light switch statechart as an example. It models a lamp which can be turned on and off and also supports various brightness values.

If you press the pressLightOn button, the lamp turns on at its lowest brightness value. If you operate pressLightOn repeatedly, each time the lamp becomes brighter until it reaches its maximum brightness. Pressing the pressLightOff button immediately turns off the light completely. The brightness can only be raised as long as it hasn’t yet reached its maximum value of five. After that, the guard condition disallows to raise it any further.

Here’s the light switch example’s statechart followed by its definition section:


The light switch sample statechart

The light switch sample statechart

interface:
    in event pressLightOn
    in event pressLightOff

interface Lamp:
    var brightness: integer

Breakpoints

Breakpoints allow for automatically suspending the simulation when a certain element of the state machine is activated. Optionally, a halting condition can be specified to better control the behavior of a breakpoint. Breakpoints can be set on transitions or states. If a state or transition with a breakpoint is reached, the simulation pauses, and the current state of variable values can be examined in the simulation view. It is possible to change variable values and to trigger events that will be raised when the simulation run is manually resumed.

Figure "Transition vs. state breakpoints" depicts at which point of execution a breakpoint pauses the simulation.


Transition vs. state breakpoints

Executing in debug mode

To make use of breakpoints, the statechart simulation needs to be executed in debug mode. You have already seen how to start a statechart simulation in run mode. For using breakpoints and snapshots, however, the debug mode is needed.

  1. Right-click on the statechart model. The context menu opens.
  2. Select Debug As → Statechart Simulation, see Figure "Starting a simulation in debugging mode".
  3. The statechart simulation starts in the debugging mode.


Starting a simulation in debugging mode

Starting a simulation in debug mode

Setting a breakpoint

  1. Right-click on a state or transition. The context menu opens.
  2. Select Toggle breakpoint from the context menu, see Figure "Setting a breakpoint".


Setting a breakpoint

Setting a breakpoint

States and transitions with a breakpoint are labeled with a Symbol: Breakpoint enabled symbol. Figure "Breakpoints on transition and state" shows an example.


Breakpoints on transition and state

Breakpoints on transition and state

Hitting a breakpoint

If the simulation runs into a state with a breakpoint, the state’s entry actions, if any, are executed. After that, execution of the state machine is suspended. The state is highlighted by a small green border.

Highlighting a suspended state

Highlighting a suspended state

If the simulation runs into a transition with a breakpoint, execution of the state machine is suspended. The transition is highlighted by drawing the transition arc in green. The transition’s actions, if any, are executed when the state machine is resumed.

Highlighting a suspended transition

Highlighting a suspended transition

Continuing the simulation

In order to continue from a breakpoint, you have two options:

  • To continue execution, click on the resume button Symbol: Resume in the simulation view. The statechart simulation continues until the next breakpoint is hit or the simulation is terminated.
  • To execute only the next run-cycle of the simulation and then suspend again, click on the step-over button Symbol: Step Over in the simulation view.

Using the breakpoints view

The breakpoints view shows a list of all breakpoints. The respective breakpoint name identifies the state or transition in question. See figure "Breakpoints view" for an example.

You can use the breakpoints view for disabling, enabling, and removing breakpoints as well as for defining conditional breakpoints.


The "Breakpoints" view

The Breakpoints view

Enabling and disabling breakpoints

A breakpoint is either enabled or disabled.

  • An enabled breakpoint causes the statechart simulation to suspend when reaching it. In the statechart and in the breakpoints view, an enabled breakpoint is visualized by a filled light blue circle with a grey border: Symbol: Breakpoint enabled.
  • A disabled breakpoint is ignored by the statechart simulation. In the statechart and in the breakpoints view, a disabled breakpoint is visualized by a hollow circle with a grey border: Symbol: Breakpoint disabled.

Figure "Breakpoints view" shows an enabled and a disabled breakpoint in the statechart editor and in the breakpoints view, respectively.

You can instruct the statechart simulation to skip all breakpoints by clicking on the Button [disengaged]: Skip all breakpoints button in the breakpoints view. The button will appear „pressed”, and while it is, the „skip breakpoints” functionality is engaged. That means, the simulation will not suspend at any breakpoint.

This is different from disabling all breakpoints, in that each breakpoint keeps its state of being enabled or disabled. Once you disengage the skip breakpoints functionality by clicking on the Button [engaged]: Skip all breakpoints button again, the simulation will suspend again at enabled breakpoints and will not suspend at disabled breakpoints.

Removing breakpoints

In order to remove some breakpoints, select these breakpoints in the breakpoints view, then click on the Button: Remove button. The selected breakpoints will be removed.

To remove all breakpoints, click on the Button: Remove all button

Conditional breakpoints

A conditional breakpoint has an associated condition and suspends the simulation only if

  • that condition is fulfilled (true) and
  • the breakpoint is enabled.

In order to attach a condition to a breakpoint, proceed as follows:

  • In the breakpoints view, select the breakpoint in question.
  • Check the Conditional checkbox, see figure "Breakpoints view" in the lower right area. The associated text field becomes writable.
  • Enter the condition into the text field. Like in the statechart editor, a content assist is available when pressing [Ctrl+Space]. The expression you entered into the text field is validated automatically. In the example shown in figure "Breakpoints view", the transition suspends the simulation only if the variable brightness has a value of 4.

Debugging a statechart

Changing variable values

In the suspended status of a statechart simulation, you can change variable values using the simulation view. When continuing execution – see section Continuing the simulation – you can observe how your state machine behaves with those modified values.

Raising multiple events simultaneously

If you click on an event’s name in the simulation view to raise that event in normal simulation, i.e., while execution isn’t suspended, the state machine processes that event and takes the corresponding transition, if any.

However, while the simulation is suspended, you can raise multiple events, without instant execution. Once execution resumes, the state machine’s behavior depends on its execution scheme:

  • In the cycle-based execution scheme, both events are handled at the same time, or, to be more exact, in the same run-to-completion step (RTC).
  • In the event-driven execution scheme, each of the two events will trigger a run-to-completion step (RTC) of its own.

Let’s have a look at an example. Please note that this example uses the cycle-based execution scheme! This is important, because in the the event-driven case the state machine’s behavior would be different.

Let’s consider that you want to press the "light on" and "light off" buttons at the same time and want to observe what happens. Figure "Raising multiple events simultaneously" shows the scenario:


Raising multiple events simultaneously [1]

Raising multiple events simultaneously [1]

  • The simulation has encountered a breakpoint at the LightOn state and has been suspended there.
  • The simulation view shows the pressLightOn and the pressLightOff events. Both events are labeled with a Symbol: Event [not raised] symbol, meaning the respective event is not raised.


Raising multiple events simultaneously [2]

Raising multiple events simultaneously [2]

  • Clicking on an event raises it and adds a blue triangle to the event symbol: Symbol: Event [raised]. Since the simulation remains suspended, the user can raise multiple events.

Both events are raised and will be handled by the state machine during the next run-to-completion step. The latter will be performed as soon as the user clicks on the step-over button Symbol: Step Over or the resume button Symbol: Resume.

Please note: Under the even-driven execution scheme, multiple events are never processed at the same time. Each event triggers a separate RTC.

Please note: While the execution is still suspended, you can „unraise” an already raised event by clicking on the event symbol Symbol: Event [raised] a second time. The blue triangle will disappear, and upon continuation of the simulation the event will not be handled.

Transition priorities

It is important to understand that in the event-driven execution scheme there is a queue of events, while in the cycle-based scheme there isn’t. If in the latter case multiple events occur simultaneously, they are all present at the same time, and the state machine has to figure out which event should trigger which transition. For example, what should the light switch state machine do, if it is in the LightOn state and both events, pressLightOn and pressLightOff, have been raised simultaneously?

The answer is transition priorities. The state machine always consults the active state’s transitions in a well-defined order, it fires the first matching transition it encounters, and it forgets about the rest. Transition priorities are specified in the corresponding property of the respective state, see figure "Transition priorities". You can change these priorities, and thus the order the transitions are being checked, by selecting a transition and moving it up or down by clicking on the respective button.

The first transition whose condition is fulfilled will be executed. Under the cycle-based execution scheme, all remaining events are quashed. In the light switch example as shown in figure "Transition priorities", the pressLightOff event would „win” and trigger a transition from the LightOn to the LightOff state, while the pressLightOff event would be discarded.


Transition priorities

Transition priorities

Snapshots

The snapshot feature allows to store and restore the state of a simulation run. A snapshot comprises all active states of the state machine as well as all variable values at the time of snapshot creation.

This feature is especially useful when testing complex state machines in which a number of steps need to be taken before reaching a certain situation you want to investigate. Using snapshots, you can store this desired situation once and then simply restore it anytime and as often as you like, without having to repeat all the tedious steps to reach that situation from scratch. Depending on the complexity of your use case, using snapshots can be a huge time-saver.

Creating a snapshot

To create a snapshot of the current statechart simulation, proceed as follows:

  1. Change to Snapshots view on the right-hand side of the YAKINDU Statechart Tools window.
  2. Click at the camera button Button: Camera in the view’s toolbar.
  3. The snapshot is taken and appears in the snapshot list. It is labeled „Snapshot” (can be changed), and it is tagged with the current timestamp. Figure "A freshly taken snapshot" shows an example.


A freshly taken snapshot

A freshly taken snapshot

The snapshots view

The snapshots view consists of two parts.

  • The snapshot list in the upper half contains all snapshots with their respective names and timestamps.
  • The snapshot details part in the lower half displays the contents of the snapshot. It contains two different views which can be toggled via its toolbar buttons:
    • Button: Show all variable values: shows all variable values
    • Button: Show image overview: shows an overview image of the state machine with the active state(s) being highlighted


Inspecting snapshot details: variables overview [left], states overview [right]

Inspecting snapshot details: variables overview [left], states overview [right]

Restoring a snapshot

To restore a snapshot for execution, proceed as follows:

  1. Select the snapshot to be restored.
  2. Click at the restore button Button: Restore snapshot.
  3. The snapshot is restored as an additional executing state machine instance.

Please note: When the semantics of the underlying state machine have been changed, it might not be possible to restore a snapshot, e.g., when the active state has been deleted.

Naming a snapshot

The label of a snapshot can be changed as follows:

  1. Click at its label. The label becomes an editable field.
  2. Enter the new snapshot name and press [Return], or click anywhere outside the editable field.

Deleting a snapshot

  • To delete one or more snapshots, select the snapshots to be deleted, then click on the remove button Button: Remove.
  • To delete all snapshots, click on the remove all button Button: Remove all.