Debugging

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

Written against MATLAB R2026b. Debugging in MATLAB means pausing a running program at a place of your choice, looking at the variables of every function on the call stack, optionally changing them, and then running on line by line or to the next stop. Two releases changed the desktop side: the Debugger panel and error breakpoints in the Live Editor arrived in R2025a, and the unsuppressed output condition of dbstop in R2024b. The release numbers come from the "since" and version-history notes of the R2026b documentation pages cited below.

Most of this page is interactive, and an interactive session cannot be reproduced in a document without inventing a transcript. So the MATLAB sessions here are described from the documentation and labelled "not run here". What was run is the same command-line debugger in GNU Octave 11.3.0 (it has dbstop, dbstatus, dbstep, dbcont, dbup, dbdown and dbstack), with the debug commands fed on standard input; its output is labelled "Octave 11.3.0 output". Octave prompts with debug> instead of K>> and words its messages differently.

Debug mode and the K>> prompt

While a program is paused at a breakpoint, MATLAB is in debug mode: the Command Window prompt changes from >> to K>>, which means the keyboard is in control. In the Editor the paused line is marked with a green arrow and is highlighted. The Run button becomes a Continue button, and from R2025a the Debugger panel opens. The paused line has not yet run: it runs when you continue or step.

At the K>> prompt you can type any MATLAB command. The commands run in the workspace of the function where execution is paused, so you can read variables, assign to them (the program then continues with the new values) and call functions with them. The documentation advises not editing the file while MATLAB is paused: changes made then do not run until the code is rerun, and saving the file while debugging ends the debugging session.

Before debugging, save the files and make sure they and the files they call are on the search path or in the current folder. The three places to run from treat unsaved changes differently: the Editor saves the file before running it, the Live Editor runs all changes whether saved or not, and the Command Window runs the saved version, so you do not see the effect of unsaved edits.

flowchart TD A["Prompt >> : the program is not paused"] -->|"run code that reaches a breakpoint, an error condition or keyboard"| B["Debug mode: prompt K>> and the line is paused, not yet run"] B -->|"dbstep, dbstep in, dbstep out"| B B -->|"dbup, dbdown change the current workspace"| B B -->|"dbcont"| C["Run until the next breakpoint or the end"] C -->|"another breakpoint"| B C -->|"end of the program"| A B -->|"dbquit"| A

Ways to look at a program without breakpoints

Before using breakpoints the documentation lists lighter options:

  • Remove a semicolon. A statement without a trailing semicolon displays its result in the Command Window (or beside the line in the Live Editor). A breakpoint condition unsuppressed output (below) pauses exactly at those lines.

  • Run to Here. The Run to Here button next to a line number runs the file and pauses before that line. If the line is never reached, MATLAB runs on to the end or to a breakpoint. Inside functions and classes, Run to Here works only while MATLAB is already paused.

  • Pause. The Pause button interrupts a long-running program at the next executable line. It can stop in code outside your own files, can take a noticeable time and in some cases does not pause at all, because MATLAB cannot pause inside some built-in code.

Breakpoints

A breakpoint is a request to pause. The documentation defines three kinds: standard (a line), conditional (a line plus a condition) and error (an event anywhere). Breakpoints can be set only at executable lines of saved files that are in the current folder or on the search path, and they can be set while MATLAB is idle or busy. A breakpoint set on a comment or blank line moves to the next executable line. Breakpoints clear automatically when the session ends.

Standard and conditional breakpoints

In the Editor, click the gray area beside an executable line (or press F12 on the current line). From the Command Window use dbstop, which has these forms:

Syntax Meaning (R2026b documentation)

dbstop in file

Breakpoint at the first executable line of file

dbstop in file at location

Breakpoint at location; execution pauses immediately before it (just after it, if the location is an anonymous function)

dbstop in file if expression

Conditional breakpoint at the first executable line; pauses only if expression evaluates to true

