Debug Logging ​
When a clocked model fails during compilation, the error is often generic — it says that something went wrong inside code generation without saying what. This page covers how to get the compiler to show its work.
This is diagnostic output about the compiler. For recording what a program computed at run time, see Logging data from inside the program; for the solver's own output during a simulation, TransientAnalysis takes a log_file argument (see TransientAnalysis).
Turning it on ​
SynchToolkit writes its intermediate results to a debug channel, off by default:
using SynchToolkit
SynchToolkit.enable_debug!(:sj) # one stage
SynchToolkit.enable_debug!() # every stage
SynchToolkit.disable_debug!() # back to quietThe stages are:
| Group | Shows |
|---|---|
:sj | The synchronous-program node and the generated module source. |
:codegen | The code-generation stage itself. |
:compile | The compilation result. |
:integration | How the clocked partitions are attached to the continuous-time problem. |
:init | Initialization handling. |
:sj is the one to reach for first: it prints the generated module, which is what you need when a model fails with an internal code-generation error rather than a modeling error.
Reading a code-generation failure ​
A failure inside code generation surfaces as a message pointing you here, for example:
Failed to evaluate the generated runtime module ##SynchRuntime#281. This is a bug in
SynchToolkit's code generation; use `SynchToolkit.enable_debug!(:sj)` to inspect the
generated code.Enabling :sj then prints the module it failed to evaluate, and the fault is usually visible in it — a name that does not resolve, a type that is not concrete, an operator that was not translated.
The underlying exception is not shown
The message above is raised in place of the original error, which is discarded rather than attached. So the debug output shows you the generated code but not the exception that evaluating it threw.
To recover the exception itself, capture the generated module from the debug record and evaluate it yourself, in SynchToolkit's own namespace — evaluating it in Main fails on using StaticArrays instead, which is an artifact of the wrong module context rather than the real fault:
Core.eval(SynchToolkit, captured_code)A small AbstractLogger that watches for the "Generated module code" record is enough to capture it.
What to do with the result ​
A code-generation failure is generally not something to work around in the model. If the generated module is malformed, report it with the model that produced it — the generated source and the recovered exception together are usually enough to localise the problem.
Errors that are worth changing the model for look different: they name a variable, a clock or an equation, and they come from clock inference rather than code generation. Those are covered by the clock-error troubleshooting table in the discrete-time modeling tutorial.
See also ​
Julia Functions, Side Effects and Hardware — logging data from inside a program
Clocks and Sampled-Data Systems — clock errors that are modeling errors