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.lang.reflect.Executable;
21 import java.lang.reflect.Method;
22 
23 public class Test995 {
24   public static final Breakpoint.Manager MANAGER = new Breakpoint.Manager();
25   public static BreakpointHandler HANDLER = null;
26 
doNothing()27   public static void doNothing() { }
28 
29   public static interface BreakpointHandler {
breakpointReached(Executable e, long loc)30     public void breakpointReached(Executable e, long loc);
31   }
32 
breakpoint()33   public static void breakpoint() {
34     return;
35   }
36 
breakpointCatchLate()37   public static void breakpointCatchLate() {
38     doNothing();
39     try {
40       doNothing();
41     } catch (Throwable t) {
42       System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
43     }
44   }
45 
breakpointCatch()46   public static void breakpointCatch() {
47     try {
48       doNothing();
49     } catch (Throwable t) {
50       System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
51     }
52   }
53 
notifyBreakpointReached(Thread thr, Executable e, long loc)54   public static void notifyBreakpointReached(Thread thr, Executable e, long loc) {
55     System.out.println("\tBreakpoint: " + e + " @ line=" + Breakpoint.locationToLine(e, loc));
56     HANDLER.breakpointReached(e, loc);
57   }
58 
59 
makeHandler(String name, BreakpointHandler h)60   public static BreakpointHandler makeHandler(String name, BreakpointHandler h) {
61     return new BreakpointHandler() {
62       public String toString() {
63         return name;
64       }
65       public void breakpointReached(Executable e, long loc) {
66         h.breakpointReached(e, loc);
67       }
68     };
69   }
70 
71   public static Runnable makeTest(String name, Runnable test) {
72     return new Runnable() {
73       public String toString() { return name; }
74       public void run() { test.run(); }
75     };
76   }
77 
78   public static void run() throws Exception {
79     // Set up breakpoints
80     Breakpoint.stopBreakpointWatch(Thread.currentThread());
81     Breakpoint.startBreakpointWatch(
82         Test995.class,
83         Test995.class.getDeclaredMethod(
84             "notifyBreakpointReached", Thread.class, Executable.class, Long.TYPE),
85         Thread.currentThread());
86 
87     Method breakpoint_method = Test995.class.getDeclaredMethod("breakpoint");
88     Method breakpoint_catch_method = Test995.class.getDeclaredMethod("breakpointCatch");
89     Method breakpoint_catch_late_method = Test995.class.getDeclaredMethod("breakpointCatchLate");
90     MANAGER.setBreakpoint(breakpoint_method, Breakpoint.getStartLocation(breakpoint_method));
91     MANAGER.setBreakpoint(
92         breakpoint_catch_method, Breakpoint.getStartLocation(breakpoint_catch_method));
93     MANAGER.setBreakpoint(
94         breakpoint_catch_late_method, Breakpoint.getStartLocation(breakpoint_catch_late_method));
95 
96     BreakpointHandler[] handlers = new BreakpointHandler[] {
97       makeHandler("do nothing", (e, l) -> {}),
98       makeHandler("throw", (e, l) -> { throw new Error("throwing error!"); }),
99     };
100 
101     Runnable[] tests = new Runnable[] {
102       makeTest("call Test995::breakpoint", Test995::breakpoint),
103       makeTest("call Test995::breakpointCatch", Test995::breakpointCatch),
104       makeTest("call Test995::breakpointCatchLate", Test995::breakpointCatchLate),
105       makeTest("catch subroutine Test995::breakpoint",
106           () -> {
107             try {
108               breakpoint();
109             } catch (Throwable t) {
110               System.out.printf("Caught %s:\"%s\"\n", t.getClass().getName(), t.getMessage());
111             }
112           }),
113     };
114 
115     for (BreakpointHandler handler : handlers) {
116       for (Runnable test : tests) {
117         try {
118           HANDLER = handler;
119           System.out.printf("Test \"%s\": Running breakpoint with handler \"%s\"\n",
120               test, handler);
121           test.run();
122           System.out.printf("Test \"%s\": No error caught with handler \"%s\"\n",
123               test, handler);
124         } catch (Throwable e) {
125           System.out.printf("Test \"%s\": Caught error %s:\"%s\" with handler \"%s\"\n",
126               test, e.getClass().getName(), e.getMessage(), handler);
127         }
128         System.out.printf("Test \"%s\": Finished running with handler \"%s\"\n", test, handler);
129         HANDLER = null;
130       }
131     }
132 
133     MANAGER.clearAllBreakpoints();
134     Breakpoint.stopBreakpointWatch(Thread.currentThread());
135   }
136 }
137