dbstop in file at location if expression

Conditional breakpoint at location

dbstop if condition

Error-type breakpoint: pauses at any line of any file when the condition occurs

dbstop(b)

Restore the breakpoints saved in the structure b (see below)

file can include a partial path for files on the search path, or an absolute path for any file. A file marker > names a local or nested function inside a file, as in dbstop in myfile>myfunction; with a file marker you cannot also give at location. location is a line number (default 1), a line number with an anonymous function number (1@2 is line 1, second anonymous function) or the name of a local function. A breakpoint on a line with anonymous functions gets one extra, initially disabled, breakpoint per anonymous function; the anonymous-function breakpoint pauses when that function is called, not where it is defined.

The expression of a conditional breakpoint is any valid MATLAB expression that returns a logical scalar; it is evaluated before the line runs. The documentation example sets the condition n>=4 on the line inside a for n = 2:6 loop: the loop runs through the early iterations without stopping and pauses on the third pass, when n is 4, and again on each later pass. In the Editor, use Set Conditional Breakpoint on the breakpoint alley, or from R2025a Set/Modify Condition in the Debugger panel.

A breakpoint placed on the line that begins a loop pauses only once, when the loop starts. To see the values at every iteration, put the breakpoint on a line inside the loop, or make it conditional.

Error breakpoints

An error breakpoint is not tied to a file or line. When its condition occurs, MATLAB pauses at the line where it happened, in whatever file that is. Set them from the Debugger panel (R2025a), from the Error Handling section of the Run button menu, or with dbstop if condition:

Command Pauses at

dbstop if error

A run-time error outside a try/catch block. You cannot resume execution after an uncaught run-time error.

dbstop if error identifier

The same, only for errors with that message identifier

dbstop if caught error

A run-time error inside the try part of a try/catch block; an identifier can be added as well

dbstop if warning

A run-time warning, with an optional warning identifier. It has no effect if warnings are disabled (warning off all, or off for that identifier).

dbstop if naninf

A line where an operator, function call or scalar assignment returns NaN or Inf

dbstop if unsuppressed output

A line that displays output because it has no semicolon (R2024b). Output from calls such as disp or fprintf does not pause.

The Debugger panel lists the same four general conditions as Pause on Errors, Pause on Warnings, Pause on NaN or Inf and Pause on Unsuppressed Output. Before R2025a, setting error breakpoints in the Live Editor was not supported.

The documentation example for the error condition runs a loop that reads x(n+1) past the end of the array. With the error breakpoint set, MATLAB pauses in debug mode at that line instead of printing the error and returning to >>; MException.last then returns the identifier (MATLAB:badsubscript) and message of the error, and the identifier can be used to narrow the breakpoint (dbstop if error MATLAB:badsubscript). Not run here.

A caught-error breakpoint shows where a try block swallows an error that you did not expect. The documentation example pauses at the first run-time error in a try portion that has the identifier MATLAB:ls:InputsMustBeStrings. To remove an error breakpoint, dbclear if error and the matching forms exist (see below). The related identifiers and MException are described in Errors, Warnings and Exceptions.

Listing, disabling, clearing and saving breakpoints

dbstatus lists the breakpoints in effect, including error conditions; dbstatus file limits the list to one file, and -completenames shows fully qualified file names. b = dbstatus(___) returns them as a structure array.

Command Effect

dbclear in myprogram at 6

Clears the breakpoint at line 6 of myprogram.m

dbclear all in myprogram

Clears all breakpoints in that file

dbclear all

Clears all breakpoints in all files, including error breakpoints

dbclear if error

Clears the error breakpoint (used in the dbstop documentation before setting an identifier-specific one)

In the Editor, right-click a breakpoint to disable or clear it, with options that apply to a single breakpoint, to a file or to all breakpoints; F12 on a line with a breakpoint clears it. A dark gray breakpoint is invalid: the file has unsaved changes (save it and the breakpoint turns red) or a syntax error (fix it and save).

