1 /* 2 * Copyright (C) 2015 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.io.BufferedReader; 18 import java.io.FileReader; 19 import java.io.InputStreamReader; 20 import java.util.Arrays; 21 import java.util.Comparator; 22 23 public class Main extends Base implements Comparator<Main> { 24 // Whether to test local unwinding. 25 private static boolean testLocal; 26 27 // Unwinding another process, modelling debuggerd. 28 private static boolean testRemote; 29 30 // We fork ourself to create the secondary process for remote unwinding. 31 private static boolean secondary; 32 33 public static void main(String[] args) throws Exception { 34 System.loadLibrary(args[0]); 35 for (int i = 1; i < args.length; i++) { 36 if (args[i].equals("--test-local")) { 37 testLocal = true; 38 } else if (args[i].equals("--test-remote")) { 39 testRemote = true; 40 } else if (args[i].equals("--secondary")) { 41 secondary = true; 42 } else { 43 System.out.println("Unknown argument: " + args[i]); 44 System.exit(1); 45 } 46 } 47 48 // Call test() via base class to test unwinding through multidex. 49 new Main().$noinline$runTest(); 50 } 51 52 public void test() { 53 // Call unwind() via Arrays.binarySearch to test unwinding through framework. 54 Main[] array = { this, this, this }; 55 Arrays.binarySearch(array, 0, 3, this /* value */, this /* comparator */); 56 } 57 58 public int compare(Main lhs, Main rhs) { 59 unwind(); 60 // Returning "equal" ensures that we terminate search 61 // after first item and thus call unwind() only once. 62 return 0; 63 } 64 65 public void unwind() { 66 if (secondary) { 67 sigstop(); // This is helper child process. Stop and wait for unwinding. 68 return; // Don't run the tests again in the secondary helper process. 69 } 70 71 if (testLocal) { 72 String result = unwindInProcess() ? "PASS" : "FAIL"; 73 System.out.println("Unwind in process: " + result); 74 } 75 76 if (testRemote) { 77 // Start a secondary helper process. It will stop itself when it is ready. 78 int pid = startSecondaryProcess(); 79 // Wait for the secondary process to stop and then unwind it remotely. 80 String result = unwindOtherProcess(pid) ? "PASS" : "FAIL"; 81 System.out.println("Unwind other process: " + result); 82 } 83 } 84 85 public static native int startSecondaryProcess(); 86 public static native boolean sigstop(); 87 public static native boolean unwindInProcess(); 88 public static native boolean unwindOtherProcess(int pid); 89 } 90