@@ -168,9 +168,9 @@ In that case, you can [change maximum heap size](https://docs.oracle.com/cd/E217
---
-### User-defined method models:
+### User-defined method models:
-The following is an example for defining your own method models.
+The following is an example for defining your own method models.
For the methods in this class:
```Java
@@ -233,7 +233,7 @@ For fields, we specify the signature of the field in `AccessPath` and its type i
You can view the output of Slicer4J in 3 different formats: [Source Map](#Source-Map), [Raw Slice](#Raw-Slice), and [#Graph](Graph).
-Let's see the output of slicing the `SliceMe` program (found under `benchmarks/SliceMe`):
+Let's see the output of slicing the `SliceMe` program (found under `benchmarks/SliceMe`):
```Java
1. public class SliceMe {
@@ -278,16 +278,18 @@ In this example, we slice from line 9 in the `SliceMe.java` file: `System.out.pr
### Source Map:
This output is only generated if the JAR is compiled with debug information.
-Slicer4J outputs a list of `files-name: source-code-line-number` for each statement that compose the slice.
+Slicer4J outputs a list of `files-name: source-code-line-number` for each statement that compose the slice.
This output is stored in the output folder in a file called `slice.log`
+> **Note:** For programs using **lambdas** or containing **synthetic classes** (e.g., Compiler-generated inner classes), the line number will appear as `-1`. This indicates that the entry corresponds to a synthetic instruction with no direct source code origin, though the underlying data dependency is correctly tracked.
+
For the example, `slice.log` contains:
```
SliceMe:4
SliceMe:7
SliceMe:9
```
-Which indicates that the slice is:
+Which indicates that the slice is:
```Java
4. if (args.length > 0){
7. parsed = null;
@@ -318,7 +320,7 @@ Here we see that all statements are within the same thread (thread #1), and we s
---
### Graph:
-Slicer4J outputs a [dot graph](https://graphviz.org/doc/info/lang.html) whose nodes are statements in the slice and edges are data and control dependencies between the statements.
+Slicer4J outputs a [dot graph](https://graphviz.org/doc/info/lang.html) whose nodes are statements in the slice and edges are data and control dependencies between the statements.
This output is stored in the output folder in a file called `slice-graph.pdf`
@@ -329,7 +331,7 @@ For the example, `slice-graph.pdf` contents is shown here:
Here we see the control dependencies (dashed edges) and data flow-dependencies (solid edges) between the Jimple statements from the raw slice.
-For example, `$stack3 = lengthof parsed` is data-flow dependent on `parsed = null` through the variable `parsed`, which is written on the edge.
+For example, `$stack3 = lengthof parsed` is data-flow dependent on `parsed = null` through the variable `parsed`, which is written on the edge.
Also, `parsed = null` is control dependent on `if $stack2 <= 0 goto parsed = null`.
---
diff --git a/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/CommandParser.java b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/CommandParser.java
index dec5c5e..5465e6d 100644
--- a/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/CommandParser.java
+++ b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/CommandParser.java
@@ -35,6 +35,16 @@ public class CommandParser {
options.addOption("d", "debug", false, "Enable debug"); // data
options.addOption("once", "once", false, "Slice one step only"); // data
options.addOption("noprint", "noprint", false, "Dont print slices"); // data
+
+ /**
+ * Function-level slicing support.
+ *
+ * Adds {@code --function-slice} option that changes slicing granularity
+ * from line-level to method-level. When enabled, the slicing criterion
+ * is expanded from a single source line to all trace statements within
+ * the containing method, producing a method-grained backward slice.
+ */
+ options.addOption("fs", "function-slice", false, "Perform function-level slicing instead of line-level");
}
@@ -73,6 +83,9 @@ public static Map parse(String[] args){
if (cmd.hasOption("noprint")) {
parsed.put("noprint", "True");
}
+ if (cmd.hasOption("fs")) {
+ parsed.put("fs", "True");
+ }
} catch (ParseException e) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(CMD_LINE_SYNTAX, options);
diff --git a/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/SlicePrettyPrinter.java b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/SlicePrettyPrinter.java
new file mode 100644
index 0000000..f3aac6a
--- /dev/null
+++ b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/SlicePrettyPrinter.java
@@ -0,0 +1,358 @@
+package ca.ubc.ece.resess.slicer.dynamic.slicer4j;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.commons.io.FileUtils;
+
+import ca.ubc.ece.resess.slicer.dynamic.core.accesspath.AccessPath;
+import ca.ubc.ece.resess.slicer.dynamic.core.slicer.DynamicSlice;
+import ca.ubc.ece.resess.slicer.dynamic.core.statements.StatementInstance;
+import guru.nidi.graphviz.attribute.Label;
+import guru.nidi.graphviz.attribute.Style;
+import guru.nidi.graphviz.attribute.ForNodeLink;
+import guru.nidi.graphviz.engine.Format;
+import guru.nidi.graphviz.engine.Graphviz;
+import guru.nidi.graphviz.engine.GraphvizException;
+import guru.nidi.graphviz.engine.Rasterizer;
+import guru.nidi.graphviz.model.MutableGraph;
+import static guru.nidi.graphviz.model.Factory.*;
+import soot.toolkits.scalar.Pair;
+
+/**
+ * Function-level slicing output support.
+ *
+ * Adds structured, human-readable slice reports that group results
+ * by method rather than individual source lines. Used in conjunction
+ * with the {@code --function-slice} CLI option.
+ */
+public class SlicePrettyPrinter {
+
+ private SlicePrettyPrinter() {
+ throw new IllegalStateException("Utility class");
+ }
+
+ /**
+ * Prints the slice results grouped by method signature.
+ *
+ *
Function-level slicing contribution: produces a method-grained view
+ * of the backward slice, where each method lists the source lines that
+ * belong to it. Output is written to {@code slice-function.log}.
+ *
+ * @param outDir output directory for the report file
+ * @param slice the completed dynamic slice
+ */
+ public static void printFunctionSlice(String outDir, DynamicSlice slice) {
+ Map> methodToLines = new LinkedHashMap<>();
+ Map methodToFile = new LinkedHashMap<>();
+
+ for (Pair, Pair> entry : slice) {
+ StatementInstance si = entry.getO1().getO1();
+ if (si == null) {
+ continue;
+ }
+ String sig = si.getMethod().getSignature();
+ methodToLines.computeIfAbsent(sig, k -> new LinkedHashSet<>())
+ .add(si.getJavaSourceFile() + ":" + si.getJavaSourceLineNo());
+ methodToFile.putIfAbsent(sig, si.getJavaSourceFile());
+ }
+
+ List output = new ArrayList<>();
+ output.add("Function-level slice (" + methodToLines.size() + " methods)");
+ output.add(repeat("=", 72));
+
+ int idx = 1;
+ for (Map.Entry> e : methodToLines.entrySet()) {
+ output.add(String.format("[%d] %s", idx++, e.getKey()));
+ output.add(" Source: " + methodToFile.getOrDefault(e.getKey(), "UNKNOWN"));
+ output.add(" Lines: " + e.getValue().size());
+ e.getValue().stream()
+ .sorted()
+ .forEach(l -> output.add(" " + l));
+ output.add("");
+ }
+
+ String fileName = outDir + File.separator + "slice-function.log";
+ try {
+ FileUtils.writeLines(new File(fileName), output);
+ } catch (IOException ex) {
+ System.err.println("Error writing function slice: " + ex.getMessage());
+ }
+ }
+
+ /**
+ * Generates a function-level DOT graph of the slice as a PDF.
+ *
+ * Function-level slicing contribution: groups slice nodes by their
+ * containing method, producing a method-grained dependency graph where
+ * each node is a method and edges represent cross-method data or control
+ * dependencies. Output is written to {@code slice-graph-function.pdf}.
+ *
+ * @param outDir output directory for the graph file
+ * @param slice the completed dynamic slice
+ */
+ public static void printFunctionDotGraph(String outDir, DynamicSlice slice) {
+ MutableGraph g = mutGraph("Function-Level Slice").setDirected(true);
+
+ // Collect unique method signatures and their display names
+ Map methodLabels = new LinkedHashMap<>();
+ for (Pair, Pair> entry : slice) {
+ StatementInstance dest = entry.getO1().getO1();
+ StatementInstance src = entry.getO2().getO1();
+ if (dest != null) {
+ methodLabels.putIfAbsent(dest.getMethod().getSignature(),
+ shortenSignature(dest.getMethod().getSignature()));
+ }
+ if (src != null) {
+ methodLabels.putIfAbsent(src.getMethod().getSignature(),
+ shortenSignature(src.getMethod().getSignature()));
+ }
+ }
+
+ // Build method-level edges, deduplicating (data overrides control)
+ Map methodEdges = new LinkedHashMap<>();
+ for (Pair, Pair> entry : slice) {
+ StatementInstance dest = entry.getO1().getO1();
+ StatementInstance src = entry.getO2().getO1();
+ if (dest == null || src == null) {
+ continue;
+ }
+ String dm = dest.getMethod().getSignature();
+ String sm = src.getMethod().getSignature();
+ if (dm.equals(sm)) {
+ continue; // skip intra-method edges
+ }
+ String edgeType = slice.getEdges(dest.getLineNo(), src.getLineNo());
+ String key = sm + "->" + dm;
+ // Data edges take priority over control edges
+ if (!methodEdges.containsKey(key) || "data".equals(edgeType)) {
+ methodEdges.put(key, edgeType);
+ }
+ }
+
+ // Create nodes
+ Map nodes = new LinkedHashMap<>();
+ for (Map.Entry e : methodLabels.entrySet()) {
+ guru.nidi.graphviz.model.Node n = node(e.getValue());
+ nodes.put(e.getKey(), n);
+ g.add(n);
+ }
+
+ // Create edges
+ for (Map.Entry e : methodEdges.entrySet()) {
+ String[] parts = e.getKey().split("->");
+ String srcSig = parts[0];
+ String destSig = parts[1];
+ String edgeType = e.getValue();
+ guru.nidi.graphviz.model.Node srcNode = nodes.get(srcSig);
+ guru.nidi.graphviz.model.Node destNode = nodes.get(destSig);
+ if (srcNode != null && destNode != null) {
+ Style edgeStyle = "control".equals(edgeType) ? Style.DASHED : Style.SOLID;
+ g.add(srcNode.link(to(destNode).with(edgeStyle, Label.of(edgeType))));
+ }
+ }
+
+ try {
+ Graphviz.fromGraph(g).rasterize(Rasterizer.builtIn("pdf"))
+ .toFile(new File(outDir + File.separator + "slice-graph-function.pdf"));
+ } catch (IOException | GraphvizException ex) {
+ System.err.println("Error writing function dot graph: " + ex.getMessage());
+ }
+ }
+
+ /**
+ * Pretty-prints a human-readable slice report with method grouping,
+ * source line listing, and inter-method dependency edges.
+ *
+ * Function-level slicing contribution: produces a structured report
+ * ({@code slice-pretty.log}) that helps developers understand which
+ * methods participate in the slice and how they depend on each other.
+ *
+ * @param outDir output directory for the report file
+ * @param slice the completed dynamic slice
+ * @param slicePositions the trace positions used as slicing criterion
+ * @param criterionStmts the StatementInstances used as slicing criterion
+ */
+ public static void printPrettySlice(String outDir, DynamicSlice slice,
+ List slicePositions, List criterionStmts) {
+
+ // Group slice entries by destination method
+ Map> methodGroups = new LinkedHashMap<>();
+ Map> methodDeps = new LinkedHashMap<>();
+ Map methodToFile = new LinkedHashMap<>();
+ Set seenLines = new LinkedHashSet<>();
+
+ for (Pair, Pair> entry : slice) {
+ StatementInstance dest = entry.getO1().getO1();
+ StatementInstance src = entry.getO2().getO1();
+ if (dest == null || src == null) {
+ continue;
+ }
+
+ String edgeType = slice.getEdges(dest.getLineNo(), src.getLineNo());
+ String destMethod = dest.getMethod().getSignature();
+ String srcMethod = src.getMethod().getSignature();
+
+ methodGroups.computeIfAbsent(destMethod, k -> new ArrayList<>()).add(dest);
+ methodToFile.putIfAbsent(destMethod, dest.getJavaSourceFile());
+
+ if (!destMethod.equals(srcMethod)) {
+ String depDesc = String.format("%s <-- %s (%s:%d)",
+ edgeType,
+ shortenSignature(srcMethod),
+ src.getJavaSourceFile(), src.getJavaSourceLineNo());
+ methodDeps.computeIfAbsent(destMethod, k -> new LinkedHashSet<>()).add(depDesc);
+ }
+ }
+
+ // Determine target method from criterion
+ String targetMethod = "";
+ if (criterionStmts != null && !criterionStmts.isEmpty() && criterionStmts.get(0) != null) {
+ targetMethod = criterionStmts.get(0).getMethod().getSignature();
+ }
+
+ // Count unique source lines in the slice
+ int totalLines = 0;
+ for (List stmts : methodGroups.values()) {
+ Set unique = new LinkedHashSet<>();
+ for (StatementInstance si : stmts) {
+ unique.add(si.getJavaSourceFile() + ":" + si.getJavaSourceLineNo());
+ }
+ totalLines += unique.size();
+ }
+
+ // Build the report
+ List output = new ArrayList<>();
+ output.add(repeat("=", 80));
+ output.add(" SLICE REPORT");
+ output.add(" Mode: FUNCTION-LEVEL");
+ output.add(" Target method: " + targetMethod);
+ output.add(" Criterion size: " + (criterionStmts != null ? criterionStmts.size() : 0) + " statements");
+ output.add(" Slice size: " + totalLines + " source lines across " + methodGroups.size() + " methods");
+ output.add(repeat("=", 80));
+ output.add("");
+
+ // Per-method detail
+ int idx = 1;
+ for (Map.Entry> e : methodGroups.entrySet()) {
+ String methodSig = e.getKey();
+ output.add(repeat("-", 80));
+ output.add(String.format("[%d] %s", idx++, methodSig));
+ output.add(" Source: " + methodToFile.getOrDefault(methodSig, "UNKNOWN"));
+
+ // Deduplicate and sort source lines
+ Set uniqueLines = new LinkedHashSet<>();
+ for (StatementInstance si : e.getValue()) {
+ uniqueLines.add(si.getJavaSourceFile() + ":" + si.getJavaSourceLineNo());
+ }
+ output.add(" Lines in slice (" + uniqueLines.size() + "):");
+ uniqueLines.stream()
+ .sorted()
+ .forEach(l -> output.add(" " + l));
+
+ // Dependencies on other methods
+ Set deps = methodDeps.get(methodSig);
+ if (deps != null && !deps.isEmpty()) {
+ output.add(" Inter-method dependencies:");
+ deps.stream().sorted().forEach(d -> output.add(" " + d));
+ }
+ output.add("");
+ }
+
+ // Method-level dependency summary
+ Map> methodGraph = new LinkedHashMap<>();
+ for (Pair, Pair> entry : slice) {
+ StatementInstance dest = entry.getO1().getO1();
+ StatementInstance src = entry.getO2().getO1();
+ if (dest == null || src == null) {
+ continue;
+ }
+ String dm = dest.getMethod().getSignature();
+ String sm = src.getMethod().getSignature();
+ if (!dm.equals(sm)) {
+ String edgeType = slice.getEdges(dest.getLineNo(), src.getLineNo());
+ methodGraph.computeIfAbsent(dm, k -> new LinkedHashSet<>())
+ .add(shortenSignature(sm) + " (" + edgeType + ")");
+ }
+ }
+
+ if (!methodGraph.isEmpty()) {
+ output.add(repeat("=", 80));
+ output.add(" METHOD-LEVEL DEPENDENCY GRAPH");
+ output.add(repeat("=", 80));
+ for (Map.Entry> e : methodGraph.entrySet()) {
+ String caller = shortenSignature(e.getKey());
+ for (String callee : e.getValue()) {
+ output.add(" " + caller + " --> " + callee);
+ }
+ }
+ output.add("");
+ }
+
+ output.add(repeat("=", 80));
+ output.add(" End of report");
+ output.add(repeat("=", 80));
+
+ String fileName = outDir + File.separator + "slice-pretty.log";
+ try {
+ FileUtils.writeLines(new File(fileName), output);
+ } catch (IOException ex) {
+ System.err.println("Error writing pretty slice: " + ex.getMessage());
+ }
+ }
+
+ /**
+ * Shortens a Soot method signature for display.
+ * Converts {@code } to {@code Foo.bar()}.
+ */
+ private static String shortenSignature(String sig) {
+ if (sig == null || sig.isEmpty()) {
+ return sig;
+ }
+ String inner = sig.startsWith("<") && sig.endsWith(">") ? sig.substring(1, sig.length() - 1) : sig;
+ int colon = inner.lastIndexOf(':');
+ if (colon < 0) {
+ return inner;
+ }
+ String className = inner.substring(0, colon);
+ String methodPart = inner.substring(colon + 1).trim();
+
+ // Extract short class name
+ String shortClass = className;
+ int lastDot = className.lastIndexOf('.');
+ if (lastDot >= 0) {
+ shortClass = className.substring(lastDot + 1);
+ }
+
+ // Extract method name (before the first space, which separates return type)
+ String methodName = methodPart;
+ int firstSpace = methodPart.indexOf(' ');
+ if (firstSpace >= 0) {
+ methodName = methodPart.substring(firstSpace + 1);
+ }
+
+ // Remove parameter types for brevity
+ int parenOpen = methodName.indexOf('(');
+ if (parenOpen >= 0) {
+ methodName = methodName.substring(0, parenOpen) + "()";
+ }
+
+ return shortClass + "." + methodName;
+ }
+
+ private static String repeat(String s, int count) {
+ StringBuilder sb = new StringBuilder(s.length() * count);
+ for (int i = 0; i < count; i++) {
+ sb.append(s);
+ }
+ return sb.toString();
+ }
+}
diff --git a/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/Slicer.java b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/Slicer.java
index 06a7654..e772cf7 100644
--- a/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/Slicer.java
+++ b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/Slicer.java
@@ -12,6 +12,7 @@
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.Map.Entry;
+import java.util.stream.Collectors;
import com.google.common.base.Optional;
@@ -200,16 +201,15 @@ public DynamicSlice directStatementDependency(StatementInstance start, boolean d
public void runInstrumentedJarFromMain(String pathToJar, String mainClass, String mainArguments) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "java -Xmx8g -cp " + pathToJar + " " + mainClass + " " + mainArguments+ " | grep \"SLICING\"");
Process p = pb.start();
- p.waitFor();
- BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
- BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir + File.separator + "trace.log"));
- String readline;
- while ((readline = reader.readLine()) != null) {
- writer.write(readline);
- writer.write("\n");
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir + File.separator + "trace.log"))) {
+ String readline;
+ while ((readline = reader.readLine()) != null) {
+ writer.write(readline);
+ writer.write("\n");
+ }
}
- writer.close();
- reader.close();
+ p.waitFor();
}
public static void main(String [] args) {
@@ -332,7 +332,35 @@ public static void main(String [] args) {
for (Integer backSlicePos: slicer.backwardSlicePositions) {
stmts.add(icdg.mapNoUnits(backSlicePos));
}
-
+
+ // Function-level slicing (--function-slice): expand the slicing criterion
+ // from a single source line to all trace statements within the containing
+ // method, producing a method-grained backward slice.
+ boolean functionSlice = commands.containsKey("fs");
+ if (functionSlice) {
+ Set targetMethods = new HashSet<>();
+ for (StatementInstance stmt : stmts) {
+ if (stmt != null) {
+ targetMethods.add(stmt.getMethod().getSignature());
+ }
+ }
+ List expandedPositions = new ArrayList<>();
+ for (StatementInstance si : icdg.getTraceList()) {
+ if (si != null && targetMethods.contains(si.getMethod().getSignature())) {
+ expandedPositions.add(si.getLineNo());
+ }
+ }
+ AnalysisLogger.log(true, "Function-level slice: expanded from {} to {} trace positions across method(s) {}",
+ slicer.backwardSlicePositions.size(), expandedPositions.size(), targetMethods);
+ slicer.setBackwardSlicePositions(
+ expandedPositions.stream().map(String::valueOf).collect(Collectors.joining("-")));
+ slicer.setVariableString("*");
+ stmts.clear();
+ for (Integer backSlicePos : slicer.backwardSlicePositions) {
+ stmts.add(icdg.mapNoUnits(backSlicePos));
+ }
+ }
+
List variables = new ArrayList<>();
if (!slicer.variableString.equals("*")) {
String[] split = slicer.variableString.split("-");
@@ -375,6 +403,13 @@ public String toString() {
String resultFileName = slicer.outDir + File.separator + "result_" +mode+"_"+ dtf.format(now) + ".csv";
SlicePrinter.printToCSV(resultFileName, dynamicSlice);
+ // Function-level slicing output: method-grouped slice and human-readable report
+ if (functionSlice) {
+ SlicePrettyPrinter.printFunctionSlice(slicer.outDir, dynamicSlice);
+ SlicePrettyPrinter.printPrettySlice(slicer.outDir, dynamicSlice, slicer.backwardSlicePositions, stmts);
+ SlicePrettyPrinter.printFunctionDotGraph(slicer.outDir, dynamicSlice);
+ }
+
AnalysisLogger.log(true, "Slice size: {}", dynamicSlice.size());
terminate(slicer.outDir, mode, startTime);
}
diff --git a/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/instrumenter/JavaInstrumenter.java b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/instrumenter/JavaInstrumenter.java
index d29ad7d..e30771b 100644
--- a/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/instrumenter/JavaInstrumenter.java
+++ b/Slicer4J/src/main/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/instrumenter/JavaInstrumenter.java
@@ -1,10 +1,12 @@
package ca.ubc.ece.resess.slicer.dynamic.slicer4j.instrumenter;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -253,7 +255,10 @@ public void start (String options, String staticLogFile, String jarPath, String
try {
classesFile.delete();
StringBuilder instrClasses = new StringBuilder();
- List orderedClasses = new ArrayList<>(instrumentedClasses);
+ List orderedClasses = new ArrayList<>();
+ for (String className : instrumentedClasses) {
+ orderedClasses.add(className);
+ }
orderedClasses.sort((a, b) -> a.compareTo(b));
for (String className : orderedClasses) {
instrClasses.append(className);
@@ -322,7 +327,18 @@ public void start (String options, String staticLogFile, String jarPath, String
jarOptions = "uf";
}
- Process p = Runtime.getRuntime().exec("jar " + jarOptions + " " + jarName + " " + clazzFile, null, new File(Slicer.SOOT_OUTPUT_STRING));
+ List cmd = new ArrayList<>();
+ cmd.add("jar");
+ cmd.add(jarOptions);
+ cmd.add(jarName);
+ cmd.addAll(instrumentedClasses.subList(i, minIndex));
+ ProcessBuilder pb = new ProcessBuilder(cmd);
+ pb.directory(new File(Slicer.SOOT_OUTPUT_STRING));
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
+ while (reader.readLine() != null) {}
+ }
p.waitFor();
// String output = IOUtils.toString(p.getInputStream());
// String errorOutput = IOUtils.toString(p.getErrorStream());
diff --git a/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/BenchTests.java b/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/BenchTests.java
index 0703b93..0d4394e 100644
--- a/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/BenchTests.java
+++ b/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/BenchTests.java
@@ -2,7 +2,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
-
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
@@ -19,214 +18,393 @@
import ca.ubc.ece.resess.slicer.dynamic.core.graph.DynamicControlFlowGraph;
-
public class BenchTests {
- Path root = Paths.get(".").normalize().toAbsolutePath();
- Path slicerPath = Paths.get(root.getParent().toString(), "scripts");
- Path outDir = Paths.get(slicerPath.toString(), "testTempDir");
- Path sliceLogger = Paths.get(root.getParent().getParent().toString(), "DynamicSlicingCore" + File.separator + "DynamicSlicingLoggingClasses" + File.separator + "DynamicSlicingLogger.jar");
-
- @BeforeAll
- static void preCleanUp() throws IOException {
- TestUtils.cleanWorkingDirectory();
- }
-
- @AfterEach
- void postCleanUp() throws IOException {
- TestUtils.cleanWorkingDirectory();
- }
-
-
- @Test
- void javaslicer_bench1() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "javaslicer-bench1-intra-procedural");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "javaslicer-bench1-intra-procedural-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
-
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "2");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 8;
- Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
-
- Set expected = new HashSet<>(Arrays.asList("Bench:5", "Bench:4", "Bench:7", "Bench:6", "Bench:8"));
-
- assertEquals(expected, sliceLines);
- }
-
- @Test
- void javaslicer_bench2() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "javaslicer-bench2-inter-procedural");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "javaslicer-bench2-inter-procedural-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
-
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "2");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 12;
- Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
-
- Set expected = new HashSet<>(Arrays.asList("Bench:12", "Bench:4", "Bench:7", "Bench:6", "Bench:8"));
-
- assertEquals(expected, sliceLines);
- }
-
- @Test
- void javaslicer_bench3() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "javaslicer-bench3-exceptions");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "javaslicer-bench3-exceptions-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
- slicer.setDebug(true);
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 20;
- Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
-
- Set expected = new HashSet<>(Arrays.asList("Bench:33", "Bench:19", "Bench:29", "Bench:4", "Bench:17", "Bench:28"));
-
- assertEquals(expected, sliceLines);
- }
-
- @Test
- void slicer4j_bench1() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "slicer4j-bench1-multiple-threads");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "slicer4j-bench1-multiple-threads-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
- slicer.setDebug(true);
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 38;
- Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
-
- Set expected = new HashSet<>(Arrays.asList("Bench:12", "Producer:28", "Bench:14", "Consumer:43", "Consumer:40"));
-
- assertEquals(expected, sliceLines);
- }
-
- @Test
- void slicer4j_bench2() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "slicer4j-bench2-native-framework");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "slicer4j-bench2-native-framework-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
- slicer.setDebug(true);
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "0 4");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 21;
- Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
-
- Set expected = new HashSet<>(Arrays.asList("Bench:5", "Bench:4", "Bench:7", "Bench:6", "Bench:9", "Bench:8"));
-
- assertEquals(expected, sliceLines);
- }
-
- @Test
- void slicer4j_bench3() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "slicer4j-bench3-java-9-constructs");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "slicer4j-bench3-java-9-constructs-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
- slicer.setDebug(true);
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "3 4");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 23;
- List sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom).stream()
- .sorted((a, b) -> a.compareTo(b))
- .collect(Collectors.toList());
-
- List expected = Arrays.asList("Bench:13", "Bench:5", "Bench:7", "Bench:6", "Bench:9", "Bench:8").stream()
- .sorted((a, b) -> a.compareTo(b))
- .collect(Collectors.toList());
-
- assertEquals(expected, sliceLines);
- }
-
- @Test
- void slicer4j_bench4() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "slicer4j-bench4-instrumentation-classes");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "slicer4j-bench4-instrumentation-classes-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
- slicer.setDebug(true);
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "22");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 11;
- Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
-
- Set expected = new HashSet<>(Arrays.asList("Bench:10", "Bench:7", "Bench:6", "Bench:9", "Bench:8"));
-
- assertEquals(expected, sliceLines);
- }
-
- @Test
- void slicer4j_bench5() throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "slicer4j-bench5-static-constructor");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "slicer4j-bench5-static-constructor-1.0.0.jar").toString();
-
- TestUtils.buildJar(testPath);
-
- Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
- slicer.setDebug(true);
- String instrumentedJar = slicer.instrument();
- slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "22");
-
- DynamicControlFlowGraph dcfg = slicer.prepareGraph();
- slicer.printGraph(dcfg);
-
- Integer tracePositionToSliceFrom = 14;
- List sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom).stream()
- .sorted((a, b) -> a.compareTo(b))
- .collect(Collectors.toList());
-
- List expected = Arrays.asList("Bench:12", "Bench:2", "Bench:4", "Bench:7", "Bench:6", "Bench:8").stream()
- .sorted((a, b) -> a.compareTo(b))
- .collect(Collectors.toList());
-
- assertEquals(expected, sliceLines);
- }
+ Path root = Paths.get(".").normalize().toAbsolutePath();
+ Path slicerPath = Paths.get(root.getParent().toString(), "scripts");
+ Path outDir = Paths.get(slicerPath.toString(), "testTempDir");
+ Path sliceLogger = Paths.get(root.getParent().getParent().toString(), "DynamicSlicingCore" + File.separator
+ + "DynamicSlicingLoggingClasses" + File.separator + "DynamicSlicingLogger.jar");
+
+ @BeforeAll
+ static void preCleanUp() throws IOException {
+ TestUtils.cleanWorkingDirectory();
+ }
+
+ @AfterEach
+ void postCleanUp() throws IOException {
+ TestUtils.cleanWorkingDirectory();
+ }
+
+ @Test
+ void javaslicer_bench1() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "javaslicer-bench1-intra-procedural");
+ String jarPath = Paths
+ .get(testPath.toString(),
+ "target" + File.separator
+ + "javaslicer-bench1-intra-procedural-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "2");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 8;
+ Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
+
+ Set expected = new HashSet<>(
+ Arrays.asList("Bench:5", "Bench:4", "Bench:7", "Bench:6", "Bench:8"));
+
+ assertEquals(expected, sliceLines);
+ }
+
+ @Test
+ void javaslicer_bench2() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "javaslicer-bench2-inter-procedural");
+ String jarPath = Paths
+ .get(testPath.toString(),
+ "target" + File.separator
+ + "javaslicer-bench2-inter-procedural-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "2");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 12;
+ Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
+
+ Set expected = new HashSet<>(
+ Arrays.asList("Bench:12", "Bench:4", "Bench:7", "Bench:6", "Bench:8"));
+
+ assertEquals(expected, sliceLines);
+ }
+
+ @Test
+ void javaslicer_bench3() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "javaslicer-bench3-exceptions");
+ String jarPath = Paths
+ .get(testPath.toString(),
+ "target" + File.separator + "javaslicer-bench3-exceptions-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ slicer.setDebug(true);
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 20;
+ Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
+
+ Set expected = new HashSet<>(
+ Arrays.asList("Bench:33", "Bench:19", "Bench:29", "Bench:4", "Bench:17", "Bench:28"));
+
+ assertEquals(expected, sliceLines);
+ }
+
+ @Test
+ void slicer4j_bench1() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "slicer4j-bench1-multiple-threads");
+ String jarPath = Paths
+ .get(testPath.toString(),
+ "target" + File.separator
+ + "slicer4j-bench1-multiple-threads-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ slicer.setDebug(true);
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 38;
+ Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
+
+ Set expected = new HashSet<>(
+ Arrays.asList("Bench:12", "Producer:28", "Bench:14", "Consumer:43", "Consumer:40"));
+
+ assertEquals(expected, sliceLines);
+ }
+
+ @Test
+ void slicer4j_bench2() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "slicer4j-bench2-native-framework");
+ String jarPath = Paths
+ .get(testPath.toString(),
+ "target" + File.separator
+ + "slicer4j-bench2-native-framework-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ slicer.setDebug(true);
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "0 4");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 21;
+ Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
+
+ Set expected = new HashSet<>(
+ Arrays.asList("Bench:5", "Bench:4", "Bench:7", "Bench:6", "Bench:9", "Bench:8"));
+
+ assertEquals(expected, sliceLines);
+ }
+
+ @Test
+ void slicer4j_bench3() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "slicer4j-bench3-java-9-constructs");
+ String jarPath = Paths
+ .get(testPath.toString(),
+ "target" + File.separator
+ + "slicer4j-bench3-java-9-constructs-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ slicer.setDebug(true);
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "3 4");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 23;
+ List sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom)
+ .stream()
+ .sorted((a, b) -> a.compareTo(b))
+ .collect(Collectors.toList());
+
+ List expected = Arrays.asList("Bench:13", "Bench:5", "Bench:7", "Bench:6", "Bench:9", "Bench:8")
+ .stream()
+ .sorted((a, b) -> a.compareTo(b))
+ .collect(Collectors.toList());
+
+ assertEquals(expected, sliceLines);
+ }
+
+ @Test
+ void slicer4j_bench4() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "slicer4j-bench4-instrumentation-classes");
+ String jarPath = Paths.get(testPath.toString(),
+ "target" + File.separator + "slicer4j-bench4-instrumentation-classes-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ slicer.setDebug(true);
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "22");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 11;
+ Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
+
+ Set expected = new HashSet<>(
+ Arrays.asList("Bench:10", "Bench:7", "Bench:6", "Bench:9", "Bench:8"));
+
+ assertEquals(expected, sliceLines);
+ }
+
+ @Test
+ void slicer4j_bench5() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "slicer4j-bench5-static-constructor");
+ String jarPath = Paths
+ .get(testPath.toString(),
+ "target" + File.separator
+ + "slicer4j-bench5-static-constructor-1.0.0.jar")
+ .toString();
+
+ TestUtils.buildJar(testPath);
+
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ slicer.setDebug(true);
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "22");
+
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+
+ Integer tracePositionToSliceFrom = 14;
+ List sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom)
+ .stream()
+ .sorted((a, b) -> a.compareTo(b))
+ .collect(Collectors.toList());
+
+ List expected = Arrays.asList("Bench:12", "Bench:2", "Bench:4", "Bench:7", "Bench:6", "Bench:8")
+ .stream()
+ .sorted((a, b) -> a.compareTo(b))
+ .collect(Collectors.toList());
+
+ assertEquals(expected, sliceLines);
+ }
+
+ // This issue is not fixable. Please see #Issue 42 for an explanation of why
+ // this test is commented out
+ // @Test
+ // void issue_42_slicer4j_bench_const_prop_simple() throws IOException,
+ // InterruptedException {
+ // Path testPath = Paths.get(root.getParent().toString(),
+ // "benchmarks" + File.separator + "issue-42-slicer4j-bench-const-prop-simple");
+ // String jarPath = Paths.get(testPath.toString(),
+ // "target" + File.separator +
+ // "issue-42-slicer4j-bench-const-prop-simple-1.0.0.jar")
+ // .toString();
+
+ // TestUtils.buildJar(testPath);
+
+ // Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ // slicer.setDebug(true);
+ // String instrumentedJar = slicer.instrument();
+ // slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "");
+
+ // DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ // slicer.printGraph(dcfg);
+
+ // // Slicing criterion: ConstPropSimple:7 (d)
+ // // From the user, lines 3, 4, 5, 6, 7 are the IDEAL expected slice
+ // // Trace position corresponds to line 7. We'll search for it dynamically
+ // later,
+ // // but for now we put a placeholder 7 or the first instance of line 7.
+ // List tracePositions = TestUtils.getTracePositionFromSourceLine(7,
+ // "Bench", dcfg);
+ // Integer tracePositionToSliceFrom = tracePositions.isEmpty() ? 7 :
+ // tracePositions.get(0);
+
+ // Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg,
+ // tracePositionToSliceFrom);
+
+ // Set expected = new HashSet<>(
+ // Arrays.asList("Bench:3", "Bench:4", "Bench:5", "Bench:6", "Bench:7"));
+
+ // System.out.println("=== issue_42_slicer4j_bench_const_prop_simple ===");
+ // System.out.println("Expected slice: " + expected);
+ // System.out.println("Actual slice: " + sliceLines);
+ // System.out.println("===================================================");
+
+ // assertEquals(expected, sliceLines);
+ // }
+
+ // @Test
+ // void issue_42_slicer4j_bench_const_prop_cross_call() throws IOException,
+ // InterruptedException {
+ // Path testPath = Paths.get(root.getParent().toString(),
+ // "benchmarks" + File.separator +
+ // "issue-42-slicer4j-bench-const-prop-cross-call");
+ // String jarPath = Paths
+ // .get(testPath.toString(),
+ // "target" + File.separator
+ // + "issue-42-slicer4j-bench-const-prop-cross-call-1.0.0.jar")
+ // .toString();
+
+ // TestUtils.buildJar(testPath);
+
+ // Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ // slicer.setDebug(true);
+ // String instrumentedJar = slicer.instrument();
+ // slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "");
+
+ // DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ // slicer.printGraph(dcfg);
+
+ // // Slicing criterion: ConstPropCrossCall:14 (z)
+ // // Idea expected slice: Lines 4, 5, 6, 7, 8, 11, 12, 13, 14.
+ // List tracePositions = TestUtils.getTracePositionFromSourceLine(14,
+ // "Bench", dcfg);
+ // Integer tracePositionToSliceFrom = tracePositions.isEmpty() ? 14 :
+ // tracePositions.get(0);
+
+ // Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg,
+ // tracePositionToSliceFrom);
+
+ // Set expected = new HashSet<>(
+ // Arrays.asList("Bench:4", "Bench:5", "Bench:6", "Bench:7", "Bench:8",
+ // "Bench:11", "Bench:12", "Bench:13", "Bench:14"));
+
+ // System.out.println("=== issue_42_slicer4j_bench_const_prop_cross_call ===");
+ // System.out.println("Expected slice: " + expected);
+ // System.out.println("Actual slice: " + sliceLines);
+ // System.out.println("=====================================================");
+
+ // assertEquals(expected, sliceLines);
+ // }
+
+ // @Test
+ // void issue_42_slicer4j_bench_const_prop_selective() throws IOException,
+ // InterruptedException {
+ // Path testPath = Paths.get(root.getParent().toString(),
+ // "benchmarks" + File.separator +
+ // "issue-42-slicer4j-bench-const-prop-selective");
+ // String jarPath = Paths
+ // .get(testPath.toString(),
+ // "target" + File.separator
+ // + "issue-42-slicer4j-bench-const-prop-selective-1.0.0.jar")
+ // .toString();
+
+ // TestUtils.buildJar(testPath);
+
+ // Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir,
+ // sliceLogger);slicer.setDebug(true);
+ // String instrumentedJar = slicer
+ // .instrument();slicer.runInstrumentedJarFromMain(instrumentedJar,"Bench","any-arg");
+
+ // DynamicControlFlowGraph dcfg = slicer.prepareGraph();slicer.printGraph(dcfg);
+
+ // // Slicing criterion: ConstPropSelective:11 (msg)
+ // // Idea expected slice: Lines 3, 4, 5, 6, 7, 8, 9, 10, 11.
+ // List tracePositions = TestUtils.getTracePositionFromSourceLine(11,
+ // "Bench", dcfg);
+ // Integer tracePositionToSliceFrom = tracePositions.isEmpty() ? 11 :
+ // tracePositions.get(0);
+
+ // Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg,
+ // tracePositionToSliceFrom);
+
+ // Set expected = new HashSet<>(
+ // Arrays.asList("Bench:3", "Bench:4", "Bench:5", "Bench:6", "Bench:7",
+ // "Bench:8", "Bench:9", "Bench:10", "Bench:11"));
+
+ // System.out.println("=== issue_42_slicer4j_bench_const_prop_selective
+ // ===");System.out.println("Expected slice:
+ // "+expected);System.out.println("Actual slice:
+ // "+sliceLines);System.out.println("====================================================");
+
+ // assertEquals(expected, sliceLines);
+ // }
}
diff --git a/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/ProgramTests.java b/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/ProgramTests.java
index 3fa1784..a2f1168 100644
--- a/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/ProgramTests.java
+++ b/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/ProgramTests.java
@@ -1,6 +1,5 @@
package ca.ubc.ece.resess.slicer.dynamic.slicer4j;
-
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -29,206 +28,203 @@
import ca.ubc.ece.resess.slicer.dynamic.core.graph.DynamicControlFlowGraph;
import ca.ubc.ece.resess.slicer.dynamic.core.statements.StatementInstance;
-
public class ProgramTests {
Path root = Paths.get(".").normalize().toAbsolutePath();
Path slicerPath = Paths.get(root.getParent().toString(), "scripts");
Path outDir = Paths.get(slicerPath.toString(), "testTempDir");
- Path sliceLogger = Paths.get(root.getParent().getParent().toString(), "DynamicSlicingCore" + File.separator + "DynamicSlicingLoggingClasses" + File.separator + "DynamicSlicingLogger.jar");
+ Path sliceLogger = Paths.get(root.getParent().getParent().toString(), "DynamicSlicingCore" + File.separator
+ + "DynamicSlicingLoggingClasses" + File.separator + "DynamicSlicingLogger.jar");
boolean useSets = true;
- @BeforeAll
+ @BeforeAll
static void preCleanUp() throws IOException {
TestUtils.cleanWorkingDirectory();
}
-
- @AfterEach
+
+ @AfterEach
void postCleanUp() throws IOException {
TestUtils.cleanWorkingDirectory();
}
-
@Test
void issue1() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue1");
String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test1-issue-1.0.0.jar").toString();
TestUtils.buildJar(testPath);
-
- String [] args = {
- "-m",
- "i",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-lc",
- sliceLogger.toString()
+
+ String[] args = {
+ "-m",
+ "i",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-lc",
+ sliceLogger.toString()
};
Slicer.main(args);
-
- ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "java -Xmx8g -cp " + outDir.toString() + File.separator + "test1-issue-1.0.0_i.jar Main | grep \"SLICING\"");
+
+ ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "java -Xmx8g -cp " + outDir.toString() + File.separator
+ + "test1-issue-1.0.0_i.jar Main | grep \"SLICING\"");
System.out.println(pb.command());
Process p = pb.start();
- p.waitFor();
- BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir.toString() + File.separator + "trace.log"));
- String readline;
- while ((readline = reader.readLine()) != null) {
- writer.write(readline);
- writer.write("\n");
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir.toString() + File.separator + "trace.log"))) {
+ String readline;
+ while ((readline = reader.readLine()) != null) {
+ writer.write(readline);
+ writer.write("\n");
+ }
}
- writer.close();
- reader.close();
-
- args = new String [] {
- "-m",
- "g",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-t",
- outDir.toString() + File.separator + "trace.log",
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-sd",
- root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
- "-tw",
- root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt"
+ p.waitFor();
+
+ args = new String[] {
+ "-m",
+ "g",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-t",
+ outDir.toString() + File.separator + "trace.log",
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-sd",
+ root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
+ "-tw",
+ root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt"
};
Slicer.main(args);
-
- args = new String [] {
- "-m",
- "s",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-t",
- outDir.toString() + File.separator + "trace.log",
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-sd",
- root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
- "-tw",
- root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt",
- "-sp",
- "15",
+
+ args = new String[] {
+ "-m",
+ "s",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-t",
+ outDir.toString() + File.separator + "trace.log",
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-sd",
+ root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
+ "-tw",
+ root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt",
+ "-sp",
+ "15",
"-d"
};
Slicer.main(args);
-
+
Path outputPath = Paths.get(slicerPath.toString(), "testTempDir" + File.separator + "slice.log");
List out = Files.readAllLines(outputPath);
System.out.println(out);
- if(useSets){
+ if (useSets) {
assertEquals(new HashSet<>(Arrays.asList(
- "Main:6",
- "Main:7",
- "Main:17",
- "Main:18",
- "Main:8",
- "Main:13",
- "Main:9")),
+ "Main:6",
+ "Main:7",
+ "Main:17",
+ "Main:18",
+ "Main:8",
+ "Main:13",
+ "Main:9")),
new HashSet<>(out));
} else {
assertEquals(Arrays.asList(
- "Main:6",
- "Main:7",
- "Main:17",
- "Main:18",
- "Main:8",
- "Main:13",
- "Main:9"),
- out);
+ "Main:6",
+ "Main:7",
+ "Main:17",
+ "Main:18",
+ "Main:8",
+ "Main:13",
+ "Main:9"),
+ out);
}
}
-
+
@Test
void issue2() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue2");
String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test2-issue-1.0.0.jar").toString();
TestUtils.buildJar(testPath);
-
- String [] args = {
- "-m",
- "i",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-lc",
- sliceLogger.toString()
+
+ String[] args = {
+ "-m",
+ "i",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-lc",
+ sliceLogger.toString()
};
Slicer.main(args);
-
- ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "java -Xmx8g -cp " + outDir.toString() + File.separator + "test2-issue-1.0.0_i.jar Main something | grep \"SLICING\"");
+
+ ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "java -Xmx8g -cp " + outDir.toString() + File.separator
+ + "test2-issue-1.0.0_i.jar Main something | grep \"SLICING\"");
System.out.println(pb.command());
Process p = pb.start();
- p.waitFor();
- BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir.toString() + File.separator + "trace.log"));
- String readline;
- while ((readline = reader.readLine()) != null) {
- writer.write(readline);
- writer.write("\n");
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir.toString() + File.separator + "trace.log"))) {
+ String readline;
+ while ((readline = reader.readLine()) != null) {
+ writer.write(readline);
+ writer.write("\n");
+ }
}
- writer.close();
- reader.close();
-
- args = new String [] {
- "-m",
- "g",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-t",
- outDir.toString() + File.separator + "trace.log",
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-sd",
- root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
- "-tw",
- root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt"
+ p.waitFor();
+
+ args = new String[] {
+ "-m",
+ "g",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-t",
+ outDir.toString() + File.separator + "trace.log",
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-sd",
+ root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
+ "-tw",
+ root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt"
};
Slicer.main(args);
-
- args = new String [] {
- "-m",
- "s",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-t",
- outDir.toString() + File.separator + "trace.log",
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-sd",
- root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
- "-tw",
- root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt",
- "-sp",
- "16",
+
+ args = new String[] {
+ "-m",
+ "s",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-t",
+ outDir.toString() + File.separator + "trace.log",
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-sd",
+ root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
+ "-tw",
+ root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt",
+ "-sp",
+ "16",
"-d"
};
Slicer.main(args);
-
+
Path outputPath = Paths.get(slicerPath.toString(), "testTempDir" + File.separator + "slice.log");
List out = Files.readAllLines(outputPath);
System.out.println(out);
-
- if(useSets){
+
+ if (useSets) {
assertEquals(new HashSet<>(Arrays.asList(
"Main:6",
"Main:15",
@@ -240,171 +236,169 @@ void issue2() throws IOException, InterruptedException {
new HashSet<>(out));
} else {
assertEquals(Arrays.asList(
- "Main:6",
- "Main:15",
- "Main:16",
- "Main:19",
- "Main:8",
- "Main:9",
- "Main:11"),
+ "Main:6",
+ "Main:15",
+ "Main:16",
+ "Main:19",
+ "Main:8",
+ "Main:9",
+ "Main:11"),
out);
}
}
-
-
+
@Test
void sliceOnce() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue1");
String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test1-issue-1.0.0.jar").toString();
TestUtils.buildJar(testPath);
-
- String [] args = {
- "-m",
- "i",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-lc",
- sliceLogger.toString()
+
+ String[] args = {
+ "-m",
+ "i",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-lc",
+ sliceLogger.toString()
};
Slicer.main(args);
-
- ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "java -Xmx8g -cp " + outDir.toString() + File.separator + "test1-issue-1.0.0_i.jar Main | grep \"SLICING\"");
+
+ ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", "java -Xmx8g -cp " + outDir.toString() + File.separator
+ + "test1-issue-1.0.0_i.jar Main | grep \"SLICING\"");
System.out.println(pb.command());
Process p = pb.start();
- p.waitFor();
- BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
-
- BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir.toString() + File.separator + "trace.log"));
- String readline;
- while ((readline = reader.readLine()) != null) {
- writer.write(readline);
- writer.write("\n");
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir.toString() + File.separator + "trace.log"))) {
+ String readline;
+ while ((readline = reader.readLine()) != null) {
+ writer.write(readline);
+ writer.write("\n");
+ }
}
- writer.close();
- reader.close();
-
- args = new String [] {
- "-m",
- "g",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-t",
- outDir.toString() + File.separator + "trace.log",
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-sd",
- root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
- "-tw",
- root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt"
+ p.waitFor();
+
+ args = new String[] {
+ "-m",
+ "g",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-t",
+ outDir.toString() + File.separator + "trace.log",
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-sd",
+ root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
+ "-tw",
+ root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt"
};
Slicer.main(args);
-
- args = new String [] {
- "-m",
- "s",
- "-j",
- jarPath,
- "-o",
- outDir.toString(),
- "-t",
- outDir.toString() + File.separator + "trace.log",
- "-sl",
- outDir.toString() + File.separator + "static_log.log",
- "-sd",
- root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
- "-tw",
- root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt",
- "-sp",
- "15",
- "-once"
+
+ args = new String[] {
+ "-m",
+ "s",
+ "-j",
+ jarPath,
+ "-o",
+ outDir.toString(),
+ "-t",
+ outDir.toString() + File.separator + "trace.log",
+ "-sl",
+ outDir.toString() + File.separator + "static_log.log",
+ "-sd",
+ root.getParent().toString() + File.separator + "models" + File.separator + "summariesManual",
+ "-tw",
+ root.getParent().toString() + File.separator + "models" + File.separator + "EasyTaintWrapperSource.txt",
+ "-sp",
+ "15",
+ "-once"
};
Slicer.main(args);
-
+
Path outputPath = Paths.get(slicerPath.toString(), "testTempDir" + File.separator + "slice.log");
List out = Files.readAllLines(outputPath);
System.out.println(out);
-
- if(useSets){
+
+ if (useSets) {
assertEquals(new HashSet<>(Arrays.asList(
"Main:13",
"Main:9")),
new HashSet<>(out));
} else {
assertEquals(Arrays.asList(
- "Main:13",
- "Main:9"),
+ "Main:13",
+ "Main:9"),
out);
}
}
-
@Test
void issue5() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue5");
String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-issue5-1.0.0.jar").toString();
-
+
TestUtils.buildJar(testPath);
-
+
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
slicer.setDebug(true);
String instrumentedJar = slicer.instrument();
slicer.runInstrumentedJarFromMain(instrumentedJar, "TreeAdd", "-l 2");
-
+
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
-
+
Integer tracePositionToSliceFrom = 107;
Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
Set expected = new HashSet<>(Arrays.asList(
- "TreeAdd:68",
- "TreeNode:50",
- "TreeNode:102",
- "TreeAdd:67",
- "TreeNode:60",
- "TreeNode:101",
- "TreeNode:104",
- "TreeAdd:36",
- "TreeNode:103",
- "TreeNode:106",
- "TreeNode:105",
- "TreeAdd:70",
- "TreeAdd:62",
- "TreeNode:49",
- "TreeAdd:40",
- "TreeAdd:72",
- "TreeNode:59",
- "TreeAdd:53",
- "TreeAdd:33",
- "TreeAdd:65"));
+ "TreeAdd:68",
+ "TreeNode:50",
+ "TreeNode:102",
+ "TreeAdd:67",
+ "TreeNode:60",
+ "TreeNode:101",
+ "TreeNode:104",
+ "TreeAdd:36",
+ "TreeNode:103",
+ "TreeNode:106",
+ "TreeNode:105",
+ "TreeAdd:70",
+ "TreeAdd:62",
+ "TreeNode:49",
+ "TreeAdd:40",
+ "TreeAdd:72",
+ "TreeNode:59",
+ "TreeAdd:53",
+ "TreeAdd:33",
+ "TreeAdd:65"));
Assertions.assertTrue(sliceLines.containsAll(expected));
}
-
+
@Test
void directStatementDependency() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue1");
String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test1-issue-1.0.0.jar").toString();
-
+
TestUtils.buildJar(testPath);
-
+
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
-
+
String instrumentedJar = slicer.instrument();
slicer.runInstrumentedJarFromMain(instrumentedJar, "Main", "");
-
+
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
-
+
Integer tracePositionToSliceFrom = 15;
- Map slideDeps = TestUtils.sliceAndGetDirectDepdendeincesMap(slicer, dcfg, tracePositionToSliceFrom);
-
+ Map slideDeps = TestUtils.sliceAndGetDirectDepdendeincesMap(slicer, dcfg,
+ tracePositionToSliceFrom);
+
Map expected = new HashMap<>();
expected.put(dcfg.mapNoUnits(15), "start");
expected.put(dcfg.mapNoUnits(14), "data, varaible:stack5, source:15");
@@ -414,119 +408,117 @@ void directStatementDependency() throws IOException, InterruptedException {
assertEquals(expected, slideDeps);
}
-
@Test
void testFieldsFramework() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-fields-framework");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-fields-framework-1.0.0.jar").toString();
-
+ String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-fields-framework-1.0.0.jar")
+ .toString();
+
TestUtils.buildJar(testPath);
-
+
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
slicer.setDebug(true);
String instrumentedJar = slicer.instrument();
slicer.runInstrumentedJarFromMain(instrumentedJar, "Main", "");
-
+
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
-
+
Integer tracePositionToSliceFrom = 21;
Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
Set expected = new HashSet<>(Arrays.asList(
- "Main:18",
- "Main:17",
- "Main:9",
- "Main:8",
- "Main:13",
- "Main:7",
- "Main:5"
- ));
+ "Main:18",
+ "Main:17",
+ "Main:9",
+ "Main:8",
+ "Main:13",
+ "Main:7",
+ "Main:5"));
assertEquals(expected, sliceLines);
}
-
@Test
void issue10() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue10");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-issue10-1.0.0.jar").toString();
-
+ String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-issue10-1.0.0.jar")
+ .toString();
+
TestUtils.buildJar(testPath);
-
+
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
slicer.setDebug(true);
String instrumentedJar = slicer.instrument();
slicer.runInstrumentedJarFromMain(instrumentedJar, "Issue", "");
-
+
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
-
+
Integer tracePositionToSliceFrom = 10;
Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
Set expected = new HashSet<>(Arrays.asList(
- "Issue:10",
- "Issue:9",
- "Issue:6"));
+ "Issue:10",
+ "Issue:9",
+ "Issue:6"));
assertEquals(expected, sliceLines);
}
-
@Test
void issue11() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue11");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-issue11-1.0.0.jar").toString();
-
+ String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-issue11-1.0.0.jar")
+ .toString();
+
TestUtils.buildJar(testPath);
-
+
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
slicer.setDebug(true);
String instrumentedJar = slicer.instrument();
slicer.runInstrumentedJarFromMain(instrumentedJar, "Issue", "");
-
+
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
-
+
Integer tracePositionToSliceFrom = 30;
Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
Set expected = new HashSet<>(Arrays.asList(
- "Issue:10",
- "Issue:9",
- "Pair:49",
- "Pair:44",
- "Pair:43",
- "Pair:42",
- "PairSet:33",
- "PairSet:31",
- "PairSet:30",
- "PairSet:29",
- "PairSet:24",
- "PairSet:23",
- "PairSet:19",
- "PairSet:18"));
+ "Issue:10",
+ "Issue:9",
+ "Pair:49",
+ "Pair:44",
+ "Pair:43",
+ "Pair:42",
+ "PairSet:33",
+ "PairSet:31",
+ "PairSet:30",
+ "PairSet:29",
+ "PairSet:24",
+ "PairSet:23",
+ "PairSet:19",
+ "PairSet:18"));
assertEquals(expected, sliceLines);
}
-
@Test
void sliceMe_test() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "SliceMe");
String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "SliceMe-1.0.0.jar").toString();
-
+
TestUtils.buildJar(testPath);
-
+
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
-
+
String instrumentedJar = slicer.instrument();
slicer.runInstrumentedJarFromMain(instrumentedJar, "SliceMe", "");
-
+
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
-
+
Integer tracePositionToSliceFrom = 5;
Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom);
@@ -535,32 +527,34 @@ void sliceMe_test() throws IOException, InterruptedException {
assertEquals(expected, sliceLines);
}
-
-
-
@Test
void conditions() throws IOException, InterruptedException {
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-conditions");
- String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-conditions-1.0.0.jar").toString();
-
+ String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-conditions-1.0.0.jar")
+ .toString();
+
TestUtils.buildJar(testPath);
-
+
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
-
+
String instrumentedJar = slicer.instrument();
slicer.runInstrumentedJarFromMain(instrumentedJar, "Bench", "");
-
+
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
-
+
Integer tracePositionToSliceFrom = 83;
- List sliceLines = new ArrayList<>(TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom)).stream()
- .sorted((a, b) -> a.compareTo(b))
- .collect(Collectors.toList());
+ List sliceLines = new ArrayList<>(
+ TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositionToSliceFrom)).stream()
+ .sorted((a, b) -> a.compareTo(b))
+ .collect(Collectors.toList());
- List expected = Arrays.asList("Bench:29", "Bench:26", "Bench:25", "Bench:22", "Bench:21", "Bench:17", "Bench:16", "Bench:18", "Bench:15", "Bench:10", "Bench:7", "Bench:4").stream()
- .sorted((a, b) -> a.compareTo(b))
- .collect(Collectors.toList());
+ List expected = Arrays
+ .asList("Bench:29", "Bench:26", "Bench:25", "Bench:22", "Bench:21", "Bench:17", "Bench:16", "Bench:18",
+ "Bench:15", "Bench:10", "Bench:7", "Bench:4")
+ .stream()
+ .sorted((a, b) -> a.compareTo(b))
+ .collect(Collectors.toList());
assertEquals(expected, sliceLines);
}
@@ -569,21 +563,26 @@ void conditions() throws IOException, InterruptedException {
void inpressDCFGAssertionTest() throws IOException, InterruptedException {
// bug where last line did not have predecessors
Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "inpress-case8");
- String jarPath = Paths.get(testPath.toString(), "results" + File.separator + "new" + File.separator + "program.jar").toString();
+ String jarPath = Paths
+ .get(testPath.toString(), "results" + File.separator + "new" + File.separator + "program.jar")
+ .toString();
String depPath = Paths.get(testPath.toString(), "bug" + File.separator + "lib").toString();
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
String instrumentedJar = slicer.instrument();
- TestUtils.runInstrumentedJarFromTest(instrumentedJar, depPath, "org.apache.commons.lang3.time.FastDatePrinterTest", "testCalendarTimezoneRespected", String.valueOf(outDir));
+ TestUtils.runInstrumentedJarFromTest(instrumentedJar, depPath,
+ "org.apache.commons.lang3.time.FastDatePrinterTest", "testCalendarTimezoneRespected",
+ String.valueOf(outDir));
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
assert !dcfg.predecessorListOf((int) dcfg.getLastLine()).isEmpty();
}
- void runInsertionSortTest( int sourceLine, List expectedSlice ) throws IOException, InterruptedException {
- Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "InsertionSort-MemSat01");
+ void runInsertionSortTest(int sourceLine, List expectedSlice) throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(),
+ "benchmarks" + File.separator + "InsertionSort-MemSat01");
String jarPath = Paths.get(testPath.toString(), "test.jar").toString();
Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
@@ -594,12 +593,13 @@ void runInsertionSortTest( int sourceLine, List expectedSlice ) throws I
DynamicControlFlowGraph dcfg = slicer.prepareGraph();
slicer.printGraph(dcfg);
- List tracePositions = TestUtils.getTracePositionFromSourceLine( sourceLine, "Main", dcfg );
- List sliceLines = new ArrayList<>(TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositions)).stream()
+ List tracePositions = TestUtils.getTracePositionFromSourceLine(sourceLine, "Main", dcfg);
+ List sliceLines = new ArrayList<>(TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositions))
+ .stream()
.sorted((a, b) -> a.compareTo(b))
.collect(Collectors.toList());
- assertEquals( sliceLines, expectedSlice );
+ assertEquals(sliceLines, expectedSlice);
}
@Test
@@ -608,16 +608,52 @@ void svCompInsertionSort2() throws IOException, InterruptedException {
.sorted((a, b) -> a.compareTo(b))
.collect(Collectors.toList());
- runInsertionSortTest( 58, expected );
+ runInsertionSortTest(58, expected);
}
- @Test
- void svCompInsertionSort3() throws IOException, InterruptedException {
- List expected = Arrays.asList("Main:58", "Main:45", "Main:46", "Main:47", "Main:40", "Main:54",
- "Main:41", "Main:42", "Main:62", "Main:49", "Main:56", "Main:57", "Main:39" ).stream()
- .sorted((a, b) -> a.compareTo(b))
- .collect(Collectors.toList());
+ // This issue is related to the modeling of println. Please see #Issue 28 for an
+ // explanation of why this test is commented out
+ // @Test
+ // void issue28_1() throws IOException, InterruptedException {
+ // Path testPath = Paths.get(root.getParent().toString(), "benchmarks" +
+ // File.separator + "test-issue28-1");
+ // String jarPath = Paths.get(testPath.toString(), "target" + File.separator +
+ // "test-issue28-1-1.0.0.jar")
+ // .toString();
+ // TestUtils.buildJar(testPath);
+ // Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ // String instrumentedJar = slicer.instrument();
+ // slicer.runInstrumentedJarFromMain(instrumentedJar, "Main", "");
+ // DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ // slicer.printGraph(dcfg);
+ // List tracePositions = TestUtils.getTracePositionFromSourceLine(11,
+ // "Main", dcfg);
+ // Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg,
+ // tracePositions);
+ // Set expected = new HashSet<>(Arrays.asList(
+ // "Main:11",
+ // "Main:8",
+ // "Main:6",
+ // "Main:5",
+ // "Main:4",
+ // "Main:3"));
+ // assertEquals(expected, sliceLines);
+ // }
- runInsertionSortTest( 49, expected );
+ @Test
+ void issue28_2() throws IOException, InterruptedException {
+ Path testPath = Paths.get(root.getParent().toString(), "benchmarks" + File.separator + "test-issue28-2");
+ String jarPath = Paths.get(testPath.toString(), "target" + File.separator + "test-issue28-2-1.0.0.jar")
+ .toString();
+ TestUtils.buildJar(testPath);
+ Slicer slicer = TestUtils.setupSlicing(root, jarPath, outDir, sliceLogger);
+ String instrumentedJar = slicer.instrument();
+ slicer.runInstrumentedJarFromMain(instrumentedJar, "Main", "");
+ DynamicControlFlowGraph dcfg = slicer.prepareGraph();
+ slicer.printGraph(dcfg);
+ List tracePositions = TestUtils.getTracePositionFromSourceLine(6, "Main", dcfg);
+ Set sliceLines = TestUtils.sliceAndGetSourceLines(slicer, dcfg, tracePositions);
+ Assertions.assertFalse(sliceLines.contains("Main:3"));
+ Assertions.assertFalse(sliceLines.contains("Main:4"));
}
}
diff --git a/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/TestUtils.java b/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/TestUtils.java
index 4b6a1a9..2c5cc09 100644
--- a/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/TestUtils.java
+++ b/Slicer4J/src/test/java/ca/ubc/ece/resess/slicer/dynamic/slicer4j/TestUtils.java
@@ -58,37 +58,30 @@ public static void runInstrumentedJarFromTest(String pathToJar, String dependenc
testClass + "#" + testMethod;
ProcessBuilder pb = new ProcessBuilder("/bin/sh", "-c", cmd + "| grep \"SLICING\"");
Process p = pb.start();
- p.waitFor();
- BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
- BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir + File.separator + "trace.log"));
- String readline;
- while ((readline = reader.readLine()) != null) {
- writer.write(readline);
- writer.write("\n");
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ BufferedWriter writer = Files.newBufferedWriter(Paths.get(outDir + File.separator + "trace.log"))) {
+ String readline;
+ while ((readline = reader.readLine()) != null) {
+ writer.write(readline);
+ writer.write("\n");
+ }
}
- writer.close();
- reader.close();
+ p.waitFor();
}
protected static void buildJar(Path testPath) throws IOException, InterruptedException {
- Process p = null;
ProcessBuilder pb = new ProcessBuilder("mvn", "clean", "package");
pb.directory(testPath.toFile());
- p = pb.start();
- p.waitFor();
- System.out.println("Out stream: ");
- BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
- String readline;
- while ((readline = reader.readLine()) != null) {
- System.out.println(readline);
- }
- reader.close();
- System.out.println("Error stream: ");
- reader = new BufferedReader(new InputStreamReader(p.getErrorStream()));
- while ((readline = reader.readLine()) != null) {
- System.out.println(readline);
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
+ String readline;
+ while ((readline = reader.readLine()) != null) {
+ System.out.println(readline);
+ }
}
- reader.close();
+ p.waitFor();
}
protected static void cleanWorkingDirectory() throws IOException {
diff --git a/benchmarks/Gson_4b/gson/pom.xml b/benchmarks/Gson_4b/gson/pom.xml
index 99b17d3..5e89de8 100644
--- a/benchmarks/Gson_4b/gson/pom.xml
+++ b/benchmarks/Gson_4b/gson/pom.xml
@@ -113,8 +113,8 @@
maven-compiler-plugin
3.3
- 1.6
- 1.6
+ 1.7
+ 1.7
diff --git a/benchmarks/JacksonCore_4b/pom.xml b/benchmarks/JacksonCore_4b/pom.xml
index 748e7d6..2c195c3 100644
--- a/benchmarks/JacksonCore_4b/pom.xml
+++ b/benchmarks/JacksonCore_4b/pom.xml
@@ -1,5 +1,5 @@
- 4.0.0
+ 4.0.0
com.fasterxml.jackson
jackson-parent
@@ -18,7 +18,7 @@
scm:git:git@github.com:FasterXML/jackson-core.git
scm:git:git@github.com:FasterXML/jackson-core.git
- http://github.com/FasterXML/jackson-core
+ http://github.com/FasterXML/jackson-core
HEAD
@@ -34,6 +34,17 @@ com.fasterxml.jackson.core.*;version=${project.version}
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.7
+ 1.7
+ true
+ lines,vars,source
+
+
org.apache.maven.plugins
maven-javadoc-plugin
@@ -83,7 +94,7 @@ com.fasterxml.jackson.core.*;version=${project.version}
2.8.1
true
- 1.6
+ 1.7
UTF-8
1g
diff --git a/benchmarks/JacksonDatabind_3b/pom.xml b/benchmarks/JacksonDatabind_3b/pom.xml
index fd0177a..7a597ad 100644
--- a/benchmarks/JacksonDatabind_3b/pom.xml
+++ b/benchmarks/JacksonDatabind_3b/pom.xml
@@ -101,7 +101,18 @@ javax.xml.datatype, javax.xml.namespace, javax.xml.parsers
-
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.7
+ 1.7
+ true
+ lines,vars,source
+
+
org.apache.maven.plugins
maven-release-plugin
diff --git a/benchmarks/JacksonDatabind_3b/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java b/benchmarks/JacksonDatabind_3b/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java
index 6a33afb..a283592 100644
--- a/benchmarks/JacksonDatabind_3b/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java
+++ b/benchmarks/JacksonDatabind_3b/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java
@@ -27,7 +27,7 @@
* to ensure that registration works as expected.
*/
public class SimpleModule
- extends Module
+ extends com.fasterxml.jackson.databind.Module
implements java.io.Serializable
{
// at 2.4.0:
@@ -35,7 +35,7 @@ public class SimpleModule
protected final String _name;
protected final Version _version;
-
+
protected SimpleSerializers _serializers = null;
protected SimpleDeserializers _deserializers = null;
@@ -71,7 +71,7 @@ public class SimpleModule
* by target class, value being mix-in to apply.
*/
protected HashMap, Class>> _mixins = null;
-
+
/**
* Set of subtypes to register, if any.
*/
@@ -81,7 +81,7 @@ public class SimpleModule
* @since 2.3
*/
protected PropertyNamingStrategy _namingStrategy = null;
-
+
/*
/**********************************************************
/* Life-cycle: creation
@@ -98,7 +98,7 @@ public SimpleModule() {
_name = "SimpleModule-"+System.identityHashCode(this);
_version = Version.unknownVersion();
}
-
+
/**
* Convenience constructor that will default version to
* {@link Version#unknownVersion()}.
@@ -115,13 +115,13 @@ public SimpleModule(Version version) {
_name = version.getArtifactId();
_version = version;
}
-
+
/**
* Constructor to use for actual reusable modules.
* ObjectMapper may use name as identifier to notice attempts
* for multiple registrations of the same module (although it
* does not have to).
- *
+ *
* @param name Unique name of the module
* @param version Version of the module
*/
@@ -145,7 +145,7 @@ public SimpleModule(String name, Version version,
List> serializers) {
this(name, version, null, serializers);
}
-
+
/**
* @since 2.1
*/
@@ -162,7 +162,7 @@ public SimpleModule(String name, Version version,
_serializers = new SimpleSerializers(serializers);
}
}
-
+
/*
/**********************************************************
/* Simple setters to allow overriding
@@ -201,7 +201,7 @@ public void setKeyDeserializers(SimpleKeyDeserializers kd) {
* Resets currently configured abstract type mappings
*/
public void setAbstractTypes(SimpleAbstractTypeResolver atr) {
- _abstractTypes = atr;
+ _abstractTypes = atr;
}
/**
@@ -234,13 +234,13 @@ protected SimpleModule setNamingStrategy(PropertyNamingStrategy naming) {
_namingStrategy = naming;
return this;
}
-
+
/*
/**********************************************************
/* Configuration methods
/**********************************************************
*/
-
+
public SimpleModule addSerializer(JsonSerializer> ser)
{
if (_serializers == null) {
@@ -249,7 +249,7 @@ public SimpleModule addSerializer(JsonSerializer> ser)
_serializers.addSerializer(ser);
return this;
}
-
+
public SimpleModule addSerializer(Class extends T> type, JsonSerializer ser)
{
if (_serializers == null) {
@@ -267,7 +267,7 @@ public SimpleModule addKeySerializer(Class extends T> type, JsonSerializer
_keySerializers.addSerializer(type, ser);
return this;
}
-
+
public SimpleModule addDeserializer(Class type, JsonDeserializer extends T> deser)
{
if (_deserializers == null) {
@@ -349,7 +349,7 @@ public SimpleModule registerSubtypes(NamedType ... subtypes)
}
return this;
}
-
+
/**
* Method for specifying that annotations define by mixinClass
* should be "mixed in" with annotations that targetType
@@ -366,13 +366,13 @@ public SimpleModule setMixInAnnotation(Class> targetType, Class> mixinClass)
_mixins.put(targetType, mixinClass);
return this;
}
-
+
/*
/**********************************************************
/* Module impl
/**********************************************************
*/
-
+
@Override
public String getModuleName() {
return _name;
@@ -380,7 +380,7 @@ public String getModuleName() {
/**
* Standard implementation handles registration of all configured
- * customizations: it is important that sub-classes call this
+ * customizations: it is important that sub-classes call this
* implementation (usually before additional custom logic)
* if they choose to override it; otherwise customizations
* will not be registered.
diff --git a/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorNullValue.java b/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorNullValue.java
index 34e084d..7a504aa 100644
--- a/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorNullValue.java
+++ b/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/creators/TestCreatorNullValue.java
@@ -51,7 +51,7 @@ public JsonDeserializer> findBeanDeserializer(JavaType type,
}
}
- private static class TestModule extends Module
+ private static class TestModule extends com.fasterxml.jackson.databind.Module
{
@Override
public String getModuleName() {
@@ -74,7 +74,7 @@ public void setupModule(SetupContext setupContext) {
/* Unit tests
/**********************************************************
*/
-
+
public void testUsesDeserializersNullValue() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new TestModule());
diff --git a/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java b/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java
index 96f0840..cf2e2ac 100644
--- a/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java
+++ b/benchmarks/JacksonDatabind_3b/src/test/java/com/fasterxml/jackson/databind/module/TestSimpleModule.java
@@ -22,7 +22,7 @@ public class TestSimpleModule extends BaseMapTest
/* Helper classes; simple beans and their handlers
/**********************************************************
*/
-
+
/**
* Trivial bean that requires custom serializer and deserializer
*/
@@ -30,7 +30,7 @@ final static class CustomBean
{
protected String str;
protected int num;
-
+
public CustomBean(String s, int i) {
str = s;
num = i;
@@ -38,7 +38,7 @@ public CustomBean(String s, int i) {
}
static enum SimpleEnum { A, B; }
-
+
// Extend SerializerBase to get access to declared handledType
static class CustomBeanSerializer extends StdSerializer
{
@@ -57,7 +57,7 @@ public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws Jso
return null;
}
}
-
+
static class CustomBeanDeserializer extends JsonDeserializer
{
@Override
@@ -105,7 +105,7 @@ public SimpleEnum deserialize(JsonParser jp, DeserializationContext ctxt)
interface Base {
public String getText();
}
-
+
static class Impl1 implements Base {
@Override
public String getText() { return "1"; }
@@ -119,7 +119,7 @@ static class Impl2 extends Impl1 {
static class BaseSerializer extends StdScalarSerializer
{
public BaseSerializer() { super(Base.class); }
-
+
@Override
public void serialize(Base value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeString("Base:"+value.getText());
@@ -134,7 +134,7 @@ static class MixableBean {
@JsonPropertyOrder({"c", "a", "b"})
static class MixInForOrder { }
-
+
protected static class MySimpleSerializers extends SimpleSerializers { }
protected static class MySimpleDeserializers extends SimpleDeserializers { }
@@ -151,7 +151,7 @@ public MySimpleModule(String name, Version version) {
}
}
- protected static class ContextVerifierModule extends Module
+ protected static class ContextVerifierModule extends com.fasterxml.jackson.databind.Module
{
@Override
public String getModuleName() { return "x"; }
@@ -169,7 +169,7 @@ public void setupModule(SetupContext context)
assertNotNull(m);
}
}
-
+
/*
/**********************************************************
/* Unit tests; first, verifying need for custom handlers
@@ -199,13 +199,13 @@ public void testWithoutModule()
verifyException(e, "No suitable constructor found");
}
}
-
+
/*
/**********************************************************
/* Unit tests; simple serializers
/**********************************************************
*/
-
+
public void testSimpleBeanSerializer() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
@@ -234,13 +234,13 @@ public void testSimpleInterfaceSerializer() throws Exception
assertEquals(quote("Base:1"), mapper.writeValueAsString(new Impl1()));
assertEquals(quote("Base:2"), mapper.writeValueAsString(new Impl2()));
}
-
+
/*
/**********************************************************
/* Unit tests; simple deserializers
/**********************************************************
*/
-
+
public void testSimpleBeanDeserializer() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
@@ -261,7 +261,7 @@ public void testSimpleEnumDeserializer() throws Exception
SimpleEnum result = mapper.readValue(quote("a"), SimpleEnum.class);
assertSame(SimpleEnum.A, result);
}
-
+
// Simple verification of [JACKSON-455]
public void testMultipleModules() throws Exception
{
@@ -293,7 +293,7 @@ public void testMultipleModules() throws Exception
/* Unit tests; other
/**********************************************************
*/
-
+
// [JACKSON-644]: ability to register mix-ins
public void testMixIns() throws Exception
{
@@ -311,7 +311,7 @@ public void testMixIns() throws Exception
// [JACKSON-686]
public void testAccessToMapper() throws Exception
{
- ContextVerifierModule module = new ContextVerifierModule();
+ ContextVerifierModule module = new ContextVerifierModule();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
}
diff --git a/benchmarks/SliceMe/pom.xml b/benchmarks/SliceMe/pom.xml
index 1bab152..81a0df0 100644
--- a/benchmarks/SliceMe/pom.xml
+++ b/benchmarks/SliceMe/pom.xml
@@ -15,8 +15,8 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
diff --git a/benchmarks/benchmarks_compare.py b/benchmarks/benchmarks_compare.py
index 6bb91b3..696fa0c 100644
--- a/benchmarks/benchmarks_compare.py
+++ b/benchmarks/benchmarks_compare.py
@@ -16,7 +16,7 @@
"javaslicer-bench1-intra-procedural" : ("target/javaslicer-bench1-intra-procedural-1.0.0.jar", "Bench 2 ", "Bench", 8),
"javaslicer-bench2-inter-procedural" : ("target/javaslicer-bench2-inter-procedural-1.0.0.jar", "Bench 2 4 ", "Bench", 8),
"javaslicer-bench3-exceptions" : ("target/javaslicer-bench3-exceptions-1.0.0.jar", "Bench ", "Bench", 29),
- "slicer4j-bench1-multiple-threads": ("target/slicer4j-bench1-multiple-threads-1.0.0.jar", "Bench ", "Bench", 14),
+ "slicer4j-bench1-multiple-threads": ("target/slicer4j-bench1-multiple-threads-1.0.0.jar", "Bench ", "Bench", 14),
"slicer4j-bench2-native-framework": ("target/slicer4j-bench2-native-framework-1.0.0.jar", "Bench 0 4", "Bench", 9),
"slicer4j-bench3-java-9-constructs": ("target/slicer4j-bench3-java-9-constructs-1.0.0.jar", "Bench 3 4", "Bench", 9),
"slicer4j-bench4-instrumentation-classes": ("target/slicer4j-bench4-instrumentation-classes-1.0.0.jar", "Bench 22 ", "Bench", 10),
@@ -25,8 +25,8 @@
defects4j_benchmarks = {
"JacksonDatabind_3b": ("target/jackson-databind-2.4.1-SNAPSHOT.jar", "org.junit.runner.JUnitCore com.fasterxml.jackson.databind.deser.TestArrayDeserialization", "com.fasterxml.jackson.databind.ObjectMapper", "3062", "_readMapAndClose", "JacksonDatabind_3b/target/test-classes/:JacksonDatabind_3b/target/dependency/*"),
- "Gson_4b": ("gson/target/gson-2.6-SNAPSHOT.jar", "junit.textui.TestRunner com.google.gson.stream.JsonReaderTest", "com.google.gson.stream.JsonReader", "1422", "checkLenient", "Gson_4b/gson/target/test-classes/:Gson_4b/gson/target/dependency/*"),
- "JacksonCore_4b": ("target/jackson-core-2.5.0-SNAPSHOT.jar", "org.junit.runner.JUnitCore com.fasterxml.jackson.core.util.TestTextBuffer", "com.fasterxml.jackson.core.util.TextBuffer", "587", "expandCurrentSegment", "JacksonCore_4b/target/test-classes/:JacksonCore_4b/target/dependency/*"),
+ "Gson_4b": ("gson/target/gson-2.6-SNAPSHOT.jar", "junit.textui.TestRunner com.google.gson.stream.JsonReaderTest", "com.google.gson.stream.JsonReader", "1422", "checkLenient", "Gson_4b/gson/target/test-classes/:Gson_4b/gson/target/dependency/*"),
+ "JacksonCore_4b": ("target/jackson-core-2.5.0-SNAPSHOT.jar", "org.junit.runner.JUnitCore com.fasterxml.jackson.core.util.TestTextBuffer", "com.fasterxml.jackson.core.util.TextBuffer", "587", "expandCurrentSegment", "JacksonCore_4b/target/test-classes/:JacksonCore_4b/target/dependency/*"),
}
analysis = open("js-vs-slc4j.csv","w")
@@ -141,7 +141,9 @@ def run_slicer4jold(project, jar_name, project_arg, extra_libs, sc_file, slice_l
print(f"looking for LINENO:{slice_line}:FILE:{sc_file}")
with open(f"{out_dir}/trace.log_icdg.log", 'r') as f:
for l in f:
- if f"LINENO:{slice_line}:FILE:{sc_file}" in l:
+ if "goto [" in l:
+ pass
+ elif f"LINENO:{slice_line}:FILE:{sc_file}" in l:
sc = l.rstrip()
line = sc.split(", ")[0]
slice_cmd = f"java -Xmx8g -cp \"{slicer4j_dir}/target/slicer4j_old.jar:{slicer4j_dir}/target/lib/*\" ca.ubc.ece.resess.slicer.dynamic.slicer4j.Slicer -j {jar_name} -m s -t {out_dir}/trace.log -o {out_dir}/ -sl {out_dir}/static-log.log -sd {slicer4j_dir}/../models/summariesManual -tw {slicer4j_dir}/../models/EasyTaintWrapperSource.txt -sp {line} > {out_dir}/{slice_file}_{line}.log 2>&1"
@@ -198,7 +200,9 @@ def run_slicer4jnew(project, jar_name, project_arg, extra_libs, sc_file, slice_l
print(f"looking for LINENO:{slice_line}:FILE:{sc_file}")
with open(f"{out_dir}/trace.log_icdg.log", 'r') as f:
for l in f:
- if f"LINENO:{slice_line}:FILE:{sc_file}" in l:
+ if "goto [" in l:
+ pass
+ elif f"LINENO:{slice_line}:FILE:{sc_file}" in l:
sc = l.rstrip()
line = sc.split(", ")[0]
slice_cmd = f"java -Xmx8g -cp \"{slicer4j_dir}/target/slicer4j_new.jar:{slicer4j_dir}/target/lib/*\" ca.ubc.ece.resess.slicer.dynamic.slicer4j.Slicer -j {jar_name} -m s -t {out_dir}/trace.log -o {out_dir}/ -sl {out_dir}/static-log.log -sd {slicer4j_dir}/../models/summariesManual -tw {slicer4j_dir}/../models/EasyTaintWrapperSource.txt -sp {line} -noprint > {out_dir}/{slice_file}_{line}.log 2>&1"
diff --git a/benchmarks/issue-42-slicer4j-bench-const-prop-cross-call/pom.xml b/benchmarks/issue-42-slicer4j-bench-const-prop-cross-call/pom.xml
new file mode 100644
index 0000000..f76842e
--- /dev/null
+++ b/benchmarks/issue-42-slicer4j-bench-const-prop-cross-call/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ 4.0.0
+ slicer4j
+ issue-42-slicer4j-bench-const-prop-cross-call
+ 1.0.0
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ true
+ lines,vars,source
+
+
+
+
+
+
diff --git a/benchmarks/issue-42-slicer4j-bench-const-prop-cross-call/src/main/java/Bench.java b/benchmarks/issue-42-slicer4j-bench-const-prop-cross-call/src/main/java/Bench.java
new file mode 100644
index 0000000..77571ab
--- /dev/null
+++ b/benchmarks/issue-42-slicer4j-bench-const-prop-cross-call/src/main/java/Bench.java
@@ -0,0 +1,17 @@
+public class Bench {
+
+ static int compute(int start, int end, int seed) {
+ int gap = end - start; // line 4
+ int offset = start + 1; // line 5
+ int base = gap * 2; // line 6
+ int result = base + offset + seed; // line 7
+ return result; // line 8
+ }
+
+ public static void main(String[] args) {
+ int x = 5; // line 11
+ int y = 15; // line 12
+ int z = compute(x, y, 3); // line 13
+ System.out.println(z); // line 14
+ }
+}
diff --git a/benchmarks/issue-42-slicer4j-bench-const-prop-selective/pom.xml b/benchmarks/issue-42-slicer4j-bench-const-prop-selective/pom.xml
new file mode 100644
index 0000000..71ba813
--- /dev/null
+++ b/benchmarks/issue-42-slicer4j-bench-const-prop-selective/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ 4.0.0
+ slicer4j
+ issue-42-slicer4j-bench-const-prop-selective
+ 1.0.0
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ true
+ lines,vars,source
+
+
+
+
+
+
diff --git a/benchmarks/issue-42-slicer4j-bench-const-prop-selective/src/main/java/Bench.java b/benchmarks/issue-42-slicer4j-bench-const-prop-selective/src/main/java/Bench.java
new file mode 100644
index 0000000..fbe9cee
--- /dev/null
+++ b/benchmarks/issue-42-slicer4j-bench-const-prop-selective/src/main/java/Bench.java
@@ -0,0 +1,13 @@
+public class Bench {
+ public static void main(String[] args) {
+ int MAGIC = 42; // line 3
+ int FACTOR = 3; // line 4
+ int dynamic = args.length; // line 5
+ int mixed = MAGIC + dynamic; // line 6
+ int step1 = mixed * FACTOR; // line 7
+ int step2 = step1 + MAGIC; // line 8
+ int step3 = step2 - dynamic; // line 9
+ String msg = "Result=" + step3; // line 10
+ System.out.println(msg); // line 11
+ }
+}
diff --git a/benchmarks/issue-42-slicer4j-bench-const-prop-simple/pom.xml b/benchmarks/issue-42-slicer4j-bench-const-prop-simple/pom.xml
new file mode 100644
index 0000000..fc0db18
--- /dev/null
+++ b/benchmarks/issue-42-slicer4j-bench-const-prop-simple/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ 4.0.0
+ slicer4j
+ issue-42-slicer4j-bench-const-prop-simple
+ 1.0.0
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+ true
+ lines,vars,source
+
+
+
+
+
+
diff --git a/benchmarks/issue-42-slicer4j-bench-const-prop-simple/src/main/java/Bench.java b/benchmarks/issue-42-slicer4j-bench-const-prop-simple/src/main/java/Bench.java
new file mode 100644
index 0000000..40afa60
--- /dev/null
+++ b/benchmarks/issue-42-slicer4j-bench-const-prop-simple/src/main/java/Bench.java
@@ -0,0 +1,9 @@
+public class Bench {
+ public static void main(String[] args) {
+ int b = 2; // line 3
+ int a = 1 + b; // line 4
+ int c = a * 3; // line 5
+ int d = c + 10; // line 6
+ System.out.println(d); // line 7
+ }
+}
diff --git a/benchmarks/javaslicer-bench1-intra-procedural/pom.xml b/benchmarks/javaslicer-bench1-intra-procedural/pom.xml
index 9be6808..c033263 100644
--- a/benchmarks/javaslicer-bench1-intra-procedural/pom.xml
+++ b/benchmarks/javaslicer-bench1-intra-procedural/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/javaslicer-bench2-inter-procedural/pom.xml b/benchmarks/javaslicer-bench2-inter-procedural/pom.xml
index ec86d11..6e74678 100644
--- a/benchmarks/javaslicer-bench2-inter-procedural/pom.xml
+++ b/benchmarks/javaslicer-bench2-inter-procedural/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/javaslicer-bench3-exceptions/pom.xml b/benchmarks/javaslicer-bench3-exceptions/pom.xml
index 058d3b3..e1fe777 100644
--- a/benchmarks/javaslicer-bench3-exceptions/pom.xml
+++ b/benchmarks/javaslicer-bench3-exceptions/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/run_benchmarks.py b/benchmarks/run_benchmarks.py
index b30fc62..8a5efed 100644
--- a/benchmarks/run_benchmarks.py
+++ b/benchmarks/run_benchmarks.py
@@ -16,7 +16,7 @@
"javaslicer-bench1-intra-procedural" : ("target/javaslicer-bench1-intra-procedural-1.0.0.jar", "Bench 2 ", "Bench", 8),
"javaslicer-bench2-inter-procedural" : ("target/javaslicer-bench2-inter-procedural-1.0.0.jar", "Bench 2 4 ", "Bench", 8),
"javaslicer-bench3-exceptions" : ("target/javaslicer-bench3-exceptions-1.0.0.jar", "Bench ", "Bench", 29),
- "slicer4j-bench1-multiple-threads": ("target/slicer4j-bench1-multiple-threads-1.0.0.jar", "Bench ", "Bench", 14),
+ "slicer4j-bench1-multiple-threads": ("target/slicer4j-bench1-multiple-threads-1.0.0.jar", "Bench ", "Bench", 14),
"slicer4j-bench2-native-framework": ("target/slicer4j-bench2-native-framework-1.0.0.jar", "Bench 0 4", "Bench", 9),
"slicer4j-bench3-java-9-constructs": ("target/slicer4j-bench3-java-9-constructs-1.0.0.jar", "Bench 3 4", "Bench", 9),
"slicer4j-bench4-instrumentation-classes": ("target/slicer4j-bench4-instrumentation-classes-1.0.0.jar", "Bench 22 ", "Bench", 10),
@@ -25,8 +25,8 @@
defects4j_benchmarks = {
"JacksonDatabind_3b": ("target/jackson-databind-2.4.1-SNAPSHOT.jar", "org.junit.runner.JUnitCore com.fasterxml.jackson.databind.deser.TestArrayDeserialization", "com.fasterxml.jackson.databind.ObjectMapper", "3062", "_readMapAndClose", "JacksonDatabind_3b/target/test-classes/:JacksonDatabind_3b/target/dependency/*"),
- "Gson_4b": ("gson/target/gson-2.6-SNAPSHOT.jar", "junit.textui.TestRunner com.google.gson.stream.JsonReaderTest", "com.google.gson.stream.JsonReader", "1422", "checkLenient", "Gson_4b/gson/target/test-classes/:Gson_4b/gson/target/dependency/*"),
- "JacksonCore_4b": ("target/jackson-core-2.5.0-SNAPSHOT.jar", "org.junit.runner.JUnitCore com.fasterxml.jackson.core.util.TestTextBuffer", "com.fasterxml.jackson.core.util.TextBuffer", "587", "expandCurrentSegment", "JacksonCore_4b/target/test-classes/:JacksonCore_4b/target/dependency/*"),
+ "Gson_4b": ("gson/target/gson-2.6-SNAPSHOT.jar", "junit.textui.TestRunner com.google.gson.stream.JsonReaderTest", "com.google.gson.stream.JsonReader", "1422", "checkLenient", "Gson_4b/gson/target/test-classes/:Gson_4b/gson/target/dependency/*"),
+ "JacksonCore_4b": ("target/jackson-core-2.5.0-SNAPSHOT.jar", "org.junit.runner.JUnitCore com.fasterxml.jackson.core.util.TestTextBuffer", "com.fasterxml.jackson.core.util.TextBuffer", "587", "expandCurrentSegment", "JacksonCore_4b/target/test-classes/:JacksonCore_4b/target/dependency/*"),
}
def count_lines_slice_slicer4j(trace):
@@ -77,11 +77,14 @@ def count_lines_slice_javaslicer(trace):
def build_jar(project):
cwd = os.getcwd()
os.chdir(f"{project}")
- cmd = f"mvn clean package > /dev/null 2>&1"
+ print(f"Building {project}")
+ cmd = f"mvn clean"
os.system(cmd)
- cmd = f"mvn -Dmaven.test.skip=true package > /dev/null 2>&1"
+ cmd = f"mvn -Dmaven.test.skip=true package"
os.system(cmd)
- cmd = "mvn dependency:copy-dependencies > /dev/null 2>&1"
+ cmd = f"mvn test-compile"
+ os.system(cmd)
+ cmd = "mvn dependency:copy-dependencies"
os.system(cmd)
os.chdir(cwd)
@@ -106,13 +109,14 @@ def run_slicer4j(project, jar_name, project_arg, extra_libs, sc_file, slice_line
if os.path.isdir(out_dir):
os.system(f"rm -r {out_dir}")
os.mkdir(out_dir)
- instr_cmd = f"java -cp \"{slicer4j_dir}/target/slicer4j-jar-with-dependencies.jar:{slicer4j_dir}/target/lib/*\" ca.ubc.ece.resess.slicer.dynamic.slicer4j.Slicer -m i -j {jar_name} -o {out_dir}/ -sl {out_dir}/static-log.log -lc {dynamic_slicing_core}/DynamicSlicingLoggingClasses/DynamicSlicingLogger.jar > /dev/null 2>&1"
+ instr_cmd = f"java -cp \"{slicer4j_dir}/target/slicer4j-jar-with-dependencies.jar:{slicer4j_dir}/target/lib/*\" ca.ubc.ece.resess.slicer.dynamic.slicer4j.Slicer -m i -j {jar_name} -o {out_dir}/ -sl {out_dir}/static-log.log -lc {dynamic_slicing_core}/DynamicSlicingLoggingClasses/DynamicSlicingLogger.jar"
os.system(instr_cmd)
instr_time = time.time()
print(f"Instrumentation time (s): {instr_time-start_instr}")
instrumented_jar = os.path.basename(jar_name).replace(".jar", "_i.jar")
cmd = f"java -cp \"{out_dir}/{instrumented_jar}:{extra_libs}\" {project_arg} | grep \"SLICING\" > {out_dir}/trace.log"
- # print(cmd)
+ print(f"Running instrumented jar with the following command:")
+ print(cmd)
os.system(cmd)
trace = list()
with open(f"{out_dir}/trace.log", 'r') as f:
@@ -137,11 +141,15 @@ def run_slicer4j(project, jar_name, project_arg, extra_libs, sc_file, slice_line
line = sc.split(", ")[0]
else:
print(f"looking for LINENO:{slice_line}:FILE:{sc_file}")
+ print(f"Looking in {out_dir}/trace.log_icdg.log")
with open(f"{out_dir}/trace.log_icdg.log", 'r') as f:
for l in f:
- if f"LINENO:{slice_line}:FILE:{sc_file}" in l:
+ if "goto [" in l:
+ pass
+ elif f"LINENO:{slice_line}:FILE:{sc_file}" in l:
sc = l.rstrip()
line = sc.split(", ")[0]
+ print(f"Slice criterion found: {sc}")
slice_cmd = f"java -Xmx8g -cp \"{slicer4j_dir}/target/slicer4j-jar-with-dependencies.jar:{slicer4j_dir}/target/lib/*\" ca.ubc.ece.resess.slicer.dynamic.slicer4j.Slicer -j {jar_name} -m s -t {out_dir}/trace.log -o {out_dir}/ -sl {out_dir}/static-log.log -sd {slicer4j_dir}/../models/summariesManual -tw {slicer4j_dir}/../models/EasyTaintWrapperSource.txt -sp {line} -d > {out_dir}/{slice_file}_{line}.log 2>&1"
os.system(slice_cmd)
slice_time = time.time()
diff --git a/benchmarks/slicer4j-bench1-multiple-threads/pom.xml b/benchmarks/slicer4j-bench1-multiple-threads/pom.xml
index b49db40..e490cec 100644
--- a/benchmarks/slicer4j-bench1-multiple-threads/pom.xml
+++ b/benchmarks/slicer4j-bench1-multiple-threads/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/slicer4j-bench2-native-framework/pom.xml b/benchmarks/slicer4j-bench2-native-framework/pom.xml
index 5f0af2b..e662512 100644
--- a/benchmarks/slicer4j-bench2-native-framework/pom.xml
+++ b/benchmarks/slicer4j-bench2-native-framework/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/slicer4j-bench4-instrumentation-classes/pom.xml b/benchmarks/slicer4j-bench4-instrumentation-classes/pom.xml
index 79564a7..070a1d5 100644
--- a/benchmarks/slicer4j-bench4-instrumentation-classes/pom.xml
+++ b/benchmarks/slicer4j-bench4-instrumentation-classes/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/slicer4j-bench5-static-constructor/pom.xml b/benchmarks/slicer4j-bench5-static-constructor/pom.xml
index fb70257..71c28eb 100644
--- a/benchmarks/slicer4j-bench5-static-constructor/pom.xml
+++ b/benchmarks/slicer4j-bench5-static-constructor/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/test-conditions/pom.xml b/benchmarks/test-conditions/pom.xml
index d9cbac5..a098d8c 100644
--- a/benchmarks/test-conditions/pom.xml
+++ b/benchmarks/test-conditions/pom.xml
@@ -15,8 +15,8 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
diff --git a/benchmarks/test-issue1/pom.xml b/benchmarks/test-issue1/pom.xml
index 8e7e0ff..c8bb67e 100644
--- a/benchmarks/test-issue1/pom.xml
+++ b/benchmarks/test-issue1/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/test-issue2/pom.xml b/benchmarks/test-issue2/pom.xml
index adfed40..6dc5a15 100644
--- a/benchmarks/test-issue2/pom.xml
+++ b/benchmarks/test-issue2/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/benchmarks/test-issue28-1/pom.xml b/benchmarks/test-issue28-1/pom.xml
new file mode 100644
index 0000000..2350755
--- /dev/null
+++ b/benchmarks/test-issue28-1/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ 4.0.0
+ slicer4j
+ test-issue28-1
+ 1.0.0
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.7
+ 1.7
+ true
+ lines,vars,source
+
+
+
+
+
+
diff --git a/benchmarks/test-issue28-1/src/main/java/Main.java b/benchmarks/test-issue28-1/src/main/java/Main.java
new file mode 100644
index 0000000..065aa9b
--- /dev/null
+++ b/benchmarks/test-issue28-1/src/main/java/Main.java
@@ -0,0 +1,13 @@
+public class Main {
+ public static void main(String[] args) {
+ double[] grades = { 50.0, 60.0, 60.0, 70.0 };
+ double product = 1.0;
+ double sum = 0.0;
+ for (double g1 : grades) {
+ sum += g1;
+ product *= 10.0;
+ }
+ System.out.println(sum);
+ System.out.println(product);
+ }
+}
diff --git a/benchmarks/test-issue28-2/pom.xml b/benchmarks/test-issue28-2/pom.xml
new file mode 100644
index 0000000..065364a
--- /dev/null
+++ b/benchmarks/test-issue28-2/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ 4.0.0
+ slicer4j
+ test-issue28-2
+ 1.0.0
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.7
+ 1.7
+ true
+ lines,vars,source
+
+
+
+
+
+
diff --git a/benchmarks/test-issue28-2/src/main/java/Main.java b/benchmarks/test-issue28-2/src/main/java/Main.java
new file mode 100644
index 0000000..e8d728a
--- /dev/null
+++ b/benchmarks/test-issue28-2/src/main/java/Main.java
@@ -0,0 +1,14 @@
+public class Main {
+ public static void main(String[] args) {
+ int a = func(1);
+ int b = func(2);
+ int c = func(3);
+ test(c);
+ }
+ public static int func(int x) {
+ return x + 1;
+ }
+ public static void test(int x) {
+ System.out.println(x);
+ }
+}
diff --git a/benchmarks/test-issue5/pom.xml b/benchmarks/test-issue5/pom.xml
index 5be30d8..d4391e8 100644
--- a/benchmarks/test-issue5/pom.xml
+++ b/benchmarks/test-issue5/pom.xml
@@ -14,10 +14,10 @@
maven-compiler-plugin
3.8.1
- 1.6
- 1.6
+ 1.7
+ 1.7
true
- lines,vars,source
+ lines,vars,source
diff --git a/scripts/slicer4j.py b/scripts/slicer4j.py
index d9b1693..20f41a6 100644
--- a/scripts/slicer4j.py
+++ b/scripts/slicer4j.py
@@ -37,6 +37,7 @@ def main():
test_class = options["test_class"]
test_method = options["test_method"]
+ test_classes_dir = options["test_classes_dir"]
main_class_args = options["main_class_args"]
framework_models = options["framework_models"]
@@ -49,6 +50,8 @@ def main():
extra_options += "-ctrl "
if options["once"]:
extra_options += "-once "
+ if options["function_slice"]:
+ extra_options += "-fs "
if options["data_only"] and options["ctrl_only"]:
print("Conflicting arguments: data-only and control-only!")
return
@@ -60,7 +63,7 @@ def main():
instrumented_jar = instrument(jar_file=jar_file, out_dir=out_dir)
print(f"Instrumented jar is at: {instrumented_jar}", flush=True)
- run(instrumented_jar, dependencies, out_dir, test_class, test_method, main_class_args)
+ run(instrumented_jar, dependencies, out_dir, test_class, test_method, test_classes_dir, main_class_args)
log_file, slice_graph = dynamic_slice(jar_file=jar_file, out_dir=out_dir, backward_criterion=backward_criterion, variables=options['variables'],
extra_options=extra_options)
@@ -68,6 +71,9 @@ def main():
print(f"Raw slice: {out_dir}/raw-slice.log")
print(f"Slice graph: {slice_graph}")
print(f"Slice with dependencies: {out_dir}/slice-dependencies.log")
+ if options["function_slice"]:
+ print(f"Function-level slice: {out_dir}/slice-function.log")
+ print(f"Pretty-print report: {out_dir}/slice-pretty.log")
def instrument(jar_file: str, out_dir: str) -> str:
@@ -79,10 +85,11 @@ def instrument(jar_file: str, out_dir: str) -> str:
return out_dir + os.sep + instrumented_jar
-def run(instrumented_jar, dependencies, out_dir, test_class, test_method, main_class_args):
+def run(instrumented_jar, dependencies, out_dir, test_class, test_method, test_classes_dir, main_class_args):
print("Running the instrumented JAR", flush=True)
if main_class_args is None:
- cmd = f"java -Xmx8g -cp \"{script_dir}/SingleJUnitTestRunner.jar:{script_dir}/junit-4.8.2.jar:{instrumented_jar}:{dependencies}/*\" SingleJUnitTestRunner {test_class}#{test_method} > {out_dir}/trace_full.log"
+ tcd_part = f":{test_classes_dir}" if test_classes_dir else ""
+ cmd = f"java -Xmx8g -cp \"{script_dir}/SingleJUnitTestRunner.jar:{script_dir}/junit-4.8.2.jar:{instrumented_jar}{tcd_part}:{dependencies}/*\" SingleJUnitTestRunner {test_class}#{test_method} > {out_dir}/trace_full.log"
else:
if main_class_args.startswith("\"") and main_class_args.endswith("\""):
main_class_args = main_class_args[1:-1]
@@ -166,12 +173,20 @@ def parse():
help="Main class to run with arguments", metavar="name", required=False)
parser.add_argument("-dep", "--dependencies", dest="dependencies",
help="JAR dependencies", metavar="path", required=False)
+ parser.add_argument("-tcd", "--test-classes-dir", dest="test_classes_dir",
+ help="Directory containing compiled test classes", metavar="path", required=False)
+
+ # Function-level slicing support: expands slicing criterion from a single
+ # source line to all trace statements within the containing method.
+ parser.add_argument("-fs", "--function-slice", dest="function_slice",
+ help="Perform function-level slicing instead of line-level", action='store_true', required=False)
args = parser.parse_args()
return {
"jar_file": args.jar_file, "out_dir": args.out_dir, "backward_criterion": args.backward_criterion,
"variables": args.variables, "data_only": args.data_only, "ctrl_only": args.ctrl_only,
"test_class": args.test_class, "test_method": args.test_method, "main_class_args": args.main_class_args,
- "dependencies": args.dependencies, "framework_models": args.framework_models, "debug": args.debug, "once": args.once
+ "dependencies": args.dependencies, "framework_models": args.framework_models, "debug": args.debug, "once": args.once,
+ "test_classes_dir": args.test_classes_dir, "function_slice": args.function_slice
}