Breakpoints are lost when the session ends. The documentation saves them with dbstatus and restores them with dbstop:

b = dbstatus("-completenames");
save("myBreakpoints.mat", "b")
dbclear all
load("myBreakpoints.mat")
dbstop(b)

Not run here (the documentation example is the same with a command-syntax save). MATLAB assigns restored breakpoints by line number, so the file must be unchanged since the breakpoints were saved, and the files must be on the search path or in the current folder.

Running on: dbcont, dbstep and dbquit

At a pause, these commands (and their keyboard shortcuts in the Editor) control what happens next. The table follows the documentation page Debug MATLAB Code Files:

Action What it does Shortcut Function

Continue

Run until the end of the file or the next breakpoint

F5

dbcont

Step

Run the current line, then pause at the next one

F10 (Shift+Command+O on macOS)

dbstep

Step In

Run the current line; if it calls another function, pause at that function’s first executable line

F11 (Shift+Command+I on macOS)

dbstep in

Step Out

Run the rest of the called function, leave it and pause

Shift+F11 (Shift+Command+U on macOS)

dbstep out

Stop

End the debugging session

Shift+F5

dbquit

dbstep nlines runs the given number of executable lines. dbstep skips breakpoints set in functions called by the current line, while dbstep out and dbstep nlines pause at any breakpoint they meet. dbstep in on a line with no call to a MATLAB code file behaves like dbstep. When the last line of a function runs, MATLAB reports the end of the function, and one more step finishes the call and returns to the caller.

To end debugging, use Stop or dbquit; the prompt returns to >> and the call stack is no longer accessible. Always end a debugging session when you are done, so that the K>> prompt does not stay and confuse later work. If MATLAB stops responding while paused (the documentation names a modal dialog or a figure created by the program), Ctrl+C ends debug mode.

The call stack and workspaces

Every function that is running has its own workspace. When you pause in a function called by another, the variables of the callers still exist, in their own workspaces, and the variables you typed at the >> prompt belong to the base workspace.

  • Debugger panel (R2025a): the Function call stack section lists the functions with the current one at the top. Selecting one makes its workspace current. Open the panel from the Editor or Live Editor tab (Analyze section, Debugger); it also manages all breakpoints of the open files and opens automatically when MATLAB enters debug mode (this can be switched off in the panel’s configuration or in Settings > MATLAB > Editor/Debugger).

  • Before R2025a: the call stack is shown at the top of the file in the Editor, in call order from left (first called) to right (current).

  • Command Window: dbstack prints the call stack (the documentation sample prints lines of the form In mean (line 48) and In plotRand (line 5)). dbup makes the workspace of the caller current, dbup n moves n levels up (the same as n times dbup), until the base workspace is reached; dbdown moves back down. dbup can only be called from the command line, and whos or who then list the variables of the selected workspace. You do not need to go back down to continue: dbcont and dbstep work from the paused line.

Trying to read a variable of another workspace while the paused line is overwriting it fails, because a variable that appears on both sides of an assignment can be unavailable while the statement is processed. The error text is quoted in the documentation as Variable "x" is inaccessible; the dbup page still shows an older wording beginning with ???, so the message differs by release.

Inspecting and changing variables

The ways to see a value while paused are, in the order of the documentation: the Workspace panel (double-click a variable to open it in the Variables Editor, or call openvar); a data tip by hovering over a variable in the Editor or Live Editor (always on while debugging in the Editor); Evaluate Selection in Command Window from the context menu (not while MATLAB is busy running a file); and typing the variable name at the K>> prompt. who and whos list the variables of the current workspace.

Typing an assignment changes the variable. The keyboard function does this from the code itself: placing keyboard in a program pauses it there, with the K>> prompt, so you can view or change variables and test whether the new values produce the right result; dbcont resumes and dbquit abandons the run. The documentation example multiplies x by 2 at the K>> prompt and continues, and the rest of the function runs with the new value. A keyboard call left in released code stops every user’s program, so treat it like a breakpoint and remove it before committing.

An example: debugging the heatflow calculation

The heatflow scenario (see the section index) computes a heat flux from temperatures. Two small files make a call stack of three levels (the caller script, heatReport, heatFlux). heatFlux uses dbstack only to print its caller, which shows the stack from code. Both files run the same in MATLAB and Octave.

function heatReport()
%heatReport Print the heat flux of a three-point temperature profile.
    T = [20 21 22];
    q = heatFlux(T, 0.5);
    disp(q)
end
function q = heatFlux(T, k)
%heatFlux Fourier flux between neighbouring points, unit spacing.
    gradT = diff(T);
    q = -k .* gradT;
    caller = dbstack();
    fprintf("called from: %s\n", caller(2).name);
end

A debugging session from the Command Window. In MATLAB the prompt would be K>>. The commands below, saved as the script debugHeatReport.m, set the breakpoint and start the program. The input then fed at the debug prompt was T, k, dbstack, dbup, T, dbdown, k = 2;, dbstep, q and dbcont. Octave 11.3.0 output:

dbstop in heatFlux at 4
dbstatus
heatReport
ans = 4
breakpoint in heatFlux at line 4
stopped in heatFlux at line 4 [/work/heatFlux.m]
4:     q = -k .* gradT;
debug> T =

   20   21   22

debug> k = 0.5000
debug> stopped in:

  -->        heatFlux at line 4 [/work/heatFlux.m]
           heatReport at line 4 [/work/heatReport.m]
      debugHeatReport at line 3 [/work/debugHeatReport.m]
debug> stopped in heatReport at line 4 [/work/heatReport.m]
debug> T =

   20   21   22

debug> stopped in heatFlux at line 4 [/work/heatFlux.m]
debug> debug> debug> stopped in heatFlux at line 5 [/work/heatFlux.m]
5:     caller = dbstack();
q =

  -2  -2

debug> called from: heatReport
  -2  -2

What the session shows: the pause happens before line 4 runs; T and k are those of heatFlux; dbstack lists the three active levels, current one first; after dbup, T is the T of heatReport (the same values, a different workspace); after dbdown the assignment k = 2 changes the argument, dbstep runs line 4 with it, and q is -2 -2 instead of the -0.5 -0.5 the program would print. The printed output lines at the end are the program finishing after dbcont. In MATLAB R2026b the same commands exist with the documented behaviour (not run here); the ans = 4 line is Octave’s return value of dbstop and MATLAB’s wording of the listing differs.

A conditional breakpoint on a bug that only shows at the end of a loop. scanFlux loops to n instead of n - 1, so its last pass reads T(n+1):

function d = scanFlux(T)
%scanFlux Differences between neighbouring temperatures.
    n = numel(T);
    d = zeros(1, n - 1);
    for i = 1:n
        d(i) = T(i+1) - T(i);
    end
end
dbstop in scanFlux at 6 if i == 3
dbstatus
d = scanFlux([20 21 22 23]);

Octave 11.3.0 output, with the commands saved as the script debugScanFlux.m (input fed: i, n, dbquit):

ans = 6
breakpoint in scanFlux at line 6 if i == 3
stopped in scanFlux at line 6 [/work/scanFlux.m]
6:         d(i) = T(i+1) - T(i);
debug> i = 3
debug> n = 4
debug> error: T(5): out of bound 4 (dimensions are 1x4)
error: called from
    scanFlux at line 6 column 9
    debugScanFlux at line 3 column 1

The pause came on the third pass (i = 3), with n = 4 visible: the loop is going to run a fourth pass that reads T(5), and the final lines are that error, from the run continuing. (In Octave the last input ended the debug prompt and execution went on to the error; the documentation says MATLAB’s dbquit ends the run.) In MATLAB the error is MATLAB:badsubscript with a message whose wording varies by release (not run here), and dbstop if error would pause at that line without choosing a line first.

Debugging tests

Test files are ordinary MATLAB files, so the commands above apply to them and to the code they call. The test framework is not part of Octave, so nothing in this section was run here; it follows the R2026b documentation of dbstop and runtests. Suppose a test in LaplacianTest.m fails on a value computed by heatflow.laplacian (the test file of Unit Testing with matlab.unittest):

dbstop in heatflow.laplacian            % breakpoint in the code under test
results = runtests("LaplacianTest");    % pauses at K>> inside laplacian
dbclear all

results = runtests("LaplacianTest", Debug=true);   % pauses where a test fails

Not run here. Three ways in, from the most targeted to the most general:

  • A breakpoint, then runtests. Set a breakpoint in the function under test (or in the test method) with dbstop in or in the Editor, and run the tests as usual. Execution pauses at the breakpoint with the K>> prompt, and dbstack shows the test method and the framework frames above it; inspect the inputs the test passed, step with dbstep, and dbcont lets the run finish.

  • runtests(___,Debug=true). The test runner enters the debugger when a test fails, at the point of the failing qualification, so you can inspect the actual and expected values. It forces serial execution.

  • dbstop if error. It pauses on an error that nothing catches. The test framework catches the errors thrown inside a test and records them as failures, so this condition usually does not pause there; use Debug=true or a breakpoint instead, and keep dbstop if error for scripts and functions run outside the framework.

Clear the breakpoints (dbclear all) before running the full suite again, or the run stops at each one.

What differs in GNU Octave

Octave has a command-line debugger with the same command names, which is why the sessions above could be run. Observed with Octave 11.3.0:

  • The prompt is debug> and the paused-line message is stopped in function at line n.

  • dbstop in Octave prints a numeric ans (the line number) when used from a script.

  • dbstop if naninf is not supported: Octave 11.3.0 warns that the condition is not yet supported. dbstop if error, if caught error and if interrupt exist.

  • There is no Debugger panel, data tips, Run to Here or Live Editor; the Octave GUI has its own breakpoint features, which were not checked for this page.

  • Given standard input at the end of the file, Octave’s debug prompt keeps repeating (the first attempt here looped endlessly), so give it input that ends the session.

Common errors and pitfalls

Situation What happens What to do

Unsaved changes or a syntax error in the file

The breakpoint is dark gray, invalid

Save, or fix the syntax error and save

Editing the file while paused

The change does not run until the code is rerun; saving ends the debugging session

End the session, edit, save and rerun

Breakpoint on a comment, blank or continuation line

It moves to the next executable line

Check where the arrow stops

Breakpoint on the line that starts a loop

Pauses only once

Put it inside the loop, or make it conditional

dbstop if error for an error inside a try

No pause, the error is caught first

Use dbstop if caught error

Resuming after an uncaught error

Not possible

Use dbquit, fix the code and rerun

dbup into a workspace whose variable is being overwritten

The variable is reported as inaccessible

Step past the assignment first

Forgetting that breakpoints survive until cleared

The program pauses in later runs

dbstatus to list them, dbclear all to remove them (they are lost at the end of the session)

A modal dialog or figure blocking the pause

MATLAB can become unresponsive

Ctrl+C

Where older books differ

Books that predate R2025a describe the call stack at the top of the Editor window and set error breakpoints from menus, because the Debugger panel did not exist, and error breakpoints in the Live Editor were not available. The unsuppressed output condition of dbstop was introduced in R2024b, so code written for earlier releases cannot use it. Error texts in old transcripts differ from current ones: the dbup page of the R2026b documentation still quotes a message that begins with ???, which is the style of old releases. The commands themselves (dbstop, dbstep, dbcont, dbquit, dbstack, dbup, dbdown, keyboard) are documented as introduced before R2006a and behave as described for decades.