xref: /aosp_15_r20/external/oj-libjdwp/src/share/back/standardHandlers.c (revision e82f7db8c62aed3c168547abe4f9f4aeceaebfc7)
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