This package provides an implementation of a debugger for Wolfram's Mathematica.
-
Clone repo
$ git clone git@github.com:teedr/mathematica-debugger.git -
Link or move the Debugger folder to a folder listed in your Mathematica
$PathMac:
$ cd <Some dir listed in your Mathematica $Path> $ ln -s <path to where you cloned mathematica-debugger>/mathematica-debugger/Debugger .Windows: Open cmd.exe as administrator (Open Start menu, search for cmd.exe, right click, select "Run as administrator")
$ cd <Some dir listed in your Mathematica $Path> $ mklink /D Debugger <path to where you cloned mathematica-debugger>\mathematica-debugger\Debugger -
Use
Get["Debugger`"]orNeeds["Debugger`"]to load the package in Mathematica
-
Wrap
Debuggeraround a code block -
After execution, the symbol
DebuggerInformationwill be populated with keys:- "AssignmentLog"
- List of timestamped assignments (in order of assignment) for each variable assigned during execution
- "CurrentAssignments"
- Association mapping each assigned variable to its current value
- "LastAssignment"
- The last variable name set during execution
- "Failures"
- A list of any messages represented by
Failureobjects
- A list of any messages represented by
- "AssignmentLog"
-
All variables in DebuggerInformation Associations will be ToString-ed and include Context
-
Populate the
DebuggerContextsoption with a list of contexts from which variables should be trackedDefaults to
DebuggerContexts -> $DebuggerContexts(where$DebuggerContextsis set by default to{"Global"}`) -
Use the
AbortOnMessageoption to stop evaluation upon the first message thrownDefaults to
AbortOnMessage -> True -
Use the
BreakOnAssertoption to interrupt evaluation on failed assertions (ie:Assert[False]can be used like a breakpoint)Defaults to
BreakOnAssert -> False -
Use the
ModuleNumbersoption to toggle module number suffix on variable namesDefaults to
ModuleNumbers -> False
- When
BreakOnAssertisTrue, the Interrupt dialog is displayed upon execution ofAssert[False] - Click Abort in the Interrupt dialog to kill the evaluation
- Click Enter Subsession in Interrupt dialog to free the kernel for evaluations
- Once the dialog is dismissed, evaluation must be controlled by the Debugger Controls
- CTRL + Shift + H: Halt
- CTRL + Shift + C: Continue
- CTRL + Shift + F: Finish
Example function definition:
func[x_Integer]:=Module[
{foo, bar},
foo = x;
bar = foo + 1;
foo = x + bar;
{foo, bar}
];
Use Debugger in function execution
In[1]:= Debugger[func[3]]
Out[1]= {7, 4}
Query DebuggerInformation to see variable set history
In[2]:= DebuggerInformation
Out[2]= Association[
"AssignmentLog" -> {
(* foo had multiple assignments *)
{1487198514, foo, 3},
{1487198515, bar, 4},
{1487198516, foo, 7}
},
"CurrentAssignments" -> Association[
foo -> 7,
bar -> 4
],
"LastAssignment" -> Rule[
foo,
7
],
"Failures" -> {}
]
Example function definition:
func::err:="Error!";
func[x_Integer]:=Module[
{foo, bar},
foo = x;
bar = foo + 1;
Message[func::err];
foo = x + bar;
{foo, bar}
];
Use Debugger in function execution
In[1]:= Debugger[func[3],ModuleNumbers->True]
func:Error!
Out[1]= $Aborted[]
Query DebuggerInformation to see variable set history
In[2]:= DebuggerInformation
Out[2]= Association[
"AssignmentLog" -> {
(* execution aborted before foo's second assignment *)
{1487198514, foo$577, 3},
{1487198514, bar$577, 4}
},
"CurrentAssignments" -> Association[
foo$577 -> 3,
bar$577 -> 4
],
"LastAssignment" -> Rule[
bar$577,
4
],
"Failures" -> {
Failure[
func,
Association[
"MessageTemplate" :> func::err,
"MessageParameters" -> {}
]
]
}
]
Example function definition:
func::err:="Error!";
func[x_Integer]:=Module[
{foo, bar},
foo = x;
bar = foo + 1;
Assert[False];
foo = x + bar;
{foo, bar}
];
Use Debugger in function execution
In[1]:= Debugger[func[3], BreakOnAssert -> True, ModuleNumbers -> True]
"Breakpoint at line: 3 of file: README.md"
Select Enter Subsession in Interrupt dialog and query DebuggerInformation to see variable state at breakpoint
(Dialog) In[2]:= DebuggerInformation
(Dialog) Out[2]= Association[
"AssignmentLog" -> {
(* execution paused before foo's second assignment *)
{1487198514, foo$577, 3},
{1487198514, bar$577, 4}
},
"CurrentAssignments" -> Association[
foo$577 -> 3,
bar$577 -> 4
],
"LastAssignment" -> bar$577,
"Failures" -> {}
]
CTRL + Shift + C to continue execution
In[1]:= Debugger[func[3], BreakOnAssert -> True]
Out[1]= {7, 4}
- There is an issue where an
Unset::writeerror is thrown from the Debugger after aborting from a message. It doesn't seem to affect any functionality but tracking down the error's source is ongoing.
Please! Fork this repository and open a pull request. Some potential future developments include:
- Log SetDelayed calls / Log function calls
- Log what function was responsible for an assignment
- Figure out some way to populate
DebuggerInformationuponAssert[False]without compromising Reap/Sow performance - Perhaps some sort of Debugger dialog
- More stuff I can't think of