Execution and Debugging

Execution

Text about Jobs and launch support of Eclipse in general

Eclipse supports asynchronous execution via so called Jobs, implemented in org.eclipse.core.runtime.jobs.Job. These Jobs can be scheduled with Job.schedule(), which will execute the run() method of a Job, which returns an IStatus.

JobChangeListeners can be added to a Job and react to the IStatus returned by the run() method of a Job.

Java

All Java related tasks are handled by the eu.hatsproject.absplugin.actions.JavaJob. There are three different classes starting an Java Job.

  1. eu.hatsproject.absplugin.actions.JavaAction - the predefined toolbar icons
  2. eu.hatsproject.absplugin.actions.shortcuts.AbstractLaunchJavaShortcut - the predefined run configurations
  3. eu.hatsproject.absplugin.actions.runconfig.JavaRunConfiguration - customized run configurations

You can start a simple JavaJob with "new JavaJob(name,action,project,file).schedule()", where

  • name is the name of this job
  • the action defines, if we need to start SDEdit:
    Action IdEffect
    ACTION_DEBUG_IDstarts debugging
    ACTION_START_SDEstarts debugging and SDEdit
    elseonly compiling (.abs files to .java and .class files)
  • project - must be an ABS project and not null
  • file - the selected file, where to find the main block. If this file is null, then the JavaJob tries to find the main block in the generated Java files.

You can overwrite the default arguments before scheduling the JavaJob. There are several set methods like for example "setDebuggerArgsSystemObserver(String debuggerArgsSystemObserver)". The default arguments are set in "setDebuggerArgumentsIfNull".

If you want to see more output / informations while a JavaJob is working, just set the boolean debugMode to true. For further information see the Javadoc and the code itself.

Maude

The eu.hatsproject.absplugin.actions.MaudeJob extends the default Job and overrides the run method offering compiling to .maude files and execution of such. To do so, one has to create a new MaudeJob, add a new MaudeJobChangeListener to it and schedule the Job.

The probably most interesting part is the returned status of the jobs run method. The MaudeJob will always return an IStatus with severity IStatus.INFO, the actual state is encoded within the code of the IStatus. The following outcomes are possible:

CodeWhat happenedReaction of the listener
MAUDE_OKfiles have been generated, but not executednone
MAUDE_INFOfiles have been generated, execution was successfulthe message of the status (console output of Maude) will be printed on the Eclipse console as Info (black)
MAUDE_WARNINGthis code is not used by the MaudeJobthe message of the status will be printed on the Eclipse console as warning (yellow)
MAUDE_ERROR_MAUDEMaude encountered an error during execution of the generated .maude filethe message of the status will be printed on the Eclipse console as error (red)
MAUDE_ERROROther errors have been encountered during compiling or starting the Maude processAn error message containing the message of the status will pop up
MAUDE_ERROR_MAUDE_PATHNo file has been found at the Maude location specified in the preferencesAn error message will pop up. If this is dismissed, the Maude Preference Page will open and allow the user to specify a valid Maude path.
MAUDE_USER_ABORTThe user aborted the Maude JobAn abort message is printed on the Eclipse console as error (red)

You may extend these by implementing new codes, but then have to adapt both the Job returning the new code as well as the listener which has to react on the new code appropriately.

Like Java Jobs, there are three points at which a Maude Job is created and scheduled:

  • The compile Maude / debug Maude Buttons (eu.hatsproject.absplugin.actions.)
  • the "Run as" menu (eu.hatsproject.absplugin.shortcuts.LaunchMaudeShortcut)
  • and the more configurable run configuration (eu.hatsproject.absplugin.runconfig.MaudeRunConfiguration)

At all these three points, the explained process of creating a job, adding a MaudeJobChangeListener and scheduling the job is followed.

For further reference see the Javadoc and the code itself.

Run Configurations

Each run configuration consist of one ore more tabs (eu.hatsproject.absplugin.actions.runconfig.JavaTab or eu.hatsproject.absplugin.actions.runconfig.MaudeTab). Run configuration attributes are set in these classes.
Tabs are composed into TabGroups (eu.hatsproject.absplugin.actions.runconfig.JavaTabGroup or eu.hatsproject.absplugin.actions.runconfig.MaudeTabGroup).
The launch of a run configuration is in eu.hatsproject.absplugin.actions.runconfig.JavaRunConfiguration or eu.hatsproject.absplugin.actions.runconfig.MaudeRunConfiguration.

If you want to add a new Scheduler or SystemObserver in the Java run configuration, just modify eu.hatsproject.absplugin.actions.runconfig.RunConfigEnums.

Debugging

General Architecture

Generally, debugging is done in cooperation with the ABSFrontend. The Eclipse plug-in creates and starts an abs.backend.java.lib.runtime.ABSRuntime and adds an internal scheduler and listeners to it.

Schedulers have to implement abs.backend.java.scheduling.TotalSchedulingStrategy and therefor contain a choose and a schedule method.

  • choose is always executed, when the debugger has finished a step and awaits selection of the next COG which should take a step
  • schedule is called, when a COG without a running task and more then one schedulable task is selected by choose. It determines which task of the chosen COG should be scheduled next.

Listeners implement methods, which are called on specific events occurring during debugging, e.g. creation of a new COG or termination of a task.

The debug package is split into four parts or sub-packages

  • eu.hatsproject.absplugin.debug.scheduling containing the SchedulingStrategy with all schedulers
  • eu.hatsproject.absplugin.debug.model which implements listeners / observers and augments the model with additional information
  • eu.hatsproject.absplugin.debug.perspective containing classes which constitute to the ABSDebugPerspective
  • eu.hatsproject.absplugin.debug.views containing views specific for the debug perspective.

For more details about these packages see below.

Note, that this debugger is NOT related to the Eclipse Debug API but implements everything manually.

Debug Model

A short overview of the classes augmenting abs.backend.java.debugging.DebugModel

ClassImplemented interfaceFunctionality
eu.hatsproject.absplugin.debug.model.Debuggerabs.backend.java.observing.SystemObservermanage model, start and terminate debug process, react on newCOGCreated
eu.hatsproject.absplugin.debug.model.DebugModelListenerabs.backend.java.debugging.DebugModelListenerreact on COG and Task creations and changes
eu.hatsproject.absplugin.debug.model.ObjectCreationObserverabs.backend.java.observing.ObjectCreationObserverreact on object creation and initialization
eu.hatsproject.absplugin.debug.model.Objects eu.hatsproject.absplugin.debug.model.Tasksnecessary to group objects and tasks in the debug viewer tree.
eu.hatsproject.absplugin.debug.model.VariableValuePairnecessary for variable view to link field names with their values

For more details about the model see documentation of abs.backend.java.debugging.DebugModel and related classes.

Graphical User Interface (Perspective and Views)

Extension points and classes for the debugging interface:

FeatureExtension PointsClasses
Debug Perspectiveorg.eclipse.ui.perspectiveseu.hatsproject.absplugin.debug.perspective.ABSDebugPerspectiveFactory
Debug View Variable Vieworg.eclipse.ui.viewseu.hatsproject.absplugin.debug.views.debugview.DebugView eu.hatsproject.absplugin.debug.views.variablesview.VariablView
Buttonsorg.eclipse.ui.viewActionseu.hatsproject.absplugin.debug.DebugActionDelegate eu.hatsproject.absplugin.debug.SchedulerChoiceDelegate
Hotkeysorg.eclipse.ui.commandseu.hatsproject.absplugin.debug.commands.ResumeCommandHandler eu.hatsproject.absplugin.debug.commands.StepOverCommand

Debugging of ABS files is done in a new ABSDebugPerspective. The ABSDebugPerspectiveFactory sets up the initial design of the perspective, containing the DebugView and the VariableView.

The DebugView is the most important view for debugging. Here, a TreeViewer shows the current state of the debugged program. The DebugTreeContentProvider and DebugTreeStyledLabelProvider (found in eu.hatsproject.absplugin.debug.views.debugview) construct this tree out of a given DebugModel (which is found in the ABSFrontend at abs.backend.java.debugging), similar to the TreeViewer found in the Outline

The VariableView again is similar to the OutlinePage, classes are found at eu.hatsproject.absplugin.debug.views.VariableView. The only difference worth mentioning is the LabeProvider being an org.eclipse.jface.viewers.ITableLabelProvider, which results in the contents of the tree being shown in multiple columns. Classes implementing ITableLabelProvider need to implement the methods getColumnImage and getColumnText which are similar to the equivalently named methods in the conventional LabelProvider, but also take a column index as parameter and return only the value for a specific element in a specific column. So the elements returned by the ContentProvider need to contain data for each column of the table.

Buttons are added to the DebugView with another extension point. Enablement of this buttons is set by the method eu.hatsproject.absplugin.debug.DebugUtils.refreshButtonEnablement, which is called whenever task is stepped, another task (or different element) is selected in the debug tree or the scheduler is changed. The enablement is set according to the currently selected scheduler, the selection of the debug tree and the steps that are currently possible.

Scheduler (SchedulingStrategy)

Scheduling is done in two layers. The eu.hatsproject.absplugin.debug.scheduling.SchedulingStrategy is directly connected the debugger implemented in the ABSFrontend. Calls to the choose(..) and schedule(..) methods are delegated to the internal schedulers. These schedulers are an extension of the abs.backend.java.scheduling.TotalSchedulingStrategy with an additional state. The interface is eu.hatsproject.absplugin.debug.scheduling.TotalScheduler. It supports a reset() method to invalidate the internal state of the scheduler.

The SchedulingStrategy delegates all calls first to the curScheduler. This is mostly a scheduler dedicated to the action the user whats to perform. The current implementations are:

  • GUIScheduler

    It is connected to the SchedulingStrategy.doSingleStep() method. It waits for user input and when triggered performs a single step.

  • NStepScheduler

    It is connected to the SchedulingStrategy.doMultipleSteps(..) method. It performs the number of steps the user entered.

  • RunToLineScheduler

    It is connected to the SchedulingStrategy.doRunToLine(..) method. It performs steps till the debugger reaches the given line in the given file. If the line is not reached, it performs all possible steps.

  • StepOverScheduler

    It is connected to the SchedulingStrategy.doStepOver() method. It takes the stack frame of the task, that was selected last time, and performs steps till the same stack frame is reached again. If the stack frame is never reached again, all possible steps are performed.

All these action schedulers ask a base scheduler for the next action that can be performed. The task of a base scheduler is to run through the program in a given order/sequence without interruption. If the sequence is finished, the scheduler switches the curScheduler to the GUIScheduler and lets the user decide on the next steps to take. It is controlled by an action scheduler (see above). There are currently two implementations:

  • RandomScheduler

    It is an extension of the abs.backend.java.scheduling.RandomSchedulingStrategy. It decides on the next step randomly. If there are no deadlocks, this scheduler can decide on all steps till the program is finished.

  • RunTaskScheduler

    This scheduler decides on all steps of the given task. After a reset, it may schedule the given task. Afterwards it will try to decide on the step actions. If there are no more step actions possible, the scheduler switches the curScheduler to the GUIScheduler and lets the user decide. That means, if the task is blocked or there are no steps left, the scheduler will ask the user to decide on the next actions (for example to continue by resetting the scheduler -single step ore resume- or by choosing another task).