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
17package art;
18
19import java.util.Arrays;
20import java.lang.reflect.Executable;
21import java.lang.reflect.Method;
22
23public class Test995 {
24  public static final Breakpoint.Manager MANAGER = new Breakpoint.Manager();
25  public static BreakpointHandler HANDLER = null;
26
27  public static void doNothing() { }
28
29  public static interface BreakpointHandler {
30    public void breakpointReached(Executable e, long loc);
31  }
32
33  public static void breakpoint() {
34    return;
35  }
36
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
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
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
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