Next: , Previous: , Up: Top   [Contents][Index]

3 Debugging Daikon

Daikon debugging options in Daikon User Manual describes several command-line options that enable logging, which can be a useful alternative to using a debugger when debugging Daikon. Because Daikon processes large amounts of data, using a debugger can be difficult.

This chapter describes some of the command-line options in more detail.


Up: Debugging Daikon   [Contents][Index]

3.1 Track logging

Often it is desirable to print information only about one or more specific invariants. This is distinct from general logging because it concentrates on specific invariant objects rather than a particular class or portion of Daikon. This is referred to as Track logging because it tracks particular values across Daikon.

The --track class|class|...<var,var,var>@ppt option to Daikon (see Daikon debugging options in Daikon User Manual) enables track logging. The argument to the --track option supplies three pieces of information:

  1. The class name of the invariant (e.g., IntEqual). Multiple class arguments can be specified separated by pipe symbols (‘|’).
  2. The variables that are used in the invariant (e.g., return, size(this.s[])). The variables are specified in angle brackets (‘<>’).
  3. The program point of interest (e.g., DataStructures.StackAr.findMin()V:::ENTER). The program point is preceded by an at sign (‘@’).

Each item is optional. For example:

IntEqual<x,y>@makeEmpty()
LessThan|GreaterThan<return,orig(y)>@EXIT99

Multiple --track switches can be specified. The class, program point, and each of the variables must match one of the specifications in order for information concerning the invariant to be printed.

Matching is a simple substring comparison. The specified item must be a substring of the actual item. For instance, LessThan matches both IntLessThan and FloatLessThan.

Program points and variables are specified exactly as they are seen in normal Daikon invariant output. Specifically, Ppt.name and VarInfo.name.name() are used to generate the names for comparisons.

Invariants are not the only classes that can be tracked. Any class name is a valid entry. Thus, for example, to print information about derived sequence variables from sequence this.theArray[] and scalar x at program point DisjSets.find(int):::EXIT, the tracking argument would be:

SequenceScalarSubscriptFactory<x,this.theArray[]>@DisjSets.find(int):::EXIT

There are two configuration options that can customize the output. The option daikon.Debug.showTraceback will output a stack trace on each log statement. The option daikon.Debug.logDetail will cause more detailed (and often voluminous) output to be printed. For more information, see Configuration options in Daikon User Manual.

Note that all interesting information is not necessarily logged. It will often be necessary to add new logging statements for the specific information of interest (see Adding track logging). This is covered in the next section.

More detailed information can be found in the Javadoc for daikon.Debug and daikon.inv.Invariant.


Next: , Up: Track logging   [Contents][Index]

3.1.1 Adding track logging

When you add a new invariant, derived variable, or other component to Daikon, you should ensure that it supports track logging in the same way that existing components do. This section describes how to do so.

Track logging is based around the class name, program point name, and variables of interest. Track logging methods accept these parameters and a string to be printed. Debug.java implements the following basic log methods:

log (String)
log (Class, Ppt, String)
log (Class, Ppt, VarInfo[], String)

The first uses the cached version of the Class, Ppt, and VarInfo that was provided in the constructor. The second uses the specified variables and the VarInfo information from Ppt. The third specifies each variable explicitly.

When logging is not enabled, calling the logging functions can take a significant amount of time (because the parameters need to be evaluated and passed). To minimize this, a function logOn() is provided to see if logging is enabled. It is recommended that code of the following form be used for efficiency:

if (Debug.logOn()) {
  Debug.log (getClass(), ppt, "Entering routine foo");
}

Track logging also can work with other loggers. Each of the logging methods has an alternative version that also accepts a logger as the first argument. In this case, normal track logging is performed if the class, ppt, and vars match. If they don’t match, the same information is logged via the specified logger. For example:

if (Debug.logOn || logger.isLoggable (Level.FINE)) {
  Debug.log (logger, getClass(), ppt, "Entering routine foo");
}

The above will print if either the tracking information matches or if the specified logger is enabled.

Convenience methods are available for track logging invariants. In this case the class name, ppt, and variable information are all taken from the invariant. The available methods are:

logOn()
logDetail()
log (String)
log (Logger, String)

These correspond to the Debug methods described above. They are the recommended way to log information concerning invariants.

Track logging also provides one additional level of detail. The function logDetail() returns whether or not more detailed information should be printed. This should be used for information which is not normally interesting or especially voluminous output. Often statements using logDetail() should be commented out when not in active use.


Previous: , Up: Track logging   [Contents][Index]

3.1.2 Track log output

Each call to a track log method will produce output in the same basic format. Space for three variables is always maintained for consistency:

 daikon.Debug: <class>: <ppt>: <var1>: <var2>: <var3>: <msg>

If showTrackback is enabled, the ‘traceback’ will follow each line of debug output.


Previous: , Up: Track logging   [Contents][Index]