Debugger

The Activate debugger is an interface that lets you control the advancement of a simulation so that, at every pause, you can inspect and modify block objects, which includes model signals.

Why debug a simulation?

If a simulation error occurs or a simulation does not provide the expected result, searching for the cause of the problem is not always an easy task. To effectively debug a model, it is often necessary to inspect values produced and exchanged between blocks step by step. This lets you identify the first instance when a signal takes an unexpected value and find the root cause of the problem. In some cases, it is also useful to modify a signal produced by a block before continuing the simulation for testing different scenarios.

How the debugger works

An Activate model is a declarative graphical program and can be debugged in the same way debuggers are used for script-based imperative languages such as OML. For Activate, a pause (breakpoint) is placed on a block, instead of an instruction or a line of code.

Running a simulation in debug mode opens Activate debugger, a dialog box with an interface that gives you control over the advancement of the simulation. At every pause, the interface is reactivated, providing access to block objects, such as inputs, outputs, and states. You can then inspect and modify the block objects, which include model signals.

Running the simulation in debug mode does not require making any modification to the model. No block needs to be added. The simulation follows the same sequence of function calls that it would outside of debug mode. It provides access to all signals, block states, and parameters.

During the simulation of an Activate model, the functions associated with the blocks present in the model are called in the order specified by the scheduling tables constructed by the compiler for realizing different actions, called tasks. You can use the Activate debugger to intercept all these calls, so that you investigate the block object and the computation performed by the block simulation function. This is done by pausing both before (pre-call phase) and after the action of the simulation function (post-call phase), so that the block object can be examined before and after its action. When a call to a block simulation function is intercepted, the block object can even be modified in the debugger, depending on the task and the phase.

Although the simulator calls the block simulation functions only when needed, the number of calls during a typical model simulation can still be very large. In most cases, pausing at every call, referred to as single-stepping, is not an effective debugging strategy. Conditions must be used to filter out calls that are not useful for debugging the model. The debugger’s two main functionalities are to allow defining the conditions under which the simulation should pause and to provide access to the block objects when paused.