It is very hard to fix a software failure without being able to reproduce it. However, reproducing a failure is often difficult and time-consuming. This paper proposes a novel technique, ReCrash, that generates multiple unit tests that reproduce a given program failure. During every execution of the target program, ReCrash stores partial copies of method arguments in memory. If the program fails (e.g., crashes), ReCrash uses the saved information to create unit tests reproducing the failure.
We present ReCrashJ, an implementation of ReCrash for Java. ReCrashJ reproduced real crashes from Javac, SVNKit, Eclipsec, and BST. ReCrashJ is efficient, incurring 13%--64% performance overhead. If this overhead is unacceptable, then ReCrashJ has another mode that has negligible overhead until a crash occurs and 0%--1.7% overhead until the crash occurs for a second time, at which point the test cases are generated.
Contents:
This section shows how to use ReCrash. (Use 'ant' first to compile the source code)
public class CrashExample { public static int abs(Integer i) { Integer ret = null; if (i < 0) { ret = -i; } else if (i > 0) { ret = i; } return ret.intValue(); } public static void main(String args[]) { CrashExample crash = new CrashExample(); try { abs(rand()); } catch(Exception e) { e.printStack(); } } /** Returns a random int between -10 and 10, inclusive. */ public static int rand() { return new Random().nextInt(21)-10; } } |
This does not have any side-effect of your program and does not require any additional jar files. The annotated source code will look like:
public class CrashExample { [...] public static void main(String args[]) { try { CrashExample crash = new CrashExample(); abs(rand()); } catch(Exception e) { "reCrash with".equals(e); e.printStack(); } } [...] } |
reCrash.jar
. For example, to run the CrashExample.class:
java -javaagent:reCrash.jar CrashExample |
java -jar reCrash.jar CrashExample.class trans/CrashExample.class |
java -jar reCrash.jar yourProgram.jar transformedProgram.jar |
reCrash.jar
in your class path.
To distribute the instrumented class files, you need to include reCrash.jar
with the instrumented class file(s).
public class Recrash51901 extends TestCase { public void setUp() throws Exception { TraceReader.readTrace("/tmp/reCrash51901.trace.gz"); } public void test_CrashExample_abs_1() throws Throwable { TraceReader.setMethodTraceItem(1); CrashExample thisObject = (CrashExample) TraceReader.readObject(0); // load arguments Integer arg_1 = 0; // Method invocation thisObject.abs(arg_1); } } |
reCrash.jar
and your subject program it in your class path.
You can contribute to ReCrash by sending bug reports, code patches, and suggestions. Use the public mailing list for ReCrash bug report or suggestions: recrash@googlegroups.com. You can subscribe and view the mail archive at http://groups.google.com/group/recrash.
Last updated: April 10, 2009