How to Use the Nelson Debugger to Set Breakpoints and Inspect Variables
The Nelson debugger provides MATLAB-style commands such as dbstop, dbup, and dbstack to set breakpoints in functions or scripts, navigate the call stack, and inspect variables from either the command line or the integrated Qt editor.
The Nelson debugger, maintained in the nelson-lang/nelson open-source repository, implements a complete debugging environment centered in modules/debugger. Built around a C++ core that interfaces with the Evaluator object, it supports both programmatic debugging commands and visual breakpoint management through the Qt text editor.
Setting Breakpoints with dbstop
The dbstop command creates breakpoints that pause execution before a specific line runs. The implementation in modules/debugger/builtin/cpp/dbstopBuiltin.cpp (lines 30‑65) parses arguments and validates line numbers before registering the breakpoint with the Evaluator.
Stop at the First Executable Line
To break when entering a function, specify the function name without a line number. Nelson resolves the target and sets the breakpoint at the first executable statement.
% Define a test function
function y = buggy(x)
n = length(x); % line 3
y = (1:n) / x';
end
% In the Nelson console
dbstop in buggy
buggy(1:5) % execution pauses before line 3
The parser resolves buggy as a macro function and registers the breakpoint via dbstopInAt (lines 57‑66), automatically targeting line 1 (the first executable line).
Stop at a Specific Line
Target a precise line number to halt execution at a specific computation. The line number is validated and adjusted to the nearest executable statement via Evaluator::adjustBreakpointLine in modules/interpreter/src/cpp/EvaluatorDebug.cpp.
dbstop in buggy at 4
buggy(1:5) % pauses on line 4 (the division)
Break in Local Subfunctions
Nelson supports the > syntax to target local functions nested within a main function file. The parser in dbstopBuiltin.cpp (lines 114‑146) walks the MacroFunctionDef::nextFunction chain to locate the subfunction definition.
% file: myfile.m
function out = myfile(a)
out = helper(a); % line 2
end
function out = helper(b)
out = b.^2;
end
dbstop in myfile>helper % breakpoint inside local function
myfile(3) % pauses when entering helper()
Managing and Clearing Breakpoints
List all active breakpoints using dbstatus, which builds a struct array from Evaluator::getBreakpoints similar to the logic in dbstackBuiltin.cpp. Remove breakpoints with dbclear.
dbstatus % display all breakpoints
dbclear all % remove every breakpoint
Controlling Execution Flow
Once execution pauses, control resumes with dbcont. This builtin clears the internal breakpoint active flag in the Evaluator and allows the interpreter to continue running.
dbcont % resume execution
Inspecting Variables and Navigating the Stack
View the Call Stack with dbstack
The dbstack command formats the current call stack obtained from DebugStack() in modules/debugger/src/cpp/DebugStack.cpp. The implementation in dbstackBuiltin.cpp (lines 70‑108) prints each frame to the console.
dbstack % show function call hierarchy
Move Up the Stack with dbup
To inspect variables in calling workspaces, use dbup to ascend the call stack. The implementation in modules/debugger/builtin/cpp/dbupBuiltin.cpp (lines 28‑55) calls Evaluator::dbUp(N), then fetches the current Scope via eval->getContext()->getCurrentScope() and prints the workspace name.
dbup % move up one frame
who % list variables in that frame's workspace
whos % display detailed variable information
Each invocation moves one level up, allowing you to examine the state of parent functions before returning to the current execution point.
Using the Qt Editor UI
The Nelson debugger integrates with the Qt text editor (modules/text_editor) to provide visual breakpoint management.
Managing Breakpoints Visually
The Breakpoints dock, instantiated in QtTextEditor.cpp (lines 98‑104) and implemented in modules/text_editor/src/cpp/QtBreakpointPanel.cpp (lines 31‑98), displays a table with columns for Enabled, File, Function, and Line.
- Add a breakpoint: Click the gutter area of the editor pane (
QtBreakpointArea.cpphandles mouse events and emitsbreakpointToggled). - Navigate: Double-click a breakpoint row in the panel (
QtBreakpointPanel::onCellClicked, lines 31‑38) to open the file and move the caret to the specific line. - Remove: Select rows and click Remove or Remove All to call
Evaluator::removeBreakpoint.
Viewing the Call Stack
The Call Stack dock (created in QtTextEditor.cpp lines 89‑96) displays the current execution frames. Clicking a frame triggers the same navigation logic used for breakpoints, allowing you to jump between calling contexts and inspect the code at each level.
Complete Debugging Workflow
The following example demonstrates setting a breakpoint, inspecting variables, and navigating the stack:
% file: demo_debug.m
function demo_debug()
a = 10; % line 1
b = helper(a); % line 2 ← set breakpoint here
disp(b); % line 3
end
function y = helper(x) % local subfunction at line 5
y = x^2; % line 6
end
% Console interaction:
dbstop in demo_debug at 2
demo_debug % pauses before line 2
who % shows 'a' (value 10), 'b' (not yet defined)
dbup % moves to base workspace
dbstack % shows demo_debug at line 2
dbcont % completes execution
Summary
- Set breakpoints using
dbstop in <function> [at <line>]or thefunction>subfunctionsyntax; the command resolves targets indbstopBuiltin.cppand stores them in the Evaluator. - Control execution with
dbcontto resume anddbclearto remove breakpoints. - Inspect state by running
dbstackto view the call hierarchy anddbupto climb frames, then usewhoorwhosto examine variables in the current scope. - Use the UI by enabling the Breakpoints and Call Stack panels in the Qt editor to toggle, navigate, and manage breakpoints visually without typing commands.
Frequently Asked Questions
How do I set a breakpoint at the exact line I specify?
Nelson adjusts the line number to the nearest executable statement via Evaluator::adjustBreakpointLine in modules/interpreter/src/cpp/EvaluatorDebug.cpp. When you run dbstop in file at 100, the system validates the line and snaps it to the next valid code line if line 100 is empty or a comment.
Can I save and restore breakpoints between sessions?
Yes. Run bp = dbstatus() to capture a struct array of all breakpoints. Later, pass this struct back to dbstop(bp) to recreate them. The Evaluator stores this data as Breakpoint objects containing filename, line, and enabled flags.
How do I inspect variables in a function that called my current function?
Use dbup to move up the call stack. According to modules/debugger/builtin/cpp/dbupBuiltin.cpp (lines 40‑56), each call shifts the Evaluator context up one frame and prints the new workspace name. Once there, run who to list variables or type variable names to see their values.
What files handle the debugger's C++ implementation?
The core debugging commands reside in modules/debugger/builtin/cpp/ (e.g., dbstopBuiltin.cpp, dbupBuiltin.cpp, dbstackBuiltin.cpp). Breakpoint storage and stepping logic live in modules/interpreter/src/cpp/EvaluatorDebug.cpp, while the Qt UI components are in modules/text_editor/src/cpp/QtBreakpointPanel.cpp and QtTextEditor.cpp.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →