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

## 9 Troubleshooting

This chapter gives solutions for certain problems you might have with Daikon. It also tells you how to report bugs in a useful manner.

If, after reading this section and other parts of the manual, you are unable to solve your problem, you may wish to send mail to one of the mailing lists (see Mailing lists).

Next: Large dtrace files, Up: Troubleshooting [Contents][Index]

### 9.1 Problems running Daikon

You may find the debugging flags `--debug` and `--dbg category` useful if you wish to track down bugs or better understand Daikon’s operation; see Daikon debugging options. See Configuration options, for another way to adjust Daikon’s output.

Next: File input errors, Up: Daikon problems [Contents][Index]

#### 9.1.1 Can’t run Daikon: could not find or load main class, or NoClassDefFoundError

Either of these errors:

    Error: Could not find or load main class daikon.Chicory
    Exception in thread "main" java.lang.NoClassDefFoundError: daikon/Chicory

means that you have not put `daikon.jar` on the classpath.

More generally, an error such as one of these:

    Error: Could not find or load main class mypackage.MyClass
    Exception in thread "main" java.lang.NoClassDefFoundError: mypackage/MyClass

means that Java did not find the class `mypackage.MyClass` on the classpath. To correct the problem, you need to make sure that the directory or jar file that contains file `mypackage/MyClass.class` is on your classpath. The classpath is passed as a command-line argument such as `-cp` or `-classpath`.

When investigating such a problem, you should verify that you can run your program when not using Daikon; for example, if you are trying to run `java -cp myclasspath:${DAIKONDIR}/daikon.jar daikon.Chicory mypackage.MyClass arg1 arg2 arg3`, then make sure that the identical command without `daikon.Chicory` works, in this case `java -cp myclasspath:${DAIKONDIR}/daikon.jar mypackage.MyClass arg1 arg2 arg3`. If both commands issue the same error, then the problem is unrelated to Daikon. If the two commands behave differently, that is a bug in Daikon.

Next: decl format errors, Previous: Can't run Daikon, Up: Daikon problems [Contents][Index]

#### 9.1.2 File input errors

If Daikon terminates with an error such as

    Error at line 530 in file test.dtrace

and inspection of the indicated file at the indicated line number does not help you to discern what is wrong, you may wish to re-run Daikon with the `show_stack_trace` option. The exact syntax for this is:

    --config_option daikon.Debug.show_stack_trace=true

The additional information in the resulting exception stack trace should indicate where the problem is occurring.

Next: Too much output, Previous: File input errors, Up: Daikon problems [Contents][Index]

#### 9.1.3 decl format errors

If Daikon terminates with an error such as

    decl format '2.0' does not match previous setting at line 4 in file test.dtrace

it means you are using multiple `.dtrace` and/or `.decls` files and they are not all in the same format. (See Declaration version in Daikon Developer Manual for information about how to determine a data file’s format.)

The most probable cause is you are using at least one version 1 `.decls` file or `.dtrace` file generated by an older version of Chicory/DynComp and at least one current `.decls` file or `.dtrace` file (which defaults to version 2) as input to Daikon. (Note that the C/C++ front end Kvasir generates a version 2 file `.decls`.) The way to avoid this problem is to use your Java-DynComp-generated `.decls` files as input to Chicory. The resulting `.dtrace` file will contain the comparability values from the `.decls` file(s) and can then be used as input to Daikon. Passing a `.decls` file to Chicory is described in Detecting invariants in Java programs, for example:

    java -cp ${DAIKONDIR}/daikon.jar daikon.Chicory \
         --comparability-file=MyClass.decls-DynComp \
         mypackage.MyClass arg1 arg2 arg3

Next: Missing output invariants, Previous: decl format errors, Up: Daikon problems [Contents][Index]

#### 9.1.4 Too much output

Sometimes, Daikon may produce a very large number of seemingly irrelevant properties that obscure the facts that you were hoping to see. Which properties are irrelevant depends on your current task, so Daikon provides ways for you to customize its output. See Daikon’s command-line options (see Running Daikon), and the techniques for enhancing its output (see Enhancing Daikon output), including its configuration options (see Configuration options). The options for the front ends — such as DynComp (see DynComp for Java options), Chicory (see Chicory options) and Kvasir (see Kvasir options) — give additional control.

Some irrelevant properties are over unrelated variables, like comparing an array index to elements of the array. You should always use the DynComp tool (see DynComp for Java, DynComp for C/C++) to avoid producing such properties.

Some irrelevant properties are not relevant to the domain (e.g., bitwise operations). You can exclude whole classes of unhelpful invariants from Daikon’s output (see Options to enable/disable specific invariants).

Some irrelevant properties are over variables you do not care about, or are in parts of the program that you do not care about. You can exclude certain variables or procedures from Daikon’s output (see Processing only part of the trace file and Options to enable/disable derived variables).

Some irrelevant properties are logically redundant — multiple properties express the same facts in different ways. You can eliminate such properties from Daikon’s output (see Options to control invariant detection).

Some irrelevant output indicates a deficiency in your test suite: your test suite is so small that many arbitrary properties hold over it. This happens when the test suite does not execute the code with a broad distribution of values, but only executes the code with a few specific values. This problem disappears if you augment your test suite so that it exercises the code with more different values.

More generally, each property that Daikon produces is a true fact about how the target program behaved. However, some of these facts would be true for any execution of the target program, and others are accidents of the particular executions that Daikon observed. Both types of facts may be useful, but for different reasons: the former tell you about your program, and the latter tell you about your test suite (and how to improve it!).

Next: True invariants are not reported due to output filters, Previous: Too much output, Up: Daikon problems [Contents][Index]

#### 9.1.5 Missing output invariants

Daikon may sometimes fail to output invariants that you expect it to output. Here are some reasons why this may happen:

- There is a sample that violates the invariant
- The invariant is true, but does not pass one of the output filters (see True invariants are not reported due to output filters).
- One or more of the variables in the invariant always has the same value as another variable. Daikon only prints invariants over one variable (the leader) from the set of equal variables (see Equal variables).
- The program point had no samples (see No samples).

There are two command-line options (`--disc_reason` and `--track`) that will display information about invariants that are not printed. The `--disc_reason` option will indicate why a particular invariant was discarded in most cases. If it does not provide enough information, try the `--track` option which traces the invariant through all of Daikon’s processing steps. See Daikon debugging options for more information.

Note that in each case the description (class, variables, program point) of the invariant must be entered carefully. It may be helpful to try the option on a similar invariant that is printed to make sure that each is specified correctly.

Next: No samples, Previous: Missing output invariants, Up: Daikon problems [Contents][Index]

#### 9.1.6 True invariants are not reported due to output filters

Sometimes, Daikon does not report an invariant, even though Daikon has computed that the invariant is true throughout the sample data. Daikon only reports invariants that satisfy all the output filters (see Invariant filters).

Here, we discuss two common reasons for filtering: statistical justification, and implication.

Daikon only reports a property if it is statistically justified, and Daikon needs to see enough samples for the statistical test to work. So, there may be a property that is true, but if too few samples were seen, then Daikon will not report it. In a longer trace, Daikon would report the property. You can adjust Daikon’s confidence limit so that the property is reported even in the short executions; see the command-line option `--conf_limit`. For instance, supplying `--conf_limit 0` causes all properties that have not been falsified to be printed.

Daikon does not report redundant, or implied, invariants (see Redundant invariants). The purpose of this is to avoid cluttering the output with facts that add no new information. Here are a few examples:

- Suppose that both `i < j` and `i <= j` are true. Daikon would report only `i < j`; Daikon would not report `i <= j`, which is implied by what Daikon has reported. Further suppose that a longer execution had a sample containing `i=22, j=22`. Only `i <= j` would be true in the second execution, and Daikon would report it. (The invariant `i < j` is an example of a false positive or overfitting in the first execution.)
- If two or more variables are found to be equal, then Daikon chooses one of them (the leader) and only prints invariants over the leader, not the other variables (see Equal variables).

Next: No return from procedure, Previous: True invariants are not reported due to output filters, Up: Daikon problems [Contents][Index]

#### 9.1.7 No samples and no output

When Daikon produces no output, that is usually a result of it having no samples from which to generalize. Use the `--output_num_samples` flag to Daikon to find out how many samples it is observing. This section tells you how to debug your problem if the answer is 0, but you believe that there are samples in the file you are feeding to Daikon.

Using the normal dataflow hierarchy, Daikon explicitly processes `:::EXIT` program points only. Other program points, such as `:::ENTER` program points, are processed indirectly when their corresponding `:::EXIT` points are encountered. (You can disable this behavior with the `--nohierarchy` switch to Daikon; see Options to control invariant detection.) If no `:::EXIT` program points are present (perhaps every execution threw an exception, you filtered out all the `:::EXIT` program points, or the data trace is obtained from spreadsheet data instead of from a program execution), then Daikon will not process any of the other program points, such as the `:::ENTER` program points. You can make Daikon print information about unmatched procedure entries via the ‘`daikon.FileIO.unmatched_procedure_entries_quiet`’ configuration option (see General configuration options).

Another way to increase the number of invariants printed out is to lower the confidence bound cutoff. Daikon only prints invariants whose confidence level is greater than the bound specified by the `--conf_limit` option (see Options to control invariant detection). In order to maximize the number of invariants printed, use `--conf_limit 0` to see all invariants Daikon is considering printing.

To try to determine why an invariant is not printed, use the `--track` to determine why Daikon does not print an invariant (see Daikon debugging options).

Next: Unsupported class version, Previous: No samples, Up: Daikon problems [Contents][Index]

#### 9.1.8 No return from procedure

Daikon sometimes issues a warning that a procedure in the target program was entered but never exited (that is, the target program abnormally terminated). In other words, the `.dtrace` file contains more entry records than exit records for the given procedure. Some procedures that were entered were never recorded to have exited: either they threw an exception, skipping the instrumentation code that would have recorded normal termination, or the target program’s run was interrupted. When this happens, the entry sample is ignored; the rationale is that the particular values seen led to exception exit, were probably illegal, and so should not be factored into the method preconditions.

In some cases, exceptional exit from a procedure can cause procedure entries and exits (in the trace file) to be incorrectly matched up; if they are incorrectly matched, then the `orig(x)` values may be incorrect. Daikon has two techniques for associating procedure exits with entries — the nonce technique and the stack technique. If a `.dtrace` file uses the nonce technique, `orig(x)` values are guaranteed to be correct. If a `.dtrace` file uses the stack technique, then incorrect `orig(x)` values are likely to occur. You can tell which technique Daikon will use by examining the `.dtrace` file. If the second line of each entry in the `.dtrace` file is ‘`this_invocation_nonce`’, then Daikon uses the nonce technique. Otherwise, it uses the stack technique. Which technique is used is determined by the front end, which creates the `.dtrace` file, and typically cannot be controlled by the user.

Next: Out of memory, Previous: No return from procedure, Up: Daikon problems [Contents][Index]

#### 9.1.9 Unsupported class version

Daikon requires a Java 8 (or newer) JVM (see Requirements). An error such as

    Exception in thread "main" java.lang.UnsupportedClassVersionError:
    daikon/Daikon (Unsupported major.minor version 52.0)

indicates that you are trying to run Daikon on an older JVM. You need to install a newer version of Java in order to run Daikon.

Next: Simplify errors, Previous: Unsupported class version, Up: Daikon problems [Contents][Index]

#### 9.1.10 Out of memory

If Daikon runs out of memory, generating a message like

    Exception in thread "main" java.lang.OutOfMemoryError
        <<no stack trace available>>

then it is likely that it has created more invariants than will fit in memory. The number of invariants created depends on the number of program points and the number of variables at each program point. In addition to the solutions discussed in Reducing program points, you can try increasing the amount of memory available to Java with the `-Xmx` argument to `java`. (This flag is JVM-specific; see your JVM documentation for details. For instance, its name in JDK versions 1.2 and earlier is `-mx`.) However, the value you use should be less than your system’s total amount of physical memory. Some implementations of Java use a surprisingly small default, such as 64 megabytes; to permit use of up to 2048 megabytes, you would run Java like so:

    java -Xmx7g ...

though you can use much more depending on the limitations of your JVM.

If you are using Chicory’s `--daikon` command-line argument to run Daikon, then you must separately indicate the amount of memory available to Chicory and to Daikon (the latter with Chicory’s `--heap-size` command-line argument). For example:

    java -Xmx7g daikon.Chicory --comparability-file=MyClass.decls-DynComp \
         --heap-size=7g --daikon mypackage.MyClass arg1 arg2 arg3

When using the Java `HotSpot` JVM, an additional parameter may need to be increased. `HotSpot` uses a separately-limited memory region, called the permanent generation, for several special kinds of allocation, one of which (interned strings) Daikon sometimes uses heavily. It may be necessary to increase this limit as well, with the `-XX:MaxPermSize=` option. For instance, to use 512 megabytes, of which at most 256 can be used for the permanent generation, you would run Java like so:

    java -Xmx7g -XX:MaxPermSize=256m

Another possible problem is the creation of too many derived variables. If you supply the `--output_num_samples` option to Daikon (see Options to control Daikon output), then it will list all variables at each program point. If some of these are of no interest, you may wish to suppress their creation. For information on how to do that, see Options to enable/disable derived variables. Also see Reducing variables for other techniques.

Any output generated before the out-of-memory error is perfectly valid.

Next: Contradictory invariants, Previous: Out of memory, Up: Daikon problems [Contents][Index]

#### 9.1.11 Simplify errors

The warning ‘`Could not utilize Simplify`’ and/or ‘`Couldn't start Simplify`’ indicates that the Simplify theorem-prover could not be run; this usually indicates that the Simplify binary was not found on the user’s path.

If Simplify is not used, certain redundant (logically implied) invariants may appear in Daikon’s output. The output is correct, but more verbose than it would be if you used Simplify.

Up: Simplify errors [Contents][Index]

#### 9.1.11.1 Installing Simplify

Obtain Simplify from https://web.archive.org/web/20170201034825/https://www.kindsoftware.com/products/opensource/archives/Simplify-1.5.5-13-06-07-binary.zip, and unzip the zip file.

Either place the appropriate binary on your path, named `Simplify`, or set the `simplify.path` property to its absolute pathname.

Note: Older versions of the `Z3` theorem prover (https://github.com/Z3Prover/z3) can replace Simplify, but more recent versions do not support the Simplify syntax. In the future, it would be nice to rewrite Daikon’s theorem-prover interface to use the SMT-LIB2 language, so that a compatible solver like `Z3` or `CVC4` could be used. The main challenge to this is writing the boilerplate code to output each different kind of invariant in SMT-LIB2 format.

Next: Method needs to be implemented, Previous: Simplify errors, Up: Daikon problems [Contents][Index]

#### 9.1.12 Contradictory invariants

The invariants Daikon produces are all true statements about the supplied program executions, so they should be mutually consistent. Sometimes, however, because of a bug or a limitation in Daikon, contradictory invariants are produced.

One known problem involves object invariants. Daikon infers object invariants by observing the state of an object when its public methods are called. However, if an object has publicly accessible fields that are changed by code outside the class, after which no public methods are called, invariants about the state of the object as seen by other code can contradict the class’s object invariants. A workaround is to allow changes to an object’s state from outside the class only by way of public methods.

Besides confusing the user, contradictory invariants also cause trouble for the Simplify theorem prover that implements the `--suppress_redundant` option. When the invariants at a particular program point contradict each other or background information (such as the types of objects), Simplify becomes unable to distinguish redundant invariants from non-redundant ones.

The best solution in such cases is to fix the underlying cause of the contradictory invariants, but since that is sometimes not possible, Daikon will try to work around the problem by avoiding the invariants that cause a contradiction. Daikon will attempt to find a small subset of the invariants that aren’t mutually consistent, and remove one, repeating this process until the remaining invariants are consistent. (Note that the invariants are removed only for the purposes of processing by Simplify; this does not affect whether they will be printed in the final output). While this technique can allow redundant invariants to be found when they otherwise wouldn’t be, it has some drawbacks: the choice of which invariant to remove is somewhat arbitrary, and the process of finding contradictory subsets can be time consuming. The removal process can be disabled with the `daikon.simplify.LemmaStack.remove_contradictions` configuration option.

Next: Daikon runs slowly, Previous: Contradictory invariants, Up: Daikon problems [Contents][Index]

#### 9.1.13 Method needs to be implemented

Daikon may produce output like the following (but all on one line):

    method daikon.inv.binary.twoSequence.SubSequence.format_esc()
    needs to be implemented:
    this.theArray[0..this.topOfStack] is a subsequence of
    orig(this.theArray[0..this.topOfStack])

This indicates that a particular invariant (shown on the last two lines above) cannot be formatted using the current formatting. In this example, the invariant can be formatted using Daikon’s default formatting (which is how it is shown above), but (as of April 2002) Daikon cannot output it in `ESC` format, so Daikon prints the above message instead. The message also shows exactly what Java method needs to be implemented to correct the problem. You can ignore such messages, or else use an output formatting that can handle those invariants. Annotate (see Annotate) automatically ignores unformattable invariants.

Next: Bigger traces cause invariants to appear, Previous: Method needs to be implemented, Up: Daikon problems [Contents][Index]

#### 9.1.14 Daikon runs slowly

If Daikon runs slowly, there are three general possible reasons:

- You did not use the DynComp tool (see Dynamic abstract type inference (DynComp)) to generate comparability sets. Without DynComp, Daikon typically runs more than an order of magnitude slower.
- The front end, such as DynComp or Chicory, took a long time to collect, then output, large amounts of data about your program execution.
- It took a long time to analyze that data trace and infer invariants over it.

To understand which part is the bottleneck, you might want to separate the creation and analysis of the trace file, so you can compare the time of each part. The next two sections address each of these issues.

You may find command-line arguments like the following useful when debugging Daikon’s performance:

       --config_option daikon.Daikon.progress_delay=100
       --show_progress --dbg daikon.init

For additional details on improving Daikon’s performance, see Out of memory.

#### 9.1.14.1 Slow creation of large trace files

Creating a trace can take a long time, because of the time to traverse and print the values of many variables. Reducing the number of program points or variables can speed up both creation and analysis of trace files. For instance, you might configure your front end to skip certain procedures (helper procedures, libraries) or not to output certain variables (large arrays or static variables), or you might split a trace file into multiple parts and process them separately. For details, see Large dtrace files.

#### 9.1.14.2 Slow inference of invariants

Daikon’s run time and space depend on the particular data that it analyzes. Informally, invariant detection time can be characterized as

    O((vars^3 * falsetime + trueinvs * testsuite) * procedures)

where vars is the number of variables at a program point, falsetime is the (small constant) time to falsify a potential invariant, trueinvs is the (small) number of true invariants at a program point, testsuite is the size of the test suite, and procedures is the number of instrumented program points. The first two products multiply a number of invariants by the time to test each invariant.

If there are many true invariants over an input, then Daikon continues to check them all over the entire input. By contrast, if not many invariants are true, then Daikon need no longer check them once they are falsified (which in practice happens quickly). Daikon processes each procedure independently.

Another important factor affecting Daikon’s run time is the number of variables. Because invariants involve up to three variables each, the number of invariants to check is cubic in the number of variables at a single program point. Derived variables (such as `a[i]`, introduced whenever there is both an array `a` and an integer `i`) can increase the number of variables substantially. The `daikon.derive.Derivation.disable_derived_variables` and individual `daikon.derive.*.*.enabled` configuration variables (see Options to enable/disable derived variables) may be used to disable derived variables altogether or selectively, at the cost of detecting fewer invariants, especially over sequences.

As noted earlier, using a comparability analysis (see Dynamic abstract type inference (DynComp)) also reduces the number of invariants that Daikon checks, and thereby speeds up Daikon.

Previous: Daikon runs slowly, Up: Daikon problems [Contents][Index]

#### 9.1.15 Bigger traces cause invariants to appear

Suppose that you run Daikon twice. The first time, you supply Daikon with traces T. The second time, you supply Daikon with more traces T+T’ for the same program points. The second Daikon execution may report the same invariants, fewer invariants, more invariants, or a mix.

The second execution may report the same invariants if the additional samples in T’ do not add any more information than those in T,

The second execution may report fewer invariants, because the additional data has eliminated overfitting (false positives). There may have been some accidental property of the shorter executions that is not true in the longer ones.

The second execution may report more invariants, because the first execution did not report some invariants that were true. True invariants are not reported due to output filters describes reasons that Daikon might not report these invariants that are true — for example, because they were not statistically justified.

Another reason that the second execution might report more invariants is if T+T’ contains samples for program points that were not in T. The first execution will not report any facts about program points that were not executed.

Next: Chicory problems, Previous: Daikon problems, Up: Troubleshooting [Contents][Index]

### 9.2 Large data trace (.dtrace) files

Running instrumented code can create very large `.dtrace` files. This can be a problem because writing the large files can slow the target programs substantially, or because the large files may fill up your disk.

This section describes ways to work around this problem.

Next: Scratch directory, Up: Large dtrace files [Contents][Index]

#### 9.2.1 Compressed .dtrace files

You can reduce file size by specifying a trace file name that includes `.gz` at the end. See the `--dtrace-file=FILENAME` argument to Chicory or Kvasir, or the `DTRACEFILE` environment variable. (Compression is the default if you don’t specify a filename.)

Next: Run Daikon online, Previous: Compression, Up: Large dtrace files [Contents][Index]

#### 9.2.2 Save large files in a scratch directory

Sometimes, the problem is just filling up your user account with large files. You can instead create `.dtrace` files in a temporary directory. Under Linux, this is often called `/scratch`. Typically you should create a subdirectory called `/scratch/$USER/`.

Next: Multiple smaller files, Previous: Scratch directory, Up: Large dtrace files [Contents][Index]

#### 9.2.3 Run Daikon online

The term online execution refers to running Daikon at the same time as the target program. The front end supplies information to Daikon directly over a socket or pipe, without writing any information to a file. This can avoid some I/O overhead, and it prevents filling up your disk with files.

The Chicory front end supports online execution via use of the `--daikon-online` option (see Chicory miscellaneous options). The Kvasir front end supports online execution via use of (normal or named) Linux pipes (see Online execution).

In the future, Daikon may be able to output partial results as the target program is executing.

Next: Less information per file, Previous: Run Daikon online, Up: Large dtrace files [Contents][Index]

#### 9.2.4 Create multiple smaller data trace files

It is usually possible to create an `.inv` file equivalent to the one that Daikon would have computed, had Daikon been able to process your entire program over its full test suite. First, use the techniques below (see Reducing program points) to split your `.dtrace` file into parts. Next, run Daikon on each resulting `.dtrace` file. Finally, use the `MergeInvariants` tool (see MergeInvariants) to combine the resulting `.inv` files into one.

Previous: Multiple smaller files, Up: Large dtrace files [Contents][Index]

#### 9.2.5 Record or read less information in the data trace file

You can record less information from each program execution, or you can make Daikon read less information from the trace files. It’s usually most efficient to do the pruning as early in the process as possible. For example, it is better to have the front end output less information, rather than have Daikon ignore some of the information.

Next: Reducing variables, Up: Less information per file [Contents][Index]

#### 9.2.5.1 Reducing program points (functions)

Here are ways to compute invariants over a subset of the program points (functions) in your program.

1. Make your front end instrument fewer files. This is often most applicable if you are using a source-based front end.
2. You can instrument fewer procedures.
   - With Chicory, use the `--ppt-omit-pattern` or `--ppt-select-pattern` options (see Processing only part of the trace file, or Chicory options) to restrict which program points are traced. Running the instrumented program will result in a smaller `.dtrace` file that contains fewer records.
   - With Kvasir, use the `--ppt-list-file` option to specify a list of program points that should be traced (see Tracing only part of a program section for more details).
   - You can remove some program points (functions) from your `.dtrace` file. The `trace-purge-fns.pl` script takes as arguments a (Perl) regular expression and a list of files. It modifies each file in place, removing every program point (function) whose name matches the regular expression. The `-v` flag means to retain rather than discard matching program points. For instance, to create two subparts of a `.dtrace` file — one containing the getters and setters, and the other containing all other functions — use the following commands:

         cp myprog.dtrace myprog-setters.dtrace
         trace-purge-fns.pl -v 'set|get' myprog-setters.dtrace
         cp myprog.dtrace myprog-non-setters.dtrace
         trace-purge-fns.pl 'set|get' myprog-non-setters.dtrace

   - You can make Daikon ignore some program points. With the `--ppt-select-pattern=ppt_regexp` flag (see Processing only part of the trace file), only program points matching the regular expression are processed. Likewise, the `--ppt-omit-pattern=ppt_omit_regexp` option causes program points matching the regular expression to be ignored.

     Also, the configuration variable `daikon.Daikon.ppt_perc` allows a percentage of the program points to be processed. See General configuration options, for details.

Next: Reducing executions, Previous: Reducing program points, Up: Less information per file [Contents][Index]

#### 9.2.5.2 Reducing variables

Here are ways to compute invariants over a subset of the variables in your program. This changes the resulting invariants, because invariants over the missing variables (including any relationship between a missing variable and a retained variable) are not detected or reported. For instance, you might remove uninteresting variables (or ones that shouldn’t be compared to certain others) or variables that use a lot of memory (such as some arrays).

1. You can reduce the number of variables that are output by instrumented code — for instance, output ‘`a`’ and ‘`a.b`’ but not ‘`a.b.c`’. Do this by reducing the class/structure instrumentation depth.
   - With Chicory, use the `--nesting-depth=N` option.
   - With Kvasir, use the `--struct-depth=N` or the `--nesting-depth=N` option.
2. With Kvasir, you can either ignore all global and/or static variables with the `--ignore-globals` and `--ignore-static-vars` options or manually specify a subset of variables to trace using the `--var-list-file` option (see Tracing only part of a program for details)
3. You can pare down an existing `.dtrace` file using the `trace-purge-vars.pl` script. Analogously to the `trace-purge-fns.pl` script, it removes certain variables from all program points in a function (or retains them, with the `-v` flag). After running this command, you will need to edit the corresponding `.decls` file by hand to remove the same variables.
4. You can make Daikon ignore certain variables rather than modifying the `.dtrace` file directly. Analogously with the `--ppt-select-pattern` and `--ppt-omit-pattern` flags, the `--var-select-pattern` and `--var-omit-pattern` flags restrict which variables Daikon processes. (See Processing only part of the trace file, and Chicory options).

Previous: Reducing variables, Up: Less information per file [Contents][Index]

#### 9.2.5.3 Reducing executions

Here are ways to run Daikon over fewer executions of each program point. (You cannot combine the resulting invariants in order to obtain the same result as running Daikon over all the executions.)

1. If you have multiple `.dtrace` files (perhaps resulting from multiple program runs), you can run Daikon on just some of them.
2. You can terminate the instrumented program when it has created a sufficiently large `.dtrace` file. If you interrupt the program while it is in the middle of writing a record to the `.dtrace` file, the last record may be only partially written. Use the `daikon/scripts/trace-untruncate` program to remove the last, possibly partial, record from the file:

       trace-untruncate myfile.dtrace

   modifies `myfile.dtrace` in place to remove the last record.

   Alternately, you can use the `daikon/scripts/trace-untruncate-fast` program. It operates much faster on very large files. In order to use `trace-untruncate-fast`, you must have already compiled it (see Installing Daikon).

3. You can cause the front end to record only a subset of executions of a given procedure, rather than every execution. For example, Chicory’s `--sample-start` command-line option does this (see Chicory miscellaneous options).

Next: Reporting problems, Previous: Large dtrace files, Up: Troubleshooting [Contents][Index]

### 9.3 Problems with Chicory

Before reporting or investigating a problem with Chicory, always check that the program executes properly when not being run under Chicory’s control.

For example, if a command such as

    java -cp myclasspath:${DAIKONDIR}/daikon.jar daikon.Chicory \
         DataStructures.StackArTester args...

fails with an error, then first try

    java -cp myclasspath:${DAIKONDIR}/daikon.jar DataStructures.StackArTester args...

- If the latter command also fails, the problem is not with Chicory. First solve your Java problem, then once again attempt to use Chicory.
- If the latter command does not fail, then you have likely found a bug in Chicory; please report it if it is not already explained in this manual.

Next: ClassFormatError LVTT entry does not match, Up: Chicory problems [Contents][Index]

#### 9.3.1 BCEL must be in the classpath, or couldn’t find or load main class

If Chicory throws one of the following errors:

    BCEL must be in the classpath.  Normally it is found in daikon.jar.

    couldn't find or load main class

then the problem is most likely that the classpath does not contain `daikon.jar`.

Next: Attempted duplicate class definition error, Previous: BCEL must be in the classpath, Up: Chicory problems [Contents][Index]

#### 9.3.2 ClassFormatError LVTT entry does not match

If Chicory throws an error such as the following:

    Exception in thread "main" java.lang.ClassFormatError:
      LVTT entry for 'v' in class file javautil/ArrayList17 does not match any LVT entry

then the problem is most likely that the classpath contains a version of the BCEL library that is newer than the 6.0 release. A modification was made to Apache BCEL after the 6.0 release that causes this problem. The incompatible version might appear in `bcel.jar`, in Java’s `rt.jar`, or elsewhere. You should either remove that version of BCEL from the classpath, or you should ensure that it appears after `daikon.jar`, which contains the correct version of BCEL. (If you are running Daikon from sources rather than from `daikon.jar`, then ensure that `${DAIKONDIR}/java/lib/bcel.jar` is the first version of BCEL on the classpath.)

Previous: ClassFormatError LVTT entry does not match, Up: Chicory problems [Contents][Index]

#### 9.3.3 Attempted duplicate class definition error

If Chicory throws an error such as the following:

    Exception in thread "main" java.lang.LinkageError:
    java.lang.LinkageError: loader (instance of  sun/misc/Launcher$AppClassLoader):
    attempted duplicate class definition for name: "SquarePanel"

then the problem is most likely that some method in your program uses Java runtime services to set up an additional thread that can get invoked asynchronously. One example is using the `java.lang.SecurityManager` class to set up a `SecurityManager` via `System.setSecurityManager`. The easiest way to work around this is to use the `--ppt-omit-pattern` option to Chicory. After you have located the problem method, rerun Chicory with the additional option:

    --ppt-omitpattern=MyPackage.MyProblemMethod

Next: Further reading, Previous: Chicory problems, Up: Troubleshooting [Contents][Index]

### 9.4 Reporting problems

If you find a bug, want to request a new feature, or have a suggestion to improve Daikon or its documentation, open an issue at https://github.com/codespecs/daikon/issues. (If you can’t figure out how to do something or do not understand why Daikon works the way it does, that is a bug, too — in the Daikon documentation. Please report those as well.) We will try to assist you and to correct any problems, so please don’t hesitate to ask for help or report difficulties. Additionally, if you can contribute enhancements or bug fixes, those will be gratefully accepted. If you have a question about the source code of Daikon or Kvasir, send email to daikon-developers@googlegroups.com.

In order for us to assist you, please provide a complete and useful bug report. Your bug report must provide all the information that is required in order to replicate the bug and verify that our fix corrects the problem. If you do not provide complete information, we will not be able to assist you.

Your bug report should include:

- how you obtained Daikon (did you download its distribution or build it from source?), and the version of Daikon, which appears in the file `daikon/README.txt` and is also printed when you run Daikon. If you are not using the most recent version, download a newer version from http://plse.cs.washington.edu/daikon/ to see whether your problem has already been corrected. If you are using a modified version of Daikon, you should verify that the problem exists in Daikon as distributed.
- a description of exactly what you did (in sufficient detail for others to reproduce the problem), exactly what happened, and what you expected to happen instead. One good way to describe what you did is a list of commands that, if executed, reproduces your error. A good way to show what happened is a transcript of execution of all of the commands. (A list of commands and a transcript are much more useful than a vague description; please don’t give vague English when you can supply a more precise specification instead. Also, please don’t give screenshots of a command terminal, which are hard to read and reproduce; instead, cut and paste the contents.) It is crucial that you not omit steps in your report. For example, include instructions for installing your software and all customizations to the software or your environment, including all relevant environment variables. Please do not force the developers to speculate about what you did; that would be a waste of their time, since you already have the knowledge.
- input files that permit the problem to be replicated (by following the detailed steps in your bug report). The most important thing is the original, uninstrumented source files (e.g., `.java`), and any inputs/tests used when you ran the program. It is also helpful to include instrumented source files, `.decl` files, and `.dtrace` files. You may include `.inv` files, but as an adjunct rather than a replacement for other files: `.inv` files are binary in format, hard to inspect, and the format may change from one version of Daikon to another.
- the JDK or JRE version (e.g., the complete output of ‘`java -version`’), and operating system and revision you are using (e.g., Ubuntu 18.04).
- any other information that you consider relevant.

When users provide an inadequate bug report, it is frequently more difficult for us to reproduce an error than to correct it. If you make it easy for us to reproduce and verify the problem, then it is much more likely to be corrected. Thanks for helping us to help you!

You may also wish to take advantage of the Daikon mailing lists (see Mailing lists).

Previous: Reporting problems, Up: Troubleshooting [Contents][Index]

### 9.5 Further reading

More information on Daikon can be found in the Daikon Developer Manual (see Introduction in Daikon Developer Manual). For instance, the Daikon Developer Manual indicates how to extend Daikon with new invariants, new derived variables, and front ends for new languages. It also contains information about the implementation and about how to debug.

You may find discussions on the mailing lists (see Mailing lists) helpful. The mailing list archives may contain helpful information, but we strive to incorporate that information in this manual so that you don’t have to search the archives as well.

For further reading, see the list of publications at the Daikon homepage, http://plse.cs.washington.edu/daikon/pubs/.

Previous: Reporting problems, Up: Troubleshooting [Contents][Index]