Skip to content

Commit cbc70e3

Browse files
committed
java agent, refactor log and replay code into lib instead of inline...
1 parent 19d75bd commit cbc70e3

9 files changed

Lines changed: 363 additions & 38 deletions

File tree

Code/ChroniclerJ/pom.xml

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,32 @@
3535
<goal>shade</goal>
3636
</goals>
3737
<configuration>
38-
<!-- <relocations> <relocation> <pattern>org.apache.commons.cli</pattern>
39-
<shadedPattern>edu.columbia.cs.psl.phosphor.org.apache.commons.cli</shadedPattern>
40-
</relocation> <relocation> <pattern>org.objectweb.asm</pattern> <shadedPattern>edu.columbia.cs.psl.phosphor.org.objectweb.asm</shadedPattern>
41-
</relocation> </relocations> -->
38+
<relocations>
39+
<relocation>
40+
<pattern>org.objectweb</pattern>
41+
<shadedPattern>edu.columbia.cs.psl.chroniclerj.org.objectweb</shadedPattern>
42+
</relocation>
43+
<!-- <relocation>
44+
<pattern>org.kxml2</pattern>
45+
<shadedPattern>edu.columbia.cs.psl.chroniclerj.org.kxml</shadedPattern>
46+
</relocation> -->
47+
<relocation>
48+
<pattern>org.objenesis</pattern>
49+
<shadedPattern>edu.columbia.cs.psl.chroniclerj.org.objenesis</shadedPattern>
50+
</relocation>
51+
<!-- <relocation>
52+
<pattern>org.xmlpull</pattern>
53+
<shadedPattern>edu.columbia.cs.psl.chroniclerj.org.xmlpull</shadedPattern>
54+
</relocation>
55+
<relocation>
56+
<pattern>com.thoughtworks</pattern>
57+
<shadedPattern>edu.columbia.cs.psl.chroniclerj.com.thoughtworks</shadedPattern>
58+
</relocation> -->
59+
<relocation>
60+
<pattern>org.apache.log4j</pattern>
61+
<shadedPattern>edu.columbia.cs.psl.chroniclerj.org.apache.log4j</shadedPattern>
62+
</relocation>
63+
</relocations>
4264
<minimizeJar>false</minimizeJar>
4365
</configuration>
4466
</execution>
@@ -56,7 +78,7 @@
5678
<includes>
5779
<include>**/*ITCase.java</include>
5880
</includes>
59-
<!-- <argLine>-Xbootclasspath/p:${project.build.directory}/${project.build.finalName}.jar
81+
<!-- <argLine>-Xbootclasspath/p:${project.build.directory}/${project.build.finalName}.jar
6082
-javaagent:${project.build.directory}/${project.build.finalName}.jar=enum,acmpeq,cacheDir=${project.build.directory}/cached-int-untaged,withSelectiveInst=${basedir}/resources/test-methods</argLine> -->
6183
</configuration>
6284
<goals>
@@ -67,13 +89,6 @@
6789
</executions>
6890
<configuration>
6991
</configuration>
70-
<dependencies>
71-
<dependency>
72-
<artifactId>surefire-outputcomparison</artifactId>
73-
<groupId>net.jonbell.surefire</groupId>
74-
<version>2.19</version>
75-
</dependency>
76-
</dependencies>
7792
</plugin>
7893
<plugin>
7994
<groupId>org.apache.maven.plugins</groupId>
@@ -91,11 +106,6 @@
91106
</build>
92107

93108
<dependencies>
94-
<dependency>
95-
<artifactId>surefire-outputcomparison</artifactId>
96-
<groupId>net.jonbell.surefire</groupId>
97-
<version>2.19</version>
98-
</dependency>
99109
<dependency>
100110
<groupId>junit</groupId>
101111
<artifactId>junit</artifactId>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Manifest-Version: 1.0
22
Created-By: 1.6.0_06 (Sun Microsystems Inc.)
33
Main-Class: edu.columbia.cs.psl.chroniclerj.Main
4+
Premain-Class: edu.columbia.cs.psl.chroniclerj.PreMain
45

Code/ChroniclerJ/src/main/java/edu/columbia/cs/psl/chroniclerj/ChroniclerJExportRunner.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public static void logMain(String main, String[] args) {
3535
System.arraycopy(args, 0, mainArgs, 0, args.length);
3636
}
3737

38+
public static String nameOverride;
39+
3840
public static void genTestCase()
3941
{
4042
genTestCase("chroniclerj-crash-" + System.currentTimeMillis() + ".test");
@@ -43,9 +45,10 @@ public static void genTestCase(String name) {
4345
export();
4446
exportSerializable();
4547
try {
46-
47-
File logFile = new File(name);
48-
48+
hasLoggedError = true;
49+
File logFile = new File((nameOverride == null ? name : nameOverride));
50+
if(logFile.exists())
51+
logFile.delete();
4952
Manifest manifest = new Manifest();
5053
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
5154
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS,
@@ -299,5 +302,19 @@ public static void _export() {
299302
inst.interrupt();
300303
}
301304
}
305+
private static boolean hasLoggedError = false;
306+
private static boolean hasRegisteredHook = false;
307+
308+
public static void registerShutdownHook() {
309+
if(!hasRegisteredHook){
310+
hasRegisteredHook = true;
311+
Runtime.getRuntime().addShutdownHook(new Thread(){
312+
public void run(){
313+
if(!hasLoggedError)
314+
ChroniclerJExportRunner.genTestCase();
315+
}
316+
});
317+
}
318+
}
302319

303320
}

Code/ChroniclerJ/src/main/java/edu/columbia/cs/psl/chroniclerj/Log.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,4 @@ public static void log(long toLog, String debug) {
304304
Log.logLock.unlock();
305305
}
306306
}
307-
308-
// private static boolean hasRegisteredHook = false;
309-
// static {
310-
// if(!hasRegisteredHook){
311-
// hasRegisteredHook = true;
312-
// Runtime.getRuntime().addShutdownHook(new Thread(){
313-
// public void run(){
314-
// ChroniclerJExportRunner.genTestCase();
315-
// }
316-
// });
317-
// }
318-
// }
319307
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package edu.columbia.cs.psl.chroniclerj;
2+
3+
import java.lang.instrument.ClassFileTransformer;
4+
import java.lang.instrument.IllegalClassFormatException;
5+
import java.lang.instrument.Instrumentation;
6+
import java.security.ProtectionDomain;
7+
8+
import org.objectweb.asm.ClassReader;
9+
import org.objectweb.asm.ClassWriter;
10+
import org.objectweb.asm.Opcodes;
11+
import org.objectweb.asm.commons.SerialVersionUIDAdder;
12+
13+
import edu.columbia.cs.psl.chroniclerj.replay.NonDeterministicReplayClassVisitor;
14+
import edu.columbia.cs.psl.chroniclerj.visitor.CallbackDuplicatingClassVisitor;
15+
import edu.columbia.cs.psl.chroniclerj.visitor.NonDeterministicLoggingClassVisitor;
16+
17+
public class PreMain {
18+
public static boolean isIgnoredClass(String className) {
19+
return className.startsWith("java") || className.startsWith("com/sun") || className.startsWith("sun/") || className.startsWith("edu/columbia/cs/psl/chroniclerj") || className.startsWith("com/rits/cloning") || className.startsWith("jdk")
20+
||className.startsWith("com/thoughtworks") || className.startsWith("org/xmlpull")
21+
|| className.startsWith("org/kxml2");
22+
}
23+
24+
public static void premain(String _args, Instrumentation inst) {
25+
final boolean replay = _args != null && _args.equals("replay");
26+
if(_args != null)
27+
{
28+
String[] args = _args.split(",");
29+
for(String arg : args)
30+
{
31+
String[] d = arg.split("=");
32+
if(d[0].equals("logFile"))
33+
{
34+
ChroniclerJExportRunner.nameOverride = d[1];
35+
}
36+
else if(d[0].equals("alwaysExport"))
37+
{
38+
ChroniclerJExportRunner.registerShutdownHook();
39+
}
40+
}
41+
}
42+
ClassFileTransformer transformer = new ClassFileTransformer() {
43+
44+
@Override
45+
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
46+
if (replay) {
47+
ClassReader cr = new ClassReader(classfileBuffer);
48+
if (isIgnoredClass(cr.getClassName()))
49+
return null;
50+
System.out.println("Inst: " + cr.getClassName());
51+
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
52+
NonDeterministicReplayClassVisitor cv = new NonDeterministicReplayClassVisitor(Opcodes.ASM5, cw);
53+
cr.accept(cv, ClassReader.EXPAND_FRAMES);
54+
return cw.toByteArray();
55+
} else {
56+
try {
57+
ClassReader cr = new ClassReader(classfileBuffer);
58+
if (isIgnoredClass(cr.getClassName()))
59+
return null;
60+
System.out.println("Inst: " + cr.getClassName());
61+
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
62+
NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(new SerialVersionUIDAdder(cw));
63+
CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor(cv);
64+
65+
cr.accept(callbackDuplicator, ClassReader.EXPAND_FRAMES);
66+
return cw.toByteArray();
67+
} catch (Throwable t) {
68+
t.printStackTrace();
69+
return null;
70+
}
71+
}
72+
}
73+
};
74+
inst.addTransformer(transformer);
75+
76+
}
77+
}

Code/ChroniclerJ/src/main/java/edu/columbia/cs/psl/chroniclerj/replay/ReplayUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,20 @@ public static char getNextC() {
208208
Log.logLock.unlock();
209209
}
210210
}
211+
public static double getNextD() {
212+
Log.logLock.lock();
213+
try {
214+
int idx = ReplayUtils.getNextIndex(ExportedSerializableLog.dLog_replayIndex, ExportedSerializableLog.dLog_owners, ExportedSerializableLog.dLog_fill);
215+
while (idx < 0) {
216+
ReplayRunner.loadNextLog("edu/columbia/cs/psl/chroniclerj/ExportedSerializableLog");
217+
idx = ReplayUtils.getNextIndex(ExportedSerializableLog.dLog_replayIndex, ExportedSerializableLog.dLog_owners, ExportedSerializableLog.dLog_fill);
218+
}
219+
ExportedLog.globalReplayIndex++;
220+
return ExportedSerializableLog.dLog[idx];
221+
} finally {
222+
Log.logLock.unlock();
223+
}
224+
}
211225

212226

213227
public static void copyInto(Object dest, Object src, int len)

0 commit comments

Comments
 (0)