1 /*
2  * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 //    THIS TEST IS LINE NUMBER SENSITIVE
25 
26 /**
27  * @test
28  * @bug 6496524
29  * @key intermittent
30  * @summary Setting breakpoint in jdb crashes Hotspot JVM
31  * @author jjh
32  *
33  * @run build TestScaffold VMConnection TargetListener TargetAdapter
34  * @run compile -g BreakpointTest.java
35  * @run driver BreakpointTest
36  */
37 
38 import com.sun.jdi.*;
39 import com.sun.jdi.event.*;
40 import com.sun.jdi.request.*;
41 
42 import java.util.*;
43 
44 // The debuggee just runs in a loop. The debugger
45 // sets a bkpt on the Math.random call.  When the
46 // bkpt is hit, the debugger disables it, resumes
47 // the debuggee, waits a bit, and enables the bkpt again.
48 
49 class BreakpointTarg {
50     public final static int BKPT_LINE = 56;
51 
52     public static long count;
doit()53     static void doit() {
54         Object[] roots = new Object[200000];
55         while (true) {
56             int index = (int) (Math.random() * roots.length); // BKPT_LINE
57             // This println makes the test pass
58             //System.out.println("Debuggee: index = " + index);
59             roots[index] = new Object();   // bkpt here passes
60                                            // and null instead of new Object()
61                                            // passes
62             count++;
63         }
64     }
65 
main(String[] args)66     public static void main(String[] args) {
67         doit();
68     }
69 }
70 
71     /********** test program **********/
72 
73 public class BreakpointTest extends TestScaffold {
74     ClassType targetClass;
75     ThreadReference mainThread;
76 
BreakpointTest(String args[])77     BreakpointTest (String args[]) {
78         super(args);
79     }
80 
main(String[] args)81     public static void main(String[] args)      throws Exception {
82         new BreakpointTest(args).startTests();
83     }
84 
85     /********** event handlers **********/
86 
87     static int maxBkpts = 50;
88     int bkptCount;
89     BreakpointRequest bkptRequest;
90     Field debuggeeCountField;
91 
92     // When we get a bkpt we want to disable the request,
93     // resume the debuggee, and then re-enable the request
breakpointReached(BreakpointEvent event)94     public void breakpointReached(BreakpointEvent event) {
95         System.out.println("Got BreakpointEvent: " + bkptCount +
96                            ", debuggeeCount = " +
97                            ((LongValue)targetClass.
98                             getValue(debuggeeCountField)).value()
99                            );
100         bkptRequest.disable();
101     }
102 
eventSetComplete(EventSet set)103     public void eventSetComplete(EventSet set) {
104         set.resume();
105 
106         // The main thread watchs the bkptCount to
107         // see if bkpts stop coming in.  The
108         // test _should_ fail well before maxBkpts bkpts.
109         if (bkptCount++ < maxBkpts) {
110             try {
111                 Thread.sleep(100);
112             } catch (InterruptedException ee) {
113             }
114             bkptRequest.enable();
115         }
116     }
117 
vmDisconnected(VMDisconnectEvent event)118     public void vmDisconnected(VMDisconnectEvent event) {
119         println("Got VMDisconnectEvent");
120     }
121 
122     /********** test core **********/
123 
runTests()124     protected void runTests() throws Exception {
125         /*
126          * Get to the top of main()
127          * to determine targetClass and mainThread
128          */
129         BreakpointEvent bpe = startToMain("BreakpointTarg");
130         targetClass = (ClassType)bpe.location().declaringType();
131         mainThread = bpe.thread();
132         EventRequestManager erm = vm().eventRequestManager();
133 
134         Location loc1 = findLocation(
135                             targetClass,
136                             BreakpointTarg.BKPT_LINE);
137 
138         bkptRequest = erm.createBreakpointRequest(loc1);
139         bkptRequest.enable();
140         debuggeeCountField = targetClass.fieldByName("count");
141         try {
142 
143             addListener (this);
144         } catch (Exception ex){
145             ex.printStackTrace();
146             failure("failure: Could not add listener");
147             throw new Exception("BreakpointTest: failed");
148         }
149 
150         int prevBkptCount;
151         vm().resume();
152         while (!vmDisconnected && bkptCount < maxBkpts) {
153             try {
154                 Thread.sleep(5000);
155             } catch (InterruptedException ee) {
156             }
157         }
158 
159         println("done with loop, final count = " +
160                     ((LongValue)targetClass.
161                      getValue(debuggeeCountField)).value());
162         bkptRequest.disable();
163         removeListener(this);
164 
165 
166         /*
167          * deal with results of test
168          * if anything has called failure("foo") testFailed will be true
169          */
170         if (!testFailed) {
171             println("BreakpointTest: passed");
172         } else {
173             throw new Exception("BreakpointTest: failed");
174         }
175     }
176 }
177