nus-apr / cerberus

Research Acceleration Platform that provides interface to multiple state-of-the-art program analysis tools including but not limited to fuzzing, static analysis and program repair.
MIT License
65 stars 30 forks source link

Issues regarding java repair tools #182

Closed Hzxin closed 5 months ago

Hzxin commented 5 months ago

Description

[Branch] composite-workflow

The following issues were encountered for the following tools: TBar, Arja_e, Arja on Defects4j & vul4j under TP2 (no localisation provided)


Arja & Arja_e Issue

[Composite workflow] Running arja/arja_e on d4j & other benchmarks on TP2 (no localization provided) will always freeze during fault localization.

To reproduce, in CW, with arja or arja_e (required small modification in arja_e driver since it does not support TP2 yet): cerberus -task repair --debug --task-profile=TP2 --tool=arja --benchmark=defects4j --bug-index=3 (Remark: if you encounter null pointer exception or class not found exception at Gzoltar, refer to the Gzoltar Issue below)

The above will timeout & tool exited with code 134. The Gzoltar process is terminated due to timeout (refer to below code)

Debug: The Gzoltar freezes during runTestMethod. Running the above process in 1h or 6h produces the same stdout / stderr msg and freezes at the same test.

Cause: In GZoltarFaultLocalizer3:

The std-output & error buffer are filled but are not being read. As a result, the process (gzoltar localization script) will be blocked waiting to write. This explains why running 1h / 6h produces the same stdout / stderr & always freezes at the same part. The process 'p' will always exit with code 134 (blocked till timeout).

ProcessBuilder pb = new ProcessBuilder();
...
        pb.command("bash", Paths.get(externalProjRoot, "localization", "localize.sh").toAbsolutePath().toString(),
                Paths.get(binJavaDir).toAbsolutePath().toString(), Paths.get(binTestDir).toAbsolutePath().toString(),
                String.join(File.pathSeparator, absoluteDeps), Paths.get(gzoltarDataDir).toAbsolutePath().toString());

        pb.directory(Paths.get(externalProjRoot, "lib").toFile());

        Process p = pb.start();
        try {
            p.waitFor();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

Suggested solution:

can do processBuilder.redirectOutput & processBuilder.redirectError to ensure the buffer is not full & prevent blocking of the process.


TBar Image Issue

In FL.sh:

  1. Missing class_dir in listTestMethod java classpath. GZoltar will fail for unsuccessful loading of class.

    CLASS_DIR=$PROJECT_DIR/target/classes
    TEST_DIR=$PROJECT_DIR/target/test-classes
    ...
    java -cp $TEST_DIR:$JUNIT_JAR:$HAMCREST_JAR:$GZOLTAR_CLI_JAR com.gzoltar.cli.Main listTestMethods $TEST_DIR --outputFile $UNIT_TESTS_FILE
  2. The class paths /target/classes & /target/test-classes will only work for maven-built bugs. For bugs that are built by Gradle, class dir is under /build/java/main & test dir is under /build/java/test. For bugs that are built by Ant, class dir shall be under /build & test dir is under /build-tests.

  3. Missing maven dependencies class path. This will fail Gzoltar for unsuccessful loading of class. Similarly, for 'Ant' project, the class path should include /lib/* to include all dependecies.

The metadata json contains all the info about the classpaths, for convenience, it might be better to pass test-class-dir, class-dir retrieved from metadata in TBar driver to the FL.sh script as arguments.


Hzxin commented 5 months ago

Additional Issue Regarding Driver:

Built script not run for TP1 with TBar.

The built script is skipped in TP1 setting, (not run_fl branch). Some bugs will have missing /test-classes in the directory when the bug is not compiled.

if not run_fl:
            self.emit_debug("Creating FL data file from provided info")
            self.write_fl_data(bug_info, failed_tests_file, fl_data)
else:
            cmd = f"bash ./FL.sh {join(self.dir_expr,'src')} {bug_id_str} {join(self.dir_setup,bug_info[self.key_build_script])}"
            self.run_command(
                cmd,
                dir_path=self.tbar_root_dir,
                env=env,
                log_file_path=self.log_output_path,
            )