1*e82f7db8SAndroid Build Coastguard Worker /*
2*e82f7db8SAndroid Build Coastguard Worker * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
3*e82f7db8SAndroid Build Coastguard Worker * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*e82f7db8SAndroid Build Coastguard Worker *
5*e82f7db8SAndroid Build Coastguard Worker * This code is free software; you can redistribute it and/or modify it
6*e82f7db8SAndroid Build Coastguard Worker * under the terms of the GNU General Public License version 2 only, as
7*e82f7db8SAndroid Build Coastguard Worker * published by the Free Software Foundation. Oracle designates this
8*e82f7db8SAndroid Build Coastguard Worker * particular file as subject to the "Classpath" exception as provided
9*e82f7db8SAndroid Build Coastguard Worker * by Oracle in the LICENSE file that accompanied this code.
10*e82f7db8SAndroid Build Coastguard Worker *
11*e82f7db8SAndroid Build Coastguard Worker * This code is distributed in the hope that it will be useful, but WITHOUT
12*e82f7db8SAndroid Build Coastguard Worker * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e82f7db8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*e82f7db8SAndroid Build Coastguard Worker * version 2 for more details (a copy is included in the LICENSE file that
15*e82f7db8SAndroid Build Coastguard Worker * accompanied this code).
16*e82f7db8SAndroid Build Coastguard Worker *
17*e82f7db8SAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License version
18*e82f7db8SAndroid Build Coastguard Worker * 2 along with this work; if not, write to the Free Software Foundation,
19*e82f7db8SAndroid Build Coastguard Worker * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20*e82f7db8SAndroid Build Coastguard Worker *
21*e82f7db8SAndroid Build Coastguard Worker * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22*e82f7db8SAndroid Build Coastguard Worker * or visit www.oracle.com if you need additional information or have any
23*e82f7db8SAndroid Build Coastguard Worker * questions.
24*e82f7db8SAndroid Build Coastguard Worker */
25*e82f7db8SAndroid Build Coastguard Worker /*
26*e82f7db8SAndroid Build Coastguard Worker * handlers
27*e82f7db8SAndroid Build Coastguard Worker *
28*e82f7db8SAndroid Build Coastguard Worker * The default event request handler functions
29*e82f7db8SAndroid Build Coastguard Worker */
30*e82f7db8SAndroid Build Coastguard Worker
31*e82f7db8SAndroid Build Coastguard Worker #include "util.h"
32*e82f7db8SAndroid Build Coastguard Worker #include "eventHandler.h"
33*e82f7db8SAndroid Build Coastguard Worker #include "threadControl.h"
34*e82f7db8SAndroid Build Coastguard Worker #include "eventHelper.h"
35*e82f7db8SAndroid Build Coastguard Worker #include "classTrack.h"
36*e82f7db8SAndroid Build Coastguard Worker
37*e82f7db8SAndroid Build Coastguard Worker #include "standardHandlers.h"
38*e82f7db8SAndroid Build Coastguard Worker
39*e82f7db8SAndroid Build Coastguard Worker static void
handleClassPrepare(JNIEnv * env,EventInfo * evinfo,HandlerNode * node,struct bag * eventBag)40*e82f7db8SAndroid Build Coastguard Worker handleClassPrepare(JNIEnv *env, EventInfo *evinfo,
41*e82f7db8SAndroid Build Coastguard Worker HandlerNode *node,
42*e82f7db8SAndroid Build Coastguard Worker struct bag *eventBag)
43*e82f7db8SAndroid Build Coastguard Worker {
44*e82f7db8SAndroid Build Coastguard Worker jthread thread = evinfo->thread;
45*e82f7db8SAndroid Build Coastguard Worker
46*e82f7db8SAndroid Build Coastguard Worker /* We try hard to avoid class loads/prepares in debugger
47*e82f7db8SAndroid Build Coastguard Worker * threads, but it is still possible for them to happen (most
48*e82f7db8SAndroid Build Coastguard Worker * likely for exceptions that are thrown within JNI
49*e82f7db8SAndroid Build Coastguard Worker * methods). If such an event occurs, we must report it, but
50*e82f7db8SAndroid Build Coastguard Worker * we cannot suspend the debugger thread.
51*e82f7db8SAndroid Build Coastguard Worker *
52*e82f7db8SAndroid Build Coastguard Worker * 1) We report the thread as NULL because we don't want the
53*e82f7db8SAndroid Build Coastguard Worker * application to get hold of a debugger thread object.
54*e82f7db8SAndroid Build Coastguard Worker * 2) We try to do the right thing wrt to suspending
55*e82f7db8SAndroid Build Coastguard Worker * threads without suspending debugger threads. If the
56*e82f7db8SAndroid Build Coastguard Worker * requested suspend policy is NONE, there's no problem. If
57*e82f7db8SAndroid Build Coastguard Worker * the requested policy is ALL, we can just suspend all
58*e82f7db8SAndroid Build Coastguard Worker * application threads without producing any surprising
59*e82f7db8SAndroid Build Coastguard Worker * results by leaving the debugger thread running. However,
60*e82f7db8SAndroid Build Coastguard Worker * if the requested policy is EVENT_THREAD, we are forced
61*e82f7db8SAndroid Build Coastguard Worker * to do something different than requested. The most
62*e82f7db8SAndroid Build Coastguard Worker * useful behavior is to suspend all application threads
63*e82f7db8SAndroid Build Coastguard Worker * (just as if the policy was ALL). This allows the
64*e82f7db8SAndroid Build Coastguard Worker * application to operate on the class before it gets into
65*e82f7db8SAndroid Build Coastguard Worker * circulation and so it is preferable to the other
66*e82f7db8SAndroid Build Coastguard Worker * alternative of suspending no threads.
67*e82f7db8SAndroid Build Coastguard Worker */
68*e82f7db8SAndroid Build Coastguard Worker if (threadControl_isDebugThread(thread)) {
69*e82f7db8SAndroid Build Coastguard Worker evinfo->thread = NULL;
70*e82f7db8SAndroid Build Coastguard Worker if (node->suspendPolicy == JDWP_SUSPEND_POLICY(EVENT_THREAD)) {
71*e82f7db8SAndroid Build Coastguard Worker node->suspendPolicy = JDWP_SUSPEND_POLICY(ALL);
72*e82f7db8SAndroid Build Coastguard Worker }
73*e82f7db8SAndroid Build Coastguard Worker }
74*e82f7db8SAndroid Build Coastguard Worker eventHelper_recordEvent(evinfo, node->handlerID,
75*e82f7db8SAndroid Build Coastguard Worker node->suspendPolicy, eventBag);
76*e82f7db8SAndroid Build Coastguard Worker }
77*e82f7db8SAndroid Build Coastguard Worker
78*e82f7db8SAndroid Build Coastguard Worker static void
handleGarbageCollectionFinish(JNIEnv * env,EventInfo * evinfo,HandlerNode * node,struct bag * eventBag)79*e82f7db8SAndroid Build Coastguard Worker handleGarbageCollectionFinish(JNIEnv *env, EventInfo *evinfo,
80*e82f7db8SAndroid Build Coastguard Worker HandlerNode *node,
81*e82f7db8SAndroid Build Coastguard Worker struct bag *eventBag)
82*e82f7db8SAndroid Build Coastguard Worker {
83*e82f7db8SAndroid Build Coastguard Worker JDI_ASSERT_MSG(JNI_FALSE, "Should never call handleGarbageCollectionFinish");
84*e82f7db8SAndroid Build Coastguard Worker }
85*e82f7db8SAndroid Build Coastguard Worker
86*e82f7db8SAndroid Build Coastguard Worker static void
handleFrameEvent(JNIEnv * env,EventInfo * evinfo,HandlerNode * node,struct bag * eventBag)87*e82f7db8SAndroid Build Coastguard Worker handleFrameEvent(JNIEnv *env, EventInfo *evinfo,
88*e82f7db8SAndroid Build Coastguard Worker HandlerNode *node,
89*e82f7db8SAndroid Build Coastguard Worker struct bag *eventBag)
90*e82f7db8SAndroid Build Coastguard Worker {
91*e82f7db8SAndroid Build Coastguard Worker /*
92*e82f7db8SAndroid Build Coastguard Worker * The frame id that comes with this event is very transient.
93*e82f7db8SAndroid Build Coastguard Worker * We can't send the frame to the helper thread because it
94*e82f7db8SAndroid Build Coastguard Worker * might be useless by the time the helper thread can use it
95*e82f7db8SAndroid Build Coastguard Worker * (if suspend policy is NONE). So, get the needed info from
96*e82f7db8SAndroid Build Coastguard Worker * the frame and then use a special command to the helper
97*e82f7db8SAndroid Build Coastguard Worker * thread.
98*e82f7db8SAndroid Build Coastguard Worker */
99*e82f7db8SAndroid Build Coastguard Worker
100*e82f7db8SAndroid Build Coastguard Worker jmethodID method;
101*e82f7db8SAndroid Build Coastguard Worker jlocation location;
102*e82f7db8SAndroid Build Coastguard Worker jvmtiError error;
103*e82f7db8SAndroid Build Coastguard Worker FrameNumber fnum = 0;
104*e82f7db8SAndroid Build Coastguard Worker jvalue returnValue;
105*e82f7db8SAndroid Build Coastguard Worker
106*e82f7db8SAndroid Build Coastguard Worker error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)
107*e82f7db8SAndroid Build Coastguard Worker (gdata->jvmti, evinfo->thread, fnum, &method, &location);
108*e82f7db8SAndroid Build Coastguard Worker if (error != JVMTI_ERROR_NONE) {
109*e82f7db8SAndroid Build Coastguard Worker location = -1;
110*e82f7db8SAndroid Build Coastguard Worker }
111*e82f7db8SAndroid Build Coastguard Worker returnValue = evinfo->u.method_exit.return_value;
112*e82f7db8SAndroid Build Coastguard Worker
113*e82f7db8SAndroid Build Coastguard Worker eventHelper_recordFrameEvent(node->handlerID,
114*e82f7db8SAndroid Build Coastguard Worker node->suspendPolicy,
115*e82f7db8SAndroid Build Coastguard Worker evinfo->ei,
116*e82f7db8SAndroid Build Coastguard Worker evinfo->thread,
117*e82f7db8SAndroid Build Coastguard Worker evinfo->clazz,
118*e82f7db8SAndroid Build Coastguard Worker evinfo->method,
119*e82f7db8SAndroid Build Coastguard Worker location,
120*e82f7db8SAndroid Build Coastguard Worker node->needReturnValue,
121*e82f7db8SAndroid Build Coastguard Worker returnValue,
122*e82f7db8SAndroid Build Coastguard Worker eventBag);
123*e82f7db8SAndroid Build Coastguard Worker }
124*e82f7db8SAndroid Build Coastguard Worker
125*e82f7db8SAndroid Build Coastguard Worker static void
genericHandler(JNIEnv * env,EventInfo * evinfo,HandlerNode * node,struct bag * eventBag)126*e82f7db8SAndroid Build Coastguard Worker genericHandler(JNIEnv *env, EventInfo *evinfo,
127*e82f7db8SAndroid Build Coastguard Worker HandlerNode *node,
128*e82f7db8SAndroid Build Coastguard Worker struct bag *eventBag)
129*e82f7db8SAndroid Build Coastguard Worker {
130*e82f7db8SAndroid Build Coastguard Worker eventHelper_recordEvent(evinfo, node->handlerID, node->suspendPolicy,
131*e82f7db8SAndroid Build Coastguard Worker eventBag);
132*e82f7db8SAndroid Build Coastguard Worker }
133*e82f7db8SAndroid Build Coastguard Worker
134*e82f7db8SAndroid Build Coastguard Worker HandlerFunction
standardHandlers_defaultHandler(EventIndex ei)135*e82f7db8SAndroid Build Coastguard Worker standardHandlers_defaultHandler(EventIndex ei)
136*e82f7db8SAndroid Build Coastguard Worker {
137*e82f7db8SAndroid Build Coastguard Worker switch (ei) {
138*e82f7db8SAndroid Build Coastguard Worker case EI_BREAKPOINT:
139*e82f7db8SAndroid Build Coastguard Worker case EI_EXCEPTION:
140*e82f7db8SAndroid Build Coastguard Worker case EI_FIELD_ACCESS:
141*e82f7db8SAndroid Build Coastguard Worker case EI_FIELD_MODIFICATION:
142*e82f7db8SAndroid Build Coastguard Worker case EI_SINGLE_STEP:
143*e82f7db8SAndroid Build Coastguard Worker case EI_THREAD_START:
144*e82f7db8SAndroid Build Coastguard Worker case EI_THREAD_END:
145*e82f7db8SAndroid Build Coastguard Worker case EI_VM_DEATH:
146*e82f7db8SAndroid Build Coastguard Worker case EI_MONITOR_CONTENDED_ENTER:
147*e82f7db8SAndroid Build Coastguard Worker case EI_MONITOR_CONTENDED_ENTERED:
148*e82f7db8SAndroid Build Coastguard Worker case EI_MONITOR_WAIT:
149*e82f7db8SAndroid Build Coastguard Worker case EI_MONITOR_WAITED:
150*e82f7db8SAndroid Build Coastguard Worker return &genericHandler;
151*e82f7db8SAndroid Build Coastguard Worker
152*e82f7db8SAndroid Build Coastguard Worker case EI_CLASS_PREPARE:
153*e82f7db8SAndroid Build Coastguard Worker return &handleClassPrepare;
154*e82f7db8SAndroid Build Coastguard Worker
155*e82f7db8SAndroid Build Coastguard Worker case EI_GC_FINISH:
156*e82f7db8SAndroid Build Coastguard Worker return &handleGarbageCollectionFinish;
157*e82f7db8SAndroid Build Coastguard Worker
158*e82f7db8SAndroid Build Coastguard Worker case EI_METHOD_ENTRY:
159*e82f7db8SAndroid Build Coastguard Worker case EI_METHOD_EXIT:
160*e82f7db8SAndroid Build Coastguard Worker return &handleFrameEvent;
161*e82f7db8SAndroid Build Coastguard Worker
162*e82f7db8SAndroid Build Coastguard Worker default:
163*e82f7db8SAndroid Build Coastguard Worker /* This NULL will trigger a AGENT_ERROR_INVALID_EVENT_TYPE */
164*e82f7db8SAndroid Build Coastguard Worker return NULL;
165*e82f7db8SAndroid Build Coastguard Worker }
166*e82f7db8SAndroid Build Coastguard Worker }
167*e82f7db8SAndroid Build Coastguard Worker
168*e82f7db8SAndroid Build Coastguard Worker void
standardHandlers_onConnect(void)169*e82f7db8SAndroid Build Coastguard Worker standardHandlers_onConnect(void)
170*e82f7db8SAndroid Build Coastguard Worker {
171*e82f7db8SAndroid Build Coastguard Worker jboolean installed;
172*e82f7db8SAndroid Build Coastguard Worker
173*e82f7db8SAndroid Build Coastguard Worker /* always report VMDeath to a connected debugger */
174*e82f7db8SAndroid Build Coastguard Worker installed = (eventHandler_createPermanentInternal(
175*e82f7db8SAndroid Build Coastguard Worker EI_VM_DEATH, genericHandler) != NULL);
176*e82f7db8SAndroid Build Coastguard Worker if (!installed) {
177*e82f7db8SAndroid Build Coastguard Worker EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"Unable to install VM Death event handler");
178*e82f7db8SAndroid Build Coastguard Worker }
179*e82f7db8SAndroid Build Coastguard Worker }
180*e82f7db8SAndroid Build Coastguard Worker
181*e82f7db8SAndroid Build Coastguard Worker void
standardHandlers_onDisconnect(void)182*e82f7db8SAndroid Build Coastguard Worker standardHandlers_onDisconnect(void)
183*e82f7db8SAndroid Build Coastguard Worker {
184*e82f7db8SAndroid Build Coastguard Worker }
185