Skip to content

Commit 9919c9b

Browse files
committed
Clean up frame generation, static inst, and debug output
1 parent 3af1241 commit 9919c9b

6 files changed

Lines changed: 84 additions & 101 deletions

File tree

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

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.objectweb.asm.commons.SerialVersionUIDAdder;
2727
import org.objectweb.asm.util.CheckClassAdapter;
2828

29+
import edu.columbia.cs.psl.chroniclerj.PreMain.ChroniclerTransformer;
2930
import edu.columbia.cs.psl.chroniclerj.visitor.CallbackDuplicatingClassVisitor;
3031
import edu.columbia.cs.psl.chroniclerj.visitor.NonDeterministicLoggingClassVisitor;
3132

@@ -65,34 +66,25 @@ private static void finishedPass() {
6566
}
6667
}
6768

69+
static ChroniclerTransformer transformer = new ChroniclerTransformer();
70+
6871
private static byte[] instrumentClass(InputStream is) {
6972
try {
70-
ClassReader cr = new ClassReader(is);
71-
{
72-
ClassWriter cw = new ClassWriter(cr, 0);
73-
SerialVersionUIDAdder uidAdder = new SerialVersionUIDAdder(cw);
74-
cr.accept(uidAdder, 0);
75-
byte[] b = cw.toByteArray();
76-
cr = new ClassReader(b);
77-
is.close();
78-
}
79-
80-
ClassWriter cw = new InstrumenterClassWriter(cr, ClassWriter.COMPUTE_MAXS
81-
| ClassWriter.COMPUTE_FRAMES, loader);
82-
NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(cw, false);
83-
CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor(cv, false);
84-
85-
cr.accept(callbackDuplicator, ClassReader.EXPAND_FRAMES);
86-
lastInstrumentedClass = cv.getClassName();
87-
byte[] out = cw.toByteArray();
88-
try {
89-
ClassReader cr2 = new ClassReader(out);
90-
cr2.accept(new CheckClassAdapter(new ClassWriter(0)), ClassReader.EXPAND_FRAMES);
91-
} catch (Exception ex) {
92-
System.err.println(lastInstrumentedClass);
93-
ex.printStackTrace();
94-
}
95-
return out;
73+
ClassReader cr = new ClassReader(is);
74+
ClassWriter cw = new ClassWriter(cr, 0);
75+
SerialVersionUIDAdder uidAdder = new SerialVersionUIDAdder(cw);
76+
cr.accept(uidAdder, 0);
77+
byte[] b = cw.toByteArray();
78+
is.close();
79+
PreMain.replay = false;
80+
lastInstrumentedClass = cr.getClassName();
81+
b = transformer.transform(null, null, null, null, b);
82+
if(b==null)
83+
{
84+
System.err.println("on " + lastInstrumentedClass);
85+
System.exit(-1);
86+
}
87+
return b;
9688
} catch (Exception ex) {
9789
logger.error("Exception processing class: " + lastInstrumentedClass, ex);
9890
ex.printStackTrace();

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

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
import edu.columbia.cs.psl.chroniclerj.visitor.NonDeterministicLoggingClassVisitor;
2929

3030
public class PreMain {
31-
static boolean replay;
31+
public static boolean replay;
32+
3233
private static final class HackyClassWriter extends ClassWriter {
3334

3435
private HackyClassWriter(ClassReader classReader, int flags) {
@@ -39,6 +40,7 @@ protected String getCommonSuperClass(String type1, String type2) {
3940
return "java/lang/Object";
4041
}
4142
}
43+
4244
static class ChroniclerTransformer implements ClassFileTransformer {
4345
@Override
4446
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
@@ -67,20 +69,22 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
6769
}
6870
} else {
6971
ClassReader cr = new ClassReader(classfileBuffer);
72+
className = cr.getClassName();
7073
if (isIgnoredClass(cr.getClassName()))
7174
return null;
7275
if (DEBUG)
7376
System.out.println("Inst: " + cr.getClassName());
74-
77+
7578
boolean skipFrames = false;
76-
ClassNode cn = new ClassNode();
79+
ClassNode cn = new ClassNode();
7780
cr.accept(cn, ClassReader.SKIP_CODE);
7881
if (cn.version >= 100 || cn.version <= 50 || className.endsWith("$Access4JacksonSerializer") || className.endsWith("$Access4JacksonDeSerializer"))
7982
skipFrames = true;
8083

81-
if(skipFrames)
82-
{
83-
//This class is old enough to not guarantee frames. Generate new frames for analysis reasons, then make sure to not emit ANY frames.
84+
if (skipFrames) {
85+
// This class is old enough to not guarantee frames.
86+
// Generate new frames for analysis reasons, then make sure
87+
// to not emit ANY frames.
8488
ClassWriter cw = new HackyClassWriter(cr, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
8589
cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {
8690
@Override
@@ -90,11 +94,11 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
9094
}, 0);
9195
cr = new ClassReader(cw.toByteArray());
9296
}
93-
94-
try {
97+
98+
try {
9599
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
96-
NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(new SerialVersionUIDAdder(cw), skipFrames);
97-
CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor(cv, skipFrames);
100+
NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(new SerialVersionUIDAdder(cw));
101+
CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor(cv);
98102

99103
cr.accept(callbackDuplicator, ClassReader.EXPAND_FRAMES);
100104
if (DEBUG) {
@@ -110,31 +114,33 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
110114
return cw.toByteArray();
111115
} catch (Throwable t) {
112116
t.printStackTrace();
113-
if (DEBUG) {
114-
TraceClassVisitor tcv = null;
115-
PrintWriter fw = null;
116-
try {
117-
File f = new File("z.class");
117+
118+
TraceClassVisitor tcv = null;
119+
PrintWriter fw = null;
120+
try {
121+
File f = new File("z.class");
122+
if(f.getParentFile() != null)
118123
f.getParentFile().mkdirs();
119-
f.delete();
120-
FileOutputStream fos = new FileOutputStream(f);
121-
fos.write(classfileBuffer);
122-
fos.close();
123-
fw = new PrintWriter("lastClass.txt");
124-
125-
tcv = new TraceClassVisitor(fw);
126-
NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(new SerialVersionUIDAdder(tcv), skipFrames);
127-
CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor(cv, skipFrames);
128-
129-
cr.accept(callbackDuplicator, ClassReader.EXPAND_FRAMES);
130-
131-
} catch (Throwable t2) {
132-
t2.printStackTrace();
133-
} finally {
134-
tcv.visitEnd();
135-
fw.close();
136-
}
124+
f.delete();
125+
FileOutputStream fos = new FileOutputStream(f);
126+
fos.write(classfileBuffer);
127+
fos.close();
128+
fw = new PrintWriter("lastClass.txt");
129+
130+
tcv = new TraceClassVisitor(fw);
131+
NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor(new SerialVersionUIDAdder(tcv));
132+
CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor(cv);
133+
134+
cr.accept(callbackDuplicator, ClassReader.EXPAND_FRAMES);
135+
136+
} catch (Throwable t2) {
137+
t2.printStackTrace();
138+
} finally {
139+
if(tcv != null)
140+
tcv.visitEnd();
141+
fw.close();
137142
}
143+
138144
return null;
139145
}
140146
}
@@ -154,27 +160,25 @@ public static boolean isIgnoredClass(String className) {
154160

155161
static boolean DEBUG = false;
156162
static String[] whiteList;
157-
163+
158164
public static void premain(String _args, Instrumentation inst) {
159165
if (_args != null) {
160166
String[] args = _args.split(",");
161167
for (String arg : args) {
162168
String[] d = arg.split("=");
163-
if(d[0].equals("replay"))
164-
{
169+
if (d[0].equals("replay")) {
165170
replay = true;
166171
if (ChroniclerJExportRunner.nameOverride != null)
167172
ReplayRunner.setupLogs(new String[] { ChroniclerJExportRunner.nameOverride });
168-
}
169-
else if (d[0].equals("logFile")) {
173+
} else if (d[0].equals("logFile")) {
170174
ChroniclerJExportRunner.nameOverride = d[1];
171-
if(replay)
175+
if (replay)
172176
ReplayRunner.setupLogs(new String[] { ChroniclerJExportRunner.nameOverride });
173177
} else if (d[0].equals("alwaysExport")) {
174178
ChroniclerJExportRunner.registerShutdownHook();
175179
} else if (d[0].equals("debug"))
176180
DEBUG = true;
177-
else if(d[0].equals("quiet"))
181+
else if (d[0].equals("quiet"))
178182
ChroniclerJExportRunner.QUIET = true;
179183
else if (d[0].equals("failsafe")) {
180184
try {
@@ -194,19 +198,17 @@ else if (d[0].equals("failsafe")) {
194198
if (testClass == null)
195199
throw new IOException("Couldn't find test config");
196200
if (replay) {
197-
ChroniclerJExportRunner.nameOverride = "target/replays/"+testClass + ".crash";
198-
ReplayRunner.setupLogs(new String[]{ChroniclerJExportRunner.nameOverride});
201+
ChroniclerJExportRunner.nameOverride = "target/replays/" + testClass + ".crash";
202+
ReplayRunner.setupLogs(new String[] { ChroniclerJExportRunner.nameOverride });
199203
} else {
200204
System.out.println("Overriding test class: " + testClass);
201-
ChroniclerJExportRunner.nameOverride = "target/replays/"+testClass + ".crash";
205+
ChroniclerJExportRunner.nameOverride = "target/replays/" + testClass + ".crash";
202206
}
203207
} catch (IOException ex) {
204208
ex.printStackTrace();
205209
System.err.println("Unable to load in failsafe config");
206210
}
207-
}
208-
else if(d[0].equals("whitelist"))
209-
{
211+
} else if (d[0].equals("whitelist")) {
210212
whiteList = d[1].split(";");
211213
}
212214
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,8 @@ public void visit(int version, int access, String name, String signature, String
3737
this.interfaces = interfaces;
3838
}
3939

40-
private boolean skipFrames;
41-
public CallbackDuplicatingClassVisitor(ClassVisitor cv, boolean skipFrames) {
40+
public CallbackDuplicatingClassVisitor(ClassVisitor cv) {
4241
super(Opcodes.ASM5, cv);
43-
this.skipFrames = skipFrames;
4442
}
4543

4644
private HashSet<MethodNode> methodsToGenerateLogging = new HashSet<MethodNode>();
@@ -63,7 +61,7 @@ public void visitEnd() {
6361
(String[]) mn.exceptions.toArray(new String[0]));
6462
AnalyzerAdapter analyzer = new AnalyzerAdapter(className, mn.access, mn.name, mn.desc, mv);
6563
CloningAdviceAdapter caa = new CloningAdviceAdapter(analyzer, mn.access,
66-
mn.name, mn.desc, className, skipFrames, analyzer);
64+
mn.name, mn.desc, className, analyzer);
6765
LocalVariablesSorter lvsorter = new LocalVariablesSorter(mn.access, mn.desc, mv);
6866
CallbackLoggingMethodVisitor clmv = new CallbackLoggingMethodVisitor(mv,
6967
mn.access, mn.name, mn.desc, className, lvsorter, caa, superName, interfaces);

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

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,10 @@ public class CloningAdviceAdapter extends InstructionAdapter implements Opcodes
6161
}
6262

6363
private LocalVariablesSorter lvsorter;
64-
private boolean skipFrames;
6564
private AnalyzerAdapter analyzer;
6665
public CloningAdviceAdapter(MethodVisitor mv, int access, String name, String desc,
67-
String classname, boolean skipFrames, AnalyzerAdapter analyzer) {
66+
String classname, AnalyzerAdapter analyzer) {
6867
super(Opcodes.ASM5, mv);
69-
this.skipFrames = skipFrames;
7068
this.analyzer = analyzer;
7169
}
7270

@@ -151,18 +149,16 @@ private void _generateClone(String typeOfField, String copyMethodToCall, String
151149

152150
visitJumpInsn(GOTO, noNeedToPop);
153151
visitLabel(nullContinue);
154-
if(!skipFrames)
155-
fn.accept(mv);
152+
fn.accept(mv);
156153
swap();
157154
pop();
158155
} else {
159156
visitLabel(nullContinue);
160-
if(!skipFrames)
161-
fn.accept(mv);
157+
fn.accept(mv);
162158
}
163159

164160
visitLabel(noNeedToPop);
165-
if(!skipFrames && fn2 != null)
161+
if(fn2 != null)
166162
fn2.accept(mv);
167163

168164
} else {

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

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements
2828
private String className;
2929
private String superName;
3030
private String[] interfaces;
31-
32-
private boolean skipFrames;
3331

3432
private boolean isAClass = true;
3533

@@ -51,9 +49,8 @@ public class NonDeterministicLoggingClassVisitor extends ClassVisitor implements
5149
}
5250
}
5351

54-
public NonDeterministicLoggingClassVisitor(ClassVisitor cv, boolean skipFrames) {
52+
public NonDeterministicLoggingClassVisitor(ClassVisitor cv) {
5553
super(Opcodes.ASM5, cv);
56-
this.skipFrames = skipFrames;
5754

5855
}
5956

@@ -90,7 +87,7 @@ public MethodVisitor visitMethod(int acc, String name, String desc, String signa
9087
// JSRInlinerAdapter mv = new JSRInlinerAdapter(analyzer, acc, name, desc, signature,
9188
// exceptions);
9289
AnalyzerAdapter analyzer = new AnalyzerAdapter(className, acc, name, desc, smv);
93-
CloningAdviceAdapter caa = new CloningAdviceAdapter(analyzer, acc, name, desc, className, skipFrames, analyzer);
90+
CloningAdviceAdapter caa = new CloningAdviceAdapter(analyzer, acc, name, desc, className, analyzer);
9491
smv = new CallbackLoggingMethodVisitor(caa, acc, name, desc, className,
9592
null, caa, superName, interfaces);
9693
smv = new JSRInlinerAdapter(smv, acc, name, desc, signature, exceptions);
@@ -109,7 +106,7 @@ public MethodVisitor visitMethod(int acc, String name, String desc, String signa
109106
// analyzer);
110107
AnalyzerAdapter analyzer = new AnalyzerAdapter(className, acc, name, desc, smv);
111108
NonDeterministicLoggingMethodVisitor cloningMV = new NonDeterministicLoggingMethodVisitor(
112-
analyzer, acc, name, desc, className, superName, isFirstConstructor, skipFrames, analyzer);
109+
analyzer, acc, name, desc, className, superName, isFirstConstructor, analyzer);
113110
if (name.equals("<init>"))
114111
isFirstConstructor = false;
115112
cloningMV.setClassVisitor(this);
@@ -161,7 +158,7 @@ else if (mi.getOpcode() != Opcodes.INVOKESTATIC) {
161158
captureDesc, null, null);
162159
AnalyzerAdapter analyzer = new AnalyzerAdapter(className, opcode, mc.getCapturePrefix()+"_capture", captureDesc, mv);
163160
CloningAdviceAdapter caa = new CloningAdviceAdapter(analyzer, opcode,
164-
mc.getCapturePrefix() + "_capture", captureDesc, className, skipFrames, analyzer);
161+
mc.getCapturePrefix() + "_capture", captureDesc, className, analyzer);
165162
LocalVariablesSorter lvs = new LocalVariablesSorter(opcode, captureDesc, caa);
166163
caa.setLocalVariableSorter(lvs);
167164
Type[] args = Type.getArgumentTypes(captureDesc);
@@ -199,14 +196,12 @@ else if (mi.getOpcode() != Opcodes.INVOKESTATIC) {
199196
caa.visitJumpInsn(Opcodes.IFLT, isNegative);
200197
caa.dup();
201198
FrameNode fn2 = CloningAdviceAdapter.getCurrentFrameNode(analyzer);
202-
caa.visitJumpInsn(Opcodes.GOTO, notNegative);
203-
caa.visitLabel(isNegative);
204-
if(!skipFrames)
205-
fn.accept(caa);
206-
caa.visitInsn(ICONST_0);
207-
caa.visitLabel(notNegative);
208-
if(!skipFrames)
209-
fn2.accept(caa);
199+
caa.visitJumpInsn(Opcodes.GOTO, notNegative);
200+
caa.visitLabel(isNegative);
201+
fn.accept(caa);
202+
caa.visitInsn(ICONST_0);
203+
caa.visitLabel(notNegative);
204+
fn2.accept(caa);
210205

211206
}
212207
caa.visitVarInsn(args[i].getOpcode(ILOAD), j);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ public void visitCode() {
8181
private boolean isFirstConstructor;
8282

8383
protected NonDeterministicLoggingMethodVisitor(MethodVisitor mv, int access,
84-
String name, String desc, String className, String superName, boolean isFirstConstructor, boolean skipFrames, AnalyzerAdapter analyzer) {
85-
super(mv, access, name, desc, className, skipFrames, analyzer);
84+
String name, String desc, String className, String superName, boolean isFirstConstructor, AnalyzerAdapter analyzer) {
85+
super(mv, access, name, desc, className, analyzer);
8686
this.name = name;
8787
this.desc = desc;
8888
this.className = className;

0 commit comments

Comments
 (0)