The revision 7 includes a working (toy) version of reCrash. Check this out!
Run CrashExampleInstrumented first. It will trace and generate a trace
file. Then run CrashGenerator and it will generate a working test case
from trace.
- Sung
---------- Forwarded message ----------
From: Sung Kim <hun...@csail.mit.edu>
Date: Jul 6, 2007 12:37 AM
Subject: [reCrash Project] r7 - in
trunk/reCrash/src/edu/mit/csail/pag/recrash: . generator toy
To: ar...@csail.mit.edu, hun...@gmail.com
Author: hunkim
Date: 2007-07-06 00:37:49 -0400 (Fri, 06 Jul 2007)
New Revision: 7
Added:
trunk/reCrash/src/edu/mit/csail/pag/recrash/MethodInfo.java
trunk/reCrash/src/edu/mit/csail/pag/recrash/generator/
trunk/reCrash/src/edu/mit/csail/pag/recrash/generator/CrashGenerator.java
trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/GeneratedTest.java
Removed:
trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/RePlayCrashExample.java
Modified:
trunk/reCrash/src/edu/mit/csail/pag/recrash/TraceItem.java
trunk/reCrash/src/edu/mit/csail/pag/recrash/Tracer.java
trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/CrashExampleInstrumented.java
Log:
This revision includes a generato that can generate a working test
case from serialized object (TraceItem).
* MethodInfo.java: added
- To store method information such as name, parameters
* Tracer.java: added more method to capture method info and generate test case
* CrashGenerator: added. It generates working test cases from
serialized TraceItem.
* GeneratedTtest.java: added. Generated code
Added: trunk/reCrash/src/edu/mit/csail/pag/recrash/MethodInfo.java
===================================================================
--- trunk/reCrash/src/edu/mit/csail/pag/recrash/MethodInfo.java
(rev 0)
+++ trunk/reCrash/src/edu/mit/csail/pag/recrash/MethodInfo.java
2007-07-06 04:37:49 UTC (rev 7)
@@ -0,0 +1,64 @@
+package edu.mit.csail.pag.recrash;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Method information
+ *
+ * @author hunkim
+ *
+ */
+public class MethodInfo {
+ // Method name
+ String methodName;
+
+ // parent class name
+ String fullyQualifiedParentCLassName;
+
+ // argument type array
+ List<String> argumentTypeList = new ArrayList<String>();
+
+ // argument name array
+ List<String> argumentNameList = new ArrayList<String>();
+
+ /**
+ * set Method name
+ * @param methodName
+ */
+ public MethodInfo(String methodName) {
+ this.methodName = methodName;
+ }
+
+ void addArgument(String name, Object object) {
+ argumentNameList.add(name);
+ argumentTypeList.add(object.getClass().getCanonicalName());
+ }
+
+ int getNumberOfArguments() {
+ return this.argumentNameList.size();
+ }
+
+ String getArgumentName(int index) {
+ assert (index >= 0 && index < this.argumentNameList.size());
+ return this.argumentNameList.get(index);
+ }
+
+ String getArgumentType(int index) {
+ assert (index >= 0 && index < this.argumentTypeList.size());
+ return this.argumentTypeList.get(index);
+ }
+
+ public void setFullyQualifiedParentCLassName(Object object) {
+ this.fullyQualifiedParentCLassName = object.getClass()
+ .getCanonicalName();
+ }
+
+ public String getFullyQualifiedParentCLassName() {
+ return fullyQualifiedParentCLassName;
+ }
+
+ public String getMethodName() {
+ return methodName;
+ }
+}
Modified: trunk/reCrash/src/edu/mit/csail/pag/recrash/TraceItem.java
===================================================================
--- trunk/reCrash/src/edu/mit/csail/pag/recrash/TraceItem.java
2007-07-05 20:29:57 UTC (rev 6)
+++ trunk/reCrash/src/edu/mit/csail/pag/recrash/TraceItem.java
2007-07-06 04:37:49 UTC (rev 7)
@@ -3,32 +3,64 @@
import java.util.Hashtable;
/**
- * This Item will bs stored and passed to server
+ * This Item will be stored and passed to the server
*
* @author hunkim
*
*/
public class TraceItem {
+ // store current object
private Hashtable<String, String> currentTrace = new
Hashtable<String, String>();
+ // current exception
private Exception crashedException;
- // TODO: We need to add signature info of current function
- String signatureInfo;
+ // current method information
+ private MethodInfo methodInfo;
+
+ public TraceItem(String methodName) {
+ methodInfo = new MethodInfo(methodName);
+ }
+ /**
+ * Add one object. Object type is stored methodInfo
+ * @param name argument name
+ * @param serializedXMLString serialized object
+ */
void addObject(String name, String serializedXMLString) {
currentTrace.put(name, serializedXMLString);
}
+ /**
+ * Read object by argument Name
+ * @param name argument name
+ * @return
+ */
String readObject(String name) {
return currentTrace.get(name);
}
+ /**
+ * Get exception
+ * @return
+ */
public Exception getCrashedException() {
return crashedException;
}
+ /**
+ * Store crash exception
+ * @param crashedException
+ */
public void setCrashedException(Exception crashedException) {
this.crashedException = crashedException;
}
+
+ /**
+ * Get method info
+ * @return
+ */
+ public MethodInfo getMethodInfo() {
+ return methodInfo;
+ }
}
Modified: trunk/reCrash/src/edu/mit/csail/pag/recrash/Tracer.java
===================================================================
--- trunk/reCrash/src/edu/mit/csail/pag/recrash/Tracer.java
2007-07-05 20:29:57 UTC (rev 6)
+++ trunk/reCrash/src/edu/mit/csail/pag/recrash/Tracer.java
2007-07-06 04:37:49 UTC (rev 7)
@@ -3,6 +3,7 @@
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.util.Date;
import com.thoughtworks.xstream.XStream;
@@ -16,14 +17,15 @@
// TODO: need to make this path in configure file or something
static final String TRACE_FILE = "/tmp/reCrash.trace";
+ // used to serialize the stream
static XStream xstream = new XStream();
+ // trace item to be stored
static TraceItem traceItem = null;
/**
- *
- * @param object
- * @param tag
+ * Write current trace with Exception information
+ * @param crashedException
*/
public static void writeTrace(Exception crashedException) {
FileWriter fw;
@@ -40,9 +42,8 @@
}
/**
- *
- * @param object
- * @param tag
+ * Read tracefile and fill traceItem
+ *
*/
public static void readTrace() {
try {
@@ -56,9 +57,10 @@
}
/**
+ * Add object by name and object
*
+ * @param name
* @param object
- * @param tag
*/
public static void addObject(String name, Object object) {
assert (name != null);
@@ -68,12 +70,6 @@
return;
}
- // New method starts and remove all previous objects
- // in the Hashtable
- if (name.equals("this")) {
- traceItem = new TraceItem();
- }
-
// trace item should not be null
// or addObject must start the "this"
assert (traceItem != null);
@@ -81,9 +77,26 @@
String serializedXMLString = xstream.toXML(object);
traceItem.addObject(name, serializedXMLString);
+ MethodInfo mInfo = traceItem.getMethodInfo();
+
+ assert (mInfo != null);
+
+ // also for methidInfo
+ if (name.equals("this")) {
+ mInfo.setFullyQualifiedParentCLassName(object);
+ } else {
+ mInfo.addArgument(name, object);
+ }
+
return;
}
+ /**
+ * Get object by name from trace
+ *
+ * @param name
+ * @return
+ */
public static Object readObject(String name) {
if (traceItem == null) {
// let's read it from file
@@ -103,4 +116,73 @@
Object object = xstream.fromXML(serealizedString);
return object;
}
+
+ /**
+ * Set new trace and method info. This method must be called first in
+ * instrumented method
+ *
+ * @param methodName
+ */
+ public static void setNewTraceAndMethodInfo(String methodName) {
+
+ // Initialize trace item and reset MethodInfo
+ traceItem = new TraceItem(methodName);
+ }
+
+ /**
+ * Generate code from traceItem
+ *
+ * @param packageName
+ * @return
+ */
+ public static String codeGeneration(String packageName) {
+ // read trace first
+ readTrace();
+ if (traceItem == null) {
+ return "// method info is null";
+ }
+
+ MethodInfo mInfo = traceItem.getMethodInfo();
+ if (mInfo == null) {
+ return "// method info is null";
+ }
+
+ // pacakge and starting stuff
+ String generatedCode = "package " + packageName + ";\n\n";
+ generatedCode += "import junit.framework.TestCase;\n";
+ generatedCode += "import edu.mit.csail.pag.recrash.Tracer;\n\n";
+ generatedCode += "//generated by reCrash on " + new
Date() + "\n";
+ generatedCode += "public class GeneratedTest extends
TestCase {\n";
+ generatedCode += "\tpublic void testCrash() {\n";
+ generatedCode += "\t\t" +
mInfo.getFullyQualifiedParentCLassName()
+ + " thisObject = (" +
mInfo.getFullyQualifiedParentCLassName()
+ + ") Tracer.readObject(\"this\");\n\n";
+
+ // reading arguments from trace
+ for (int i = 0; i < mInfo.getNumberOfArguments(); i++) {
+ generatedCode += "\t\t" + mInfo.getArgumentType(i) + " "
+ + mInfo.getArgumentName(i) + "= ("
+ + mInfo.getArgumentType(i) +
")Tracer.readObject(\""
+ + mInfo.getArgumentName(i) + "\");\n";
+ }
+
+ // call method
+ generatedCode += "\t\tthisObject." +
mInfo.getMethodName() + "(";
+
+ // passing arguments
+ for (int i = 0; i < mInfo.getNumberOfArguments(); i++) {
+ if (i != 0) {
+ generatedCode += ",";
+ }
+
+ generatedCode += mInfo.getArgumentName(i);
+ }
+ // closing method call
+ generatedCode += ");\n";
+
+ // closing method and class
+ generatedCode += "\t}\n}\n";
+
+ return generatedCode;
+ }
}
Added: trunk/reCrash/src/edu/mit/csail/pag/recrash/generator/CrashGenerator.java
===================================================================
--- trunk/reCrash/src/edu/mit/csail/pag/recrash/generator/CrashGenerator.java
(rev 0)
+++ trunk/reCrash/src/edu/mit/csail/pag/recrash/generator/CrashGenerator.java
2007-07-06 04:37:49 UTC (rev 7)
@@ -0,0 +1,18 @@
+package edu.mit.csail.pag.recrash.generator;
+
+import edu.mit.csail.pag.recrash.Tracer;
+
+/**
+ * Generating code fromTracer
+ *
+ * TODO: need to write the output to the file
+ *
+ * @author hunkim
+ *
+ */
+public class CrashGenerator {
+ static public void main(String args[]) {
+ System.out.println(Tracer
+
.codeGeneration("edu.mit.csail.pag.recrash.toy"));
+ }
+}
Modified: trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/CrashExampleInstrumented.java
===================================================================
--- trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/CrashExampleInstrumented.java
2007-07-05 20:29:57 UTC (rev 6)
+++ trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/CrashExampleInstrumented.java
2007-07-06 04:37:49 UTC (rev 7)
@@ -9,11 +9,17 @@
this.name = name;
}
- int abs(Integer i) {
- // TODO: how can I get signature of this function and
save it to?
+ int abs(Integer i, String x) {
+ // TODO: how can I get this information automatically?
+ // From BCEL??
+ // This must be run first, before adding any object
+ Tracer
+ .setNewTraceAndMethodInfo("abs");
+
// instrumentation
Tracer.addObject("this", this);
Tracer.addObject("i", i);
+ Tracer.addObject("x", x);
Integer ret = null;
if (i < 0) {
@@ -29,9 +35,9 @@
CrashExampleInstrumented crash = new
CrashExampleInstrumented("test");
- crash.abs(1);
- crash.abs(-1);
- crash.abs(0);
+ crash.abs(1, "a");
+ crash.abs(-1, "b");
+ crash.abs(0, "c");
}
// added new main
Copied: trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/GeneratedTest.java
(from rev 6, trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/RePlayCrashExample.java)
===================================================================
--- trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/GeneratedTest.java
(rev 0)
+++ trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/GeneratedTest.java
2007-07-06 04:37:49 UTC (rev 7)
@@ -0,0 +1,15 @@
+package edu.mit.csail.pag.recrash.toy;
+
+import junit.framework.TestCase;
+import edu.mit.csail.pag.recrash.Tracer;
+
+//generated by reCrash on Fri Jul 06 00:33:05 EDT 2007
+public class GeneratedTest extends TestCase {
+ public void testCrash() {
+ edu.mit.csail.pag.recrash.toy.CrashExampleInstrumented
thisObject = (edu.mit.csail.pag.recrash.toy.CrashExampleInstrumented)
Tracer.readObject("this");
+
+ java.lang.Integer i= (java.lang.Integer)Tracer.readObject("i");
+ java.lang.String x= (java.lang.String)Tracer.readObject("x");
+ thisObject.abs(i,x);
+ }
+}
Deleted: trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/RePlayCrashExample.java
===================================================================
--- trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/RePlayCrashExample.java
2007-07-05 20:29:57 UTC (rev 6)
+++ trunk/reCrash/src/edu/mit/csail/pag/recrash/toy/RePlayCrashExample.java
2007-07-06 04:37:49 UTC (rev 7)
@@ -1,12 +0,0 @@
-package edu.mit.csail.pag.recrash.toy;
-
-import edu.mit.csail.pag.recrash.Tracer;
-import junit.framework.TestCase;
-
-public class RePlayCrashExample extends TestCase {
- public void testCrash() {
- CrashExampleInstrumented crash =
(CrashExampleInstrumented) Tracer.readObject("this");
- Integer arg1 = (Integer) Tracer.readObject("i");
- crash.abs(arg1);
- }
-}