1 /* 2 * Copyright (C) 2018 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 import java.lang.reflect.Field; 18 import java.lang.reflect.Method; 19 20 class NotLoaded { foo()21 public void foo() {} 22 } 23 24 public class Main { main(String[] args)25 public static void main(String[] args) throws Exception { 26 runTest(null); 27 } 28 29 // This method being synchronized means the SIGQUIT code in ART will call 30 // FindLocksAtDexPc (we check for the presence of try blocks and monitor-enter), 31 // which triggered a DCHECK of an invariant. runTest(Object m)32 public static synchronized void runTest(Object m) throws Exception { 33 if (m != null) { 34 // We used to crash while trying to resolve NotLoaded and beint interrupted 35 // by the SIGQUIT. 36 if (m instanceof NotLoaded) { 37 ((NotLoaded)m).foo(); 38 } 39 } 40 SigQuit.doKill(); 41 // Sleep some time to get the kill while executing this method. 42 Thread.sleep(2); 43 System.out.println("Done"); 44 } 45 46 private final static class SigQuit { 47 private final static int sigquit; 48 private final static Method kill; 49 private final static int pid; 50 51 static { 52 int pidTemp = -1; 53 int sigquitTemp = -1; 54 Method killTemp = null; 55 56 try { 57 Class<?> osClass = Class.forName("android.system.Os"); 58 Method getpid = osClass.getDeclaredMethod("getpid"); 59 pidTemp = (Integer)getpid.invoke(null); 60 61 Class<?> osConstants = Class.forName("android.system.OsConstants"); 62 Field sigquitField = osConstants.getDeclaredField("SIGQUIT"); 63 sigquitTemp = (Integer)sigquitField.get(null); 64 65 killTemp = osClass.getDeclaredMethod("kill", int.class, int.class); 66 } catch (Exception e) { 67 throw new Error(e); 68 } 69 70 pid = pidTemp; 71 sigquit = sigquitTemp; 72 kill = killTemp; 73 } 74 doKill()75 public static void doKill() throws Exception { 76 kill.invoke(null, pid, sigquit); 77 } 78 } 79 } 80