33import java .io .File ;
44import java .io .FileInputStream ;
55import java .io .FileOutputStream ;
6- import java .io .FileWriter ;
76import java .io .IOException ;
87import java .io .PrintWriter ;
98import java .lang .instrument .ClassFileTransformer ;
1312import java .util .Scanner ;
1413
1514import org .objectweb .asm .ClassReader ;
15+ import org .objectweb .asm .ClassVisitor ;
1616import org .objectweb .asm .ClassWriter ;
17+ import org .objectweb .asm .MethodVisitor ;
1718import org .objectweb .asm .Opcodes ;
19+ import org .objectweb .asm .commons .JSRInlinerAdapter ;
1820import org .objectweb .asm .commons .SerialVersionUIDAdder ;
21+ import org .objectweb .asm .tree .ClassNode ;
1922import org .objectweb .asm .util .CheckClassAdapter ;
2023import org .objectweb .asm .util .TraceClassVisitor ;
2124
2629
2730public class PreMain {
2831 static boolean replay ;
32+ private static final class HackyClassWriter extends ClassWriter {
2933
34+ private HackyClassWriter (ClassReader classReader , int flags ) {
35+ super (classReader , flags );
36+ }
37+
38+ protected String getCommonSuperClass (String type1 , String type2 ) {
39+ return "java/lang/Object" ;
40+ }
41+ }
3042 static class ChroniclerTransformer implements ClassFileTransformer {
3143 @ Override
3244 public byte [] transform (ClassLoader loader , String className , Class <?> classBeingRedefined , ProtectionDomain protectionDomain , byte [] classfileBuffer ) throws IllegalClassFormatException {
@@ -54,15 +66,35 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
5466 return null ;
5567 }
5668 } else {
57- try {
58- ClassReader cr = new ClassReader (classfileBuffer );
59- if (isIgnoredClass (cr .getClassName ()))
60- return null ;
61- if (DEBUG )
62- System .out .println ("Inst: " + cr .getClassName ());
69+ ClassReader cr = new ClassReader (classfileBuffer );
70+ if (isIgnoredClass (cr .getClassName ()))
71+ return null ;
72+ if (DEBUG )
73+ System .out .println ("Inst: " + cr .getClassName ());
74+
75+ boolean skipFrames = false ;
76+ ClassNode cn = new ClassNode ();
77+ cr .accept (cn , ClassReader .SKIP_CODE );
78+ if (cn .version >= 100 || cn .version <= 50 || className .endsWith ("$Access4JacksonSerializer" ) || className .endsWith ("$Access4JacksonDeSerializer" ))
79+ skipFrames = true ;
80+
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+ ClassWriter cw = new HackyClassWriter (cr , ClassWriter .COMPUTE_MAXS | ClassWriter .COMPUTE_FRAMES );
85+ cr .accept (new ClassVisitor (Opcodes .ASM5 , cw ) {
86+ @ Override
87+ public MethodVisitor visitMethod (int access , String name , String desc , String signature , String [] exceptions ) {
88+ return new JSRInlinerAdapter (super .visitMethod (access , name , desc , signature , exceptions ), access , name , desc , signature , exceptions );
89+ }
90+ }, 0 );
91+ cr = new ClassReader (cw .toByteArray ());
92+ }
93+
94+ try {
6395 ClassWriter cw = new ClassWriter (ClassWriter .COMPUTE_MAXS );
64- NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor (new SerialVersionUIDAdder (cw ));
65- CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor (cv );
96+ NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor (new SerialVersionUIDAdder (cw ), skipFrames );
97+ CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor (cv , skipFrames );
6698
6799 cr .accept (callbackDuplicator , ClassReader .EXPAND_FRAMES );
68100 if (DEBUG ) {
@@ -89,11 +121,10 @@ public byte[] transform(ClassLoader loader, String className, Class<?> classBein
89121 fos .write (classfileBuffer );
90122 fos .close ();
91123 fw = new PrintWriter ("lastClass.txt" );
92- ClassReader cr = new ClassReader (classfileBuffer );
93-
124+
94125 tcv = new TraceClassVisitor (fw );
95- NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor (new SerialVersionUIDAdder (tcv ));
96- CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor (cv );
126+ NonDeterministicLoggingClassVisitor cv = new NonDeterministicLoggingClassVisitor (new SerialVersionUIDAdder (tcv ), skipFrames );
127+ CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor (cv , skipFrames );
97128
98129 cr .accept (callbackDuplicator , ClassReader .EXPAND_FRAMES );
99130
@@ -154,20 +185,20 @@ else if (d[0].equals("failsafe")) {
154185 String testClass = null ;
155186 while (s .hasNextLine ()) {
156187 String line = s .nextLine ();
157- if (line .startsWith ("tc. " )) {
158- testClass = line .split ( "=" )[ 1 ] ;
188+ if (line .startsWith ("forkTestSet=java.lang.Class| " )) {
189+ testClass = line .substring ( "forkTestSet=java.lang.Class|" . length ()) ;
159190 break ;
160191 }
161192 }
162193 s .close ();
163194 if (testClass == null )
164195 throw new IOException ("Couldn't find test config" );
165196 if (replay ) {
166- ChroniclerJExportRunner .nameOverride = "target/" +testClass + ".crash" ;
197+ ChroniclerJExportRunner .nameOverride = "target/replays/ " +testClass + ".crash" ;
167198 ReplayRunner .setupLogs (new String []{ChroniclerJExportRunner .nameOverride });
168199 } else {
169200 System .out .println ("Overriding test class: " + testClass );
170- ChroniclerJExportRunner .nameOverride = "target/" +testClass + ".crash" ;
201+ ChroniclerJExportRunner .nameOverride = "target/replays/ " +testClass + ".crash" ;
171202 }
172203 } catch (IOException ex ) {
173204 ex .printStackTrace ();
0 commit comments