1 /* 2 * Copyright (C) 2017 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.Arrays; 20 import java.util.Objects; 21 import java.lang.reflect.Executable; 22 import java.lang.reflect.Method; 23 24 public class Test1928 { 25 public static boolean PRINT_FULL_EXCEPTION = false; 26 public static ExceptionHandler HANDLER = null; 27 28 public static interface ExceptionHandler { exceptionOccurred( Executable m, long loc, Throwable exception, Executable catch_m, long catch_l)29 public void exceptionOccurred( 30 Executable m, long loc, Throwable exception, Executable catch_m, long catch_l); 31 } 32 PrintStack()33 private static void PrintStack() { 34 System.out.println("\tCurrent Stack:"); 35 for (StackTrace.StackFrameData e : StackTrace.GetStackTrace(Thread.currentThread())) { 36 if (Objects.equals(e.method.getDeclaringClass().getPackage(), Test1928.class.getPackage())) { 37 System.out.println("\t\t" + e.method + " @ line = " + 38 Breakpoint.locationToLine(e.method, e.current_location)); 39 } 40 } 41 } 42 ExceptionEvent(Thread thr, Executable throw_method, long throw_location, Throwable exception, Executable catch_method, long catch_location)43 public static void ExceptionEvent(Thread thr, 44 Executable throw_method, 45 long throw_location, 46 Throwable exception, 47 Executable catch_method, 48 long catch_location) { 49 System.out.println(thr.getName() + ": " + throw_method + " @ line = " + 50 Breakpoint.locationToLine(throw_method, throw_location) + " throws " + 51 exception.getClass() + ": " + exception.getMessage()); 52 String catch_message; 53 if (catch_method == null) { 54 catch_message = "<UNKNOWN>"; 55 } else { 56 catch_message = catch_method.toString() + " @ line = " + 57 Breakpoint.locationToLine(catch_method, catch_location); 58 } 59 PrintStack(); 60 System.out.println("\tWill be caught by: " + catch_message); 61 if (PRINT_FULL_EXCEPTION) { 62 System.out.print("exception is: "); 63 exception.printStackTrace(System.out); 64 } 65 if (HANDLER != null) { 66 HANDLER.exceptionOccurred( 67 throw_method, throw_location, exception, catch_method, catch_location); 68 } 69 } 70 71 public static class BaseTestException extends Error { BaseTestException(String e)72 public BaseTestException(String e) { super(e); } BaseTestException(String e, Throwable t)73 public BaseTestException(String e, Throwable t) { super(e, t); } 74 } 75 public static class TestException extends BaseTestException { TestException(String e)76 public TestException(String e) { super(e); } TestException(String e, Throwable t)77 public TestException(String e, Throwable t) { super(e, t); } 78 } 79 80 public static class TestExceptionNoRethrow extends TestException { TestExceptionNoRethrow(String e)81 public TestExceptionNoRethrow(String e) { super(e); } TestExceptionNoRethrow(String e, Throwable t)82 public TestExceptionNoRethrow(String e, Throwable t) { super(e, t); } 83 } 84 85 public static class DoNothingHandler implements ExceptionHandler { exceptionOccurred( Executable m, long loc, Throwable exception, Executable catch_m, long catch_l)86 public void exceptionOccurred( 87 Executable m, long loc, Throwable exception, Executable catch_m, long catch_l) { 88 System.out.println("\tDoing nothing!"); 89 return; 90 } 91 } 92 93 public static class ThrowCatchBase implements ExceptionHandler { exceptionOccurred( Executable m, long loc, Throwable exception, Executable catch_m, long catch_l)94 public void exceptionOccurred( 95 Executable m, long loc, Throwable exception, Executable catch_m, long catch_l) { 96 System.out.println("\tThrowing BaseTestException and catching it!"); 97 try { 98 throw new BaseTestException("ThrowBaseHandler during throw from " + m + " @ line = " + 99 Breakpoint.locationToLine(m, loc), exception); 100 } catch (BaseTestException t) { 101 System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); 102 if (PRINT_FULL_EXCEPTION) { 103 t.printStackTrace(System.out); 104 } 105 } 106 } 107 } 108 doThrow()109 public static void doThrow() { 110 throw new TestException("doThrow"); 111 } 112 113 public static class DoThrowClass implements Runnable { run()114 public void run() { doThrow(); } 115 } 116 throwCatchBaseTestException()117 public static void throwCatchBaseTestException() { 118 try { 119 throw new TestException("throwCatchBaseTestException"); 120 } catch (BaseTestException t) { 121 System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); 122 if (PRINT_FULL_EXCEPTION) { 123 t.printStackTrace(System.out); 124 } 125 } 126 } 127 128 public static class DoThrowCatchBaseTestException implements Runnable { run()129 public void run() { throwCatchBaseTestException(); } 130 } 131 throwCatchTestException()132 public static void throwCatchTestException() { 133 try { 134 throw new TestException("throwCatchTestException"); 135 } catch (TestException t) { 136 System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); 137 if (PRINT_FULL_EXCEPTION) { 138 t.printStackTrace(System.out); 139 } 140 } 141 } 142 143 public static class DoThrowCatchTestException implements Runnable { run()144 public void run() { throwCatchTestException(); } 145 } 146 throwCatchTestExceptionNoRethrow()147 public static void throwCatchTestExceptionNoRethrow() { 148 try { 149 throw new TestException("throwCatchTestExceptionNoRethrow"); 150 } catch (TestExceptionNoRethrow t) { 151 System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\""); 152 if (PRINT_FULL_EXCEPTION) { 153 t.printStackTrace(System.out); 154 } 155 } 156 } 157 158 public static class DoThrowCatchTestExceptionNoRethrow implements Runnable { run()159 public void run() { throwCatchTestExceptionNoRethrow(); } 160 } 161 run()162 public static void run() throws Exception { 163 // Set up 164 Exceptions.setupExceptionTracing( 165 Test1928.class, 166 TestException.class, 167 Test1928.class.getDeclaredMethod( 168 "ExceptionEvent", 169 Thread.class, 170 Executable.class, 171 Long.TYPE, 172 Throwable.class, 173 Executable.class, 174 Long.TYPE), 175 null); 176 Exceptions.enableExceptionEvent(Thread.currentThread()); 177 178 ExceptionHandler[] handlers = new ExceptionHandler[] { 179 new DoNothingHandler(), 180 new ThrowCatchBase(), 181 }; 182 183 Runnable[] tests = new Runnable[] { 184 new DoThrowClass(), 185 new DoThrowCatchBaseTestException(), 186 new DoThrowCatchTestException(), 187 new DoThrowCatchTestExceptionNoRethrow(), 188 }; 189 190 for (ExceptionHandler handler : handlers) { 191 for (Runnable test : tests) { 192 try { 193 HANDLER = handler; 194 System.out.printf("Test \"%s\": Running with handler \"%s\"\n", 195 test.getClass().getName(), handler.getClass().getName()); 196 test.run(); 197 System.out.printf("Test \"%s\": No error caught with handler \"%s\"\n", 198 test.getClass().getName(), handler.getClass().getName()); 199 } catch (Throwable e) { 200 System.out.printf("Test \"%s\": Caught error %s:\"%s\" with handler \"%s\"\n", 201 test.getClass().getName(), 202 e.getClass().getName(), 203 e.getMessage(), 204 handler.getClass().getName()); 205 if (PRINT_FULL_EXCEPTION) { 206 e.printStackTrace(System.out); 207 } 208 } 209 System.out.printf("Test \"%s\": Finished running with handler \"%s\"\n", 210 test.getClass().getName(), handler.getClass().getName()); 211 HANDLER = null; 212 } 213 } 214 Exceptions.disableExceptionEvent(Thread.currentThread()); 215 } 216 } 217