Files
JIMRI/help/en/package/jmri/jmrit/logixng/ConditionalNGDebugger.shtml
2026-06-17 14:00:51 +02:00

204 lines
9.9 KiB
Plaintext

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="generator" content="HTML Tidy for HTML5 for Apple macOS version 5.8.0">
<title>JMRI: LogixNG Debugger</title>
<meta name="author" content="Daniel Bergqvist">
<meta name="keywords" content="JMRI logixng debugger"><!--#include virtual="/help/en/parts/Style.shtml" -->
</head>
<body>
<!--#include virtual="/help/en/parts/Header.shtml" -->
<div id="mBody">
<!--#include virtual="../../../../html/tools/logixng/Sidebar.shtml"-->
<div id="mainContent">
<h1>JMRI: LogixNG Debugger</h1>
<p>Sometimes it can be difficult to understand exactly what's going on in a ConditionalNG.
LogixNG therefore has a debugger that allows a step by step walk thru a ConditionalNG to
see what it's actually doing.</p>
<p>To use the debugger, it must be enabled. In <strong>Preferences &rArr; LogixNG</strong>,
the option <strong>Install debugger</strong> must be enabled.</p>
<p>The debugger supports two different tools. The first one is an IDE style debugger which
supports single step operation, breakpoints, etc. This provides a detail look at what happens
for a single ConditionalNG. The second one displays each statement before and/or after it is
executed for every active ConditionalNG. This can provide a history of the actions and
expressions. Since this applies to all ConditionalNGs, it also provides insight into how
different ConditionalNGs might interact. See <a href="#logging">Statement Logging</a>.
Note: Both tools can be used at the same time.</p>
<h2>Using the debugger</h2>
<p>To run a ConditionalNG using the debugger, click on the <strong>Debug</strong> button in the
LogixNG ConditionalNG list. The status pane will open with the editor listing in the left
section.</p>
<p>The Debugger menu will be in the menu bar.</p>
<div style="margin-left: 2em">
<a href="images/DebugMenu.png"><img src="images/DebugMenu.png" alt="Debug Menu"></a>
</div>
<p>The debugger starts when the ConditionalNG is executed, for example when one of its
actions or expressions triggers it. The ConditionalNG can also be executed by selecting
the menu choice <strong>Debug &rArr; Execute</strong>.</p>
<p>The current action/expression has a thick top border before it is processed and and a thick
lower border afterwards.</p>
<div style="margin-left: 2em;">
<a href="images/DebugBefore.png"><img src="images/DebugBefore.png" alt="Debug Before"></a>
<a href="images/DebugAfter.png"><img src="images/DebugAfter.png" alt="Debug After"></a>
</div>
<p>When the ConditionalNG has started executing, the debugger will stop it before the
first action.</p>
<p>You can then step by step thru the ConditionalNG by selecting the menu item
<strong>Debug &rArr; Step into</strong>. The debugger will then stop both before and after
executing/evaluating the action/expression.</p>
<p>If the item has children, you can jump over the children by instead selecting the menu item
<strong>Debug &rArr; Step over</strong>. <em>Step over</em> means that the debugger
will process the children items without stopping before and after each one. When the children
items have been processed, the debugger will stop after the parent item. Note: If a child
has a breakpoint, processing will stop at that child even though <em>step over</em> is active.</p>
<p>If you want to run the ConditionalNG instead of stopping on each item, you select the menu item
<strong>Debug &rArr; Run</strong>. <em>Run</em> is frequently used with breakpoints to stop
at a particular row.</p>
<p>Breakpoints can be set on a row using the context menu.</p>
<div style="margin-left: 2em;">
<a href="images/DebugBreakpoint.png"><img style="border: solid thin black !important;"
src="images/DebugBreakpoint.png" alt="Debug Breakpoint"></a>
</div>
<p>The breakpoint border uses the same border concept for before and after.</p>
<div style="margin-left: 2em;">
<a href="images/DebugBreakpointSet.png"><img src="images/DebugBreakpointSet.png"
alt="Debug Breakpoint set"></a>
</div>
<p>When the breakpoint occurs, the borders are combined.</p>
<div style="margin-left: 2em;">
<a href="images/DebugBreakpointActive.png"><img src="images/DebugBreakpointActive.png"
alt="Debug Breakpoint active"></a>
</div>
<h2>Status pane</h2>
<p>On the right side of the debugger window, there are three panes. The top pane shows status if it's
available. Example of status is the return value of expressions. If the debugger stops after an
expression, the status pane will show the result of the expression, for example <i>Return value True</i>.</p>
<div style="margin-left: 2em;">
<a href="images/DebugPane.png"><img src="images/DebugPane.png"
alt="Debug Pane"></a>
</div>
<h2>Local variables pane</h2>
<p>On the right side of the debugger window, the middle pane shows the current local variables.</p>
<h2>LogixNG threads and the debugger</h2>
<p>When the debugger stops before or after an action/expression in the ConditionalNG,
it blocks further execution of both this ConditionalNG and all other
ConditionalNGs that is executed in the same thread. It's therefore recommended to move
the ConditionalNG to a separate thread when the debugger is used, so that the debugger
doesn't block the other ConditionalNGs. See <a href="LogixNGTableEditor.shtml#EditThreads">
Edit ConditionalNG Threads</a>.</p>
<h2 id="logging">Statement Logging<span class="since">since 5.7.7</span></h2>
<p>The <strong>Log all before</strong> and <strong>Log all after</strong> LogixNG preferences
are used to control the statement logging process. When enabled, the expressions and actions
will be displayed on the JMRI System Console as they are executed. The system console
is opened using <strong>Help &rArr; System Console</strong>. Using a startup action for the
JMRI System Console is recommended.</p>
<p>The preferences can be enabled or disabled and saved at any time. For example, do some
preliminary setup. Enable the preferences, do the process, and then disable the preferences.
Then the System Console <strong>Copy to clipboard</strong> button can be used to copy and
paste into a text document for further analysis.</p>
<p>Here is a simple LogixNG.</p>
<div style="margin-left: 2em;">
<pre>
LogixNG: IQ:AUTO:0001
ConditionalNG: IQC:AUTO:0001
! A
Many
! A1
If Then Else. Execute on change
? If
And. Evaluate All
? E1
Sensor ISCLOCKRUNNING is Inactive
! Then
Log data: Only text: Clock is stopped
! Else
Log data: Only text: Clock is running
! A2
Call module: Module
</pre>
</div>
<p>Here are the <strong>Before</strong> and <strong>After</strong> lines with both preferences
enabled and the sensor is changed to active.</p>
<div style="margin-left: 2em;">
<pre>
WARN - LogixNG Before: IQ:AUTO:0001, IQC:AUTO:0001: Many
WARN - LogixNG Before: IQ:AUTO:0001, IQC:AUTO:0001: If Then Else. Execute on change
WARN - LogixNG Before: IQ:AUTO:0001, IQC:AUTO:0001: And. Evaluate All
WARN - LogixNG Before: IQ:AUTO:0001, IQC:AUTO:0001: Sensor ISCLOCKRUNNING is Inactive
WARN - LogixNG After: IQ:AUTO:0001, IQC:AUTO:0001: Sensor ISCLOCKRUNNING is Inactive --- Return value False
WARN - LogixNG After: IQ:AUTO:0001, IQC:AUTO:0001: And. Evaluate All --- Return value False
WARN - LogixNG Before: IQ:AUTO:0001, IQC:AUTO:0001: Log data: Only text: Clock is running
WARN - Clock is running
WARN - LogixNG After: IQ:AUTO:0001, IQC:AUTO:0001: Log data: Only text: Clock is running
WARN - LogixNG After: IQ:AUTO:0001, IQC:AUTO:0001: If Then Else. Execute on change
WARN - LogixNG Before: IQ:AUTO:0001, IQC:AUTO:0001: Call module: Module
WARN - LogixNG Before: IQ:AUTO:0001, IQC:AUTO:0001: Log data: Only text: Module called
WARN - Module called
WARN - LogixNG After: IQ:AUTO:0001, IQC:AUTO:0001: Log data: Only text: Module called
WARN - LogixNG After: IQ:AUTO:0001, IQC:AUTO:0001: Call module: Module
WARN - LogixNG After: IQ:AUTO:0001, IQC:AUTO:0001: Many
</pre>
</div>
<p>The <strong>Before</strong> lines are by start sequence. The <strong>After</strong> lines
are by completion sequence. When an item has subordinate items, such as <strong>Many</strong>,
<strong>If</strong> and <strong>And</strong> in the example, the <strong>Before</strong> and
<strong>After</strong> lines will be separated.</p>
<p>The <strong>After</strong> line for <strong>Expressions</strong> includes the resulting
true/false state.</p>
<p>The LogixNG and ConditionalNG names identify the source of the log entry. When a conditional
calls a module, the names do not changed since the module is running within the conditional
context. If <strong>Before</strong> is enabled, the <em>Call module</em> action
identifies the call to the module. If <strong>After</strong> is enabled, the <strong>After</strong>
<em>Call Module</em> will show the return point. If <strong>After</strong> is not enabled, the
return is not visible and has to be deduced by looking at the <strong>Before</strong> lines
based on the statement sequence.</p>
<!--#include virtual="/help/en/parts/Footer.shtml" -->
</div>
<!-- closes #mainContent-->
</div>
<!-- closes #mBody-->
<script src="/js/help.js"></script>
</body>
</html>