Debug Framework Tutorials
For a list of all debug related tutorials see Debug Framework Tutorials Overview.
In this series we will handle launching, debugging with all its flavors (stepping, suspend/resume, breakpoints), source lookup to trace the current code location and finally variables and memory support.
But before we can even think of debugging, we need a language definition and an interpreter with debugging support.
Displayed source code will only show relevant parts, please refer to the provided links to see the full implementation.
Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online.
Language definition
Lets keep things simple and use a fictional interpreter that simply processes lines of code by printing them to the standard output. Therefore any text file can be used as source input. This way, we may use the Eclipse default Text Editor as our source editor.
Our simple language shall support variable definitions in the form "my variable name = some content". To also make use of variables we will allow for placeholders ${variableName} that will get replaced by the actual variable content.
Finally we support memory dumps. For simplicity each processed line content will add to our memory dump.
A simple script example looks as follows:
hello world first name = Christian ${first name}, you just defined a variable counter = 23 we are running our interpreter
Interpreter implementation
Lets have a look at the TextInterpreter implementation (just the relevant parts):
package com.codeandme.debugger.textinterpreter; public class TextInterpreter extends Job { public TextInterpreter() { super("Text interpreter"); } /** * Set the source code to be executed. As our interpreter is line oriented, we immediately split the text into separate lines. * * @param code * source code */ public void setCode(final String code) { String[] lines = code.replaceAll("\r\n", "\n").split("\n"); fLines = new LinkedList<String>(Arrays.asList(lines)); } @Override protected synchronized IStatus run(final IProgressMonitor monitor) { fTerminated = false; fLineNumber = 1; fVariables.clear(); fMemory = new StringWriter(); debug(DebugAction.LOADED); while ((!fTerminated) && (!monitor.isCanceled()) && (!fLines.isEmpty())) { // read line to execute String line = fLines.remove(0); line = evaluate(line); // "execute" line of code System.out.println(line); // alter our simulated memory fMemory.append(line); // advance by one line fLineNumber++; debug(DebugAction.SUSPEND); } debug(DebugAction.TERMINATE); return Status.OK_STATUS; } public String evaluate(String lineOfCode) { // do variable replacement Matcher matcher = VARIABLE_MATCHER.matcher(lineOfCode); while (matcher.matches()) { lineOfCode = matcher.replaceFirst(fVariables.get(matcher.group(1))); matcher = VARIABLE_MATCHER.matcher(lineOfCode); } // try to register variable String[] tokens = lineOfCode.split("="); if (tokens.length == 2) { // variable found fVariables.put(tokens[0].trim(), tokens[1].trim()); } return lineOfCode; } }
As interpreters typically run in their own process or thread our interpreter is implemented as a Job. The two important methods so far are setCode() and run(). Everything else is for debugging support and will be explained in the following tutorials.
The main loop (line 31) processes line by line by printing, altering the memory and extracting variables. This is done until all lines are processed or the Job got terminated via the monitor or an external call.
All we have to do to start our interpreter is:
TextInterpreter interpreter = new TextInterpreter(); interpreter.setCode("hello world"); interpreter.schedule();Launching is a topic of its own and will be briefly handled in the next tutorial.
thank you for your tutorial
ReplyDeleteDear Christian,
ReplyDeletethank you for the great tutorial. Is it possible to upload the whole source code again?
I am moving my old tutorials step by step to github. Get in touch with me directly an I'll send you a zipped version of the debugger tutorials
DeleteHello Christian, could you please send me the zip ViewGragon@gmail.com.
DeleteThank you!
Hello Christian
ReplyDeleteThis is very interesting... could you please also send me the zip touti.airbnb@gmail.com
Many Thanks