1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package art;
18 
19 import java.util.Base64;
20 public class Test1989 {
21 
22   static class Transform {
sayHi(Object l_first, Object l_second)23     public void sayHi(Object l_first, Object l_second) {
24       System.out.println("hello without locks");
25     }
26   }
27 
28   /**
29    * base64 encoded class/dex file for
30    * class Transform {
31    *   public void sayHi(Object l_first, Object l_second) {
32    *    monitor-enter l_first
33    *    monitor-enter l_second
34    *    System.out.println("Goodbye before unlock");
35    *    monitor-exit l_second
36    *    System.out.println("Goodbye after unlock");
37    *   }
38    * }
39    */
40   private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
41 "yv66vgADAC0AHgEAFEdvb2RieWUgYWZ0ZXIgdW5sb2NrDAAYAB0BABBqYXZhL2xhbmcvT2JqZWN0" +
42 "AQAGPGluaXQ+BwADDAAEAAkHABEBABZhcnQvVGVzdDE5ODkkVHJhbnNmb3JtAQADKClWBwAVAQAE" +
43 "Q29kZQgAHAkACgACAQANVGVzdDE5ODkuamF2YQEAClNvdXJjZUZpbGUMABIAGwEAE2phdmEvaW8v" +
44 "UHJpbnRTdHJlYW0BAAdwcmludGxuCgAFAAYBAAVzYXlIaQEAEGphdmEvbGFuZy9TeXN0ZW0IAAEK" +
45 "AAcAEAEAA291dAcACAEAJyhMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL09iamVjdDspVgEA" +
46 "FShMamF2YS9sYW5nL1N0cmluZzspVgEAFUdvb2RieWUgYmVmb3JlIHVubG9jawEAFUxqYXZhL2lv" +
47 "L1ByaW50U3RyZWFtOwAgABkABQAAAAAAAgAAAAQACQABAAsAAAARAAEAAQAAAAUqtwATsQAAAAAA" +
48 "AQAUABoAAQALAAAAIwACAAMAAAAXK8IswrIADRIMtgAXLMOyAA0SFrYAF7EAAAAAAAEADwAAAAIA" +
49 "Dg==");
50   private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
51 "ZGV4CjAzNQB5oAZwVUwJoMSgbr1BNffRcXjpPMVhYzgYBAAAcAAAAHhWNBIAAAAAAAAAAFQDAAAW" +
52 "AAAAcAAAAAkAAADIAAAAAwAAAOwAAAABAAAAEAEAAAQAAAAYAQAAAQAAADgBAADAAgAAWAEAAFgB" +
53 "AABgAQAAdgEAAI0BAACnAQAAtwEAANsBAAD7AQAAEgIAACYCAAA6AgAATgIAAF0CAABoAgAAawIA" +
54 "AG8CAAB0AgAAgQIAAIcCAACMAgAAlQIAAJwCAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" +
55 "CgAAAA0AAAANAAAACAAAAAAAAAAPAAAACAAAAKQCAAAOAAAACAAAAKwCAAAHAAQAEgAAAAAAAAAA" +
56 "AAAAAAABABQAAAAEAAIAEwAAAAUAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAsAAADYAgAARAMAAAAA" +
57 "AAAGPGluaXQ+ABRHb29kYnllIGFmdGVyIHVubG9jawAVR29vZGJ5ZSBiZWZvcmUgdW5sb2NrABhM" +
58 "YXJ0L1Rlc3QxOTg5JFRyYW5zZm9ybTsADkxhcnQvVGVzdDE5ODk7ACJMZGFsdmlrL2Fubm90YXRp" +
59 "b24vRW5jbG9zaW5nQ2xhc3M7AB5MZGFsdmlrL2Fubm90YXRpb24vSW5uZXJDbGFzczsAFUxqYXZh" +
60 "L2lvL1ByaW50U3RyZWFtOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5nL1N0cmluZzsA" +
61 "EkxqYXZhL2xhbmcvU3lzdGVtOwANVGVzdDE5ODkuamF2YQAJVHJhbnNmb3JtAAFWAAJWTAADVkxM" +
62 "AAthY2Nlc3NGbGFncwAEbmFtZQADb3V0AAdwcmludGxuAAVzYXlIaQAFdmFsdWUAAAIAAAAFAAUA" +
63 "AQAAAAYAAgMCEAQIERcMAgIBFRgBAAAAAAAAAAAAAAACAAAAuwIAALICAADMAgAAAAAAAAAAAAAA" +
64 "AAAABgAOAAgCAAAOHh54H3gAAAEAAQABAAAA6AIAAAQAAABwEAMAAAAOAAUAAwACAAAA7AIAABIA" +
65 "AAAdAx0EYgAAABoBAgBuIAIAEAAeBGIDAAAaBAEAbiACAEMADgAAAAEBAICABPgFAQGQBgAAEAAA" +
66 "AAAAAAABAAAAAAAAAAEAAAAWAAAAcAAAAAIAAAAJAAAAyAAAAAMAAAADAAAA7AAAAAQAAAABAAAA" +
67 "EAEAAAUAAAAEAAAAGAEAAAYAAAABAAAAOAEAAAIgAAAWAAAAWAEAAAEQAAACAAAApAIAAAQgAAAC" +
68 "AAAAsgIAAAMQAAADAAAAxAIAAAYgAAABAAAA2AIAAAMgAAACAAAA6AIAAAEgAAACAAAA+AIAAAAg" +
69 "AAABAAAARAMAAAAQAAABAAAAVAMAAA==");
70 
run()71   public static void run() throws Exception {
72     Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
73     doTest(new Transform());
74   }
75 
doTest(Transform t)76   public static void doTest(Transform t) throws Exception {
77     Object a = new Object();
78     Object b = new Object();
79     t.sayHi(a, b);
80     Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
81     try {
82       t.sayHi(a, b);
83     } catch (Throwable e) {
84       System.out.println("Got exception of type " + e.getClass());
85     }
86     System.out.println("Make sure locks aren't held");
87     Thread thr = new Thread(() -> {
88       synchronized(a) {
89         synchronized (b) {
90           System.out.println("Locks are good.");
91         }
92       }
93     });
94     thr.start();
95     thr.join();
96   }
97 }
98