Bug Summary

File:jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c
Warning:line 729, column 5
Access to field 'pending' results in a dereference of a null pointer (loaded from variable 'request')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name invoker.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjava -I /home/daniel/Projects/java/jdk/src/java.base/unix/native/libjava -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -D LIBC=gnu -D _GNU_SOURCE -D _REENTRANT -D _LARGEFILE64_SOURCE -D LINUX -D DEBUG -D _LITTLE_ENDIAN -D ARCH="amd64" -D amd64 -D _LP64=1 -D JDWP_LOGGING -I /home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/unix/native/libjdwp -I /home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/headers/jdk.jdwp.agent -I /home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/include -I /home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/export -D _FORTIFY_SOURCE=2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wno-unused -Wno-unused-function -std=c99 -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c /home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c
1/*
2 * Copyright (c) 1998, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include "util.h"
27#include "invoker.h"
28#include "eventHandler.h"
29#include "threadControl.h"
30#include "outStream.h"
31#include "signature.h"
32
33static jrawMonitorID invokerLock;
34
35void
36invoker_initialize(void)
37{
38 invokerLock = debugMonitorCreate("JDWP Invocation Lock");
39}
40
41void
42invoker_reset(void)
43{
44}
45
46void invoker_lock(void)
47{
48 debugMonitorEnter(invokerLock);
49}
50
51void invoker_unlock(void)
52{
53 debugMonitorExit(invokerLock);
54}
55
56/*
57 * Note: argument refs may be destroyed on out-of-memory error
58 */
59static jvmtiError
60createGlobalRefs(JNIEnv *env, InvokeRequest *request)
61{
62 jvmtiError error = JVMTI_ERROR_NONE;
63 void *cursor = NULL((void*)0);
64 jbyte argumentTag = 0;
65 jint argIndex = 0;
66 jvalue *argument = request->arguments;
67 jclass clazz = NULL((void*)0);
68 jobject instance = NULL((void*)0);
69 jobject *argRefs = NULL((void*)0);
70
71 if ( request->argumentCount > 0 ) {
72 /*LINTED*/
73 argRefs = jvmtiAllocate((jint)(request->argumentCount*sizeof(jobject)));
74 if ( argRefs==NULL((void*)0) ) {
75 error = AGENT_ERROR_OUT_OF_MEMORY((jvmtiError)(JVMTI_ERROR_MAX+64+8));
76 } else {
77 /*LINTED*/
78 (void)memset(argRefs, 0, request->argumentCount*sizeof(jobject));
79 }
80 }
81
82 if ( error == JVMTI_ERROR_NONE ) {
83 saveGlobalRef(env, request->clazz, &clazz);
84 if (clazz == NULL((void*)0)) {
85 error = AGENT_ERROR_OUT_OF_MEMORY((jvmtiError)(JVMTI_ERROR_MAX+64+8));
86 }
87 }
88
89 if ( error == JVMTI_ERROR_NONE && request->instance != NULL((void*)0) ) {
90 saveGlobalRef(env, request->instance, &instance);
91 if (instance == NULL((void*)0)) {
92 error = AGENT_ERROR_OUT_OF_MEMORY((jvmtiError)(JVMTI_ERROR_MAX+64+8));
93 }
94 }
95
96 if ( error == JVMTI_ERROR_NONE && argRefs!=NULL((void*)0) ) {
97 methodSignature_init(request->methodSignature, &cursor);
98 while (methodSignature_nextArgumentExists(&cursor, &argumentTag)) {
99 if ( argIndex > request->argumentCount ) {
100 break;
101 }
102 if (isReferenceTag(argumentTag)) {
103 /* Create a global ref for any non-null argument */
104 if (argument->l != NULL((void*)0)) {
105 saveGlobalRef(env, argument->l, &argRefs[argIndex]);
106 if (argRefs[argIndex] == NULL((void*)0)) {
107 error = AGENT_ERROR_OUT_OF_MEMORY((jvmtiError)(JVMTI_ERROR_MAX+64+8));
108 break;
109 }
110 }
111 }
112 argument++;
113 argIndex++;
114 }
115 }
116
117#ifdef FIXUP /* Why isn't this an error? */
118 /* Make sure the argument count matches */
119 if ( error == JVMTI_ERROR_NONE && argIndex != request->argumentCount ) {
120 error = AGENT_ERROR_INVALID_COUNT((jvmtiError)(JVMTI_ERROR_MAX+64+19));
121 }
122#endif
123
124 /* Finally, put the global refs into the request if no errors */
125 if ( error == JVMTI_ERROR_NONE ) {
126 request->clazz = clazz;
127 request->instance = instance;
128 if ( argRefs!=NULL((void*)0) ) {
129 argIndex = 0;
130 methodSignature_init(request->methodSignature, &cursor);
131 argument = request->arguments;
132 while ( methodSignature_nextArgumentExists(&cursor, &argumentTag) &&
133 argIndex < request->argumentCount ) {
134 if ( isReferenceTag(argumentTag) ) {
135 argument->l = argRefs[argIndex];
136 }
137 argument++;
138 argIndex++;
139 }
140 jvmtiDeallocate(argRefs);
141 }
142 return JVMTI_ERROR_NONE;
143
144 } else {
145 /* Delete global references */
146 if ( clazz != NULL((void*)0) ) {
147 tossGlobalRef(env, &clazz);
148 }
149 if ( instance != NULL((void*)0) ) {
150 tossGlobalRef(env, &instance);
151 }
152 if ( argRefs!=NULL((void*)0) ) {
153 for ( argIndex=0; argIndex < request->argumentCount; argIndex++ ) {
154 if ( argRefs[argIndex] != NULL((void*)0) ) {
155 tossGlobalRef(env, &argRefs[argIndex]);
156 }
157 }
158 jvmtiDeallocate(argRefs);
159 }
160 }
161
162 return error;
163}
164
165/*
166 * Delete global argument references from the request which got put there before a
167 * invoke request was carried out. See fillInvokeRequest().
168 */
169static void
170deleteGlobalArgumentRefs(JNIEnv *env, InvokeRequest *request)
171{
172 void *cursor = NULL((void*)0);
173 jint argIndex = 0;
174 jbyte argumentTag = 0;
175 jvalue *argument = request->arguments;
176 methodSignature_init(request->methodSignature, &cursor);
177
178 if (request->clazz != NULL((void*)0)) {
179 tossGlobalRef(env, &(request->clazz));
180 }
181 if (request->instance != NULL((void*)0)) {
182 tossGlobalRef(env, &(request->instance));
183 }
184 /* Delete global argument references */
185 while (methodSignature_nextArgumentExists(&cursor, &argumentTag) &&
186 argIndex < request->argumentCount) {
187 if (isReferenceTag(argumentTag)) {
188 if (argument->l != NULL((void*)0)) {
189 tossGlobalRef(env, &(argument->l));
190 }
191 }
192 argument++;
193 argIndex++;
194 }
195}
196
197static jvmtiError
198fillInvokeRequest(JNIEnv *env, InvokeRequest *request,
199 jbyte invokeType, jbyte options, jint id,
200 jthread thread, jclass clazz, jmethodID method,
201 jobject instance,
202 jvalue *arguments, jint argumentCount)
203{
204 jvmtiError error;
205 if (!request->available) {
206 /*
207 * Thread is not at a point where it can invoke.
208 */
209 return AGENT_ERROR_INVALID_THREAD((jvmtiError)(JVMTI_ERROR_MAX+64+23));
210 }
211 if (request->pending) {
212 /*
213 * Pending invoke
214 */
215 return AGENT_ERROR_ALREADY_INVOKING((jvmtiError)(JVMTI_ERROR_MAX+64+10));
216 }
217
218 request->invokeType = invokeType;
219 request->options = options;
220 request->detached = JNI_FALSE0;
221 request->id = id;
222 request->clazz = clazz;
223 request->method = method;
224 request->instance = instance;
225 request->arguments = arguments;
226 request->arguments = arguments;
227 request->argumentCount = argumentCount;
228
229 request->returnValue.j = 0;
230 request->exception = 0;
231
232 /*
233 * Squirrel away the method signature
234 */
235 error = methodSignature(method, NULL((void*)0), &request->methodSignature, NULL((void*)0));
236 if (error != JVMTI_ERROR_NONE) {
237 return error;
238 }
239
240 /*
241 * The given references for class and instance are not guaranteed
242 * to be around long enough for invocation, so create new ones
243 * here.
244 */
245 error = createGlobalRefs(env, request);
246 if (error != JVMTI_ERROR_NONE) {
247 jvmtiDeallocate(request->methodSignature);
248 return error;
249 }
250
251 request->pending = JNI_TRUE1;
252 request->available = JNI_FALSE0;
253 return JVMTI_ERROR_NONE;
254}
255
256void
257invoker_enableInvokeRequests(jthread thread)
258{
259 InvokeRequest *request;
260
261 JDI_ASSERT(thread)do { if (gdata && gdata->assertOn && !(thread
)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 261, "thread"); } } while (0)
;
262
263 debugMonitorEnter(invokerLock);
264 request = threadControl_getInvokeRequest(thread);
265 if (request == NULL((void*)0)) {
266 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+23))), ((jvmtiError)(JVMTI_ERROR_MAX+64+23)), ("getting thread invoke request"
==((void*)0)?"":"getting thread invoke request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 266); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting thread invoke request"); }
;
267 }
268
269 request->available = JNI_TRUE1;
270 debugMonitorExit(invokerLock);
271}
272
273/*
274 * Check that method is in the specified clazz or one of its super classes.
275 * We have to enforce this check at the JDWP layer because the JNI layer
276 * has different requirements.
277 */
278static jvmtiError check_methodClass(JNIEnv *env, jclass clazz, jmethodID method)
279{
280 jclass containing_class = NULL((void*)0);
281 jvmtiError error;
282
283 error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)(*((*((((gdata->log_flags & (0x00000004))?(log_message_begin
("JVMTI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,283), log_message_end ("%s()","GetMethodDeclaringClass")):((
void)0)),(gdata->jvmti))))->GetMethodDeclaringClass))
284 (gdata->jvmti, method, &containing_class);
285 if (error != JVMTI_ERROR_NONE) {
286 return JVMTI_ERROR_NONE; /* Bad jmethodID ? This will be handled elsewhere */
287 }
288
289 if (JNI_FUNC_PTR(env,IsSameObject)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,289), log_message_end ("%s()","IsSameObject")):((void)0)), (
env))))->IsSameObject))
(env, clazz, containing_class)) {
290 return JVMTI_ERROR_NONE;
291 }
292
293 // If not the same class then check that containing_class is a superclass of
294 // clazz (not a superinterface).
295 if (JNI_FUNC_PTR(env,IsAssignableFrom)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,295), log_message_end ("%s()","IsAssignableFrom")):((void)0)
), (env))))->IsAssignableFrom))
(env, clazz, containing_class) &&
296 referenceTypeTag(containing_class) != JDWP_TYPE_TAG(INTERFACE)2) {
297 return JVMTI_ERROR_NONE;
298 }
299 return JVMTI_ERROR_INVALID_METHODID;
300}
301
302jvmtiError
303invoker_requestInvoke(jbyte invokeType, jbyte options, jint id,
304 jthread thread, jclass clazz, jmethodID method,
305 jobject instance,
306 jvalue *arguments, jint argumentCount)
307{
308 JNIEnv *env = getEnv();
309 InvokeRequest *request;
310 jvmtiError error = JVMTI_ERROR_NONE;
311
312 if (invokeType == INVOKE_STATIC2) {
313 error = check_methodClass(env, clazz, method);
314 if (error != JVMTI_ERROR_NONE) {
315 return error;
316 }
317 }
318
319 debugMonitorEnter(invokerLock);
320 request = threadControl_getInvokeRequest(thread);
321 if (request != NULL((void*)0)) {
322 error = fillInvokeRequest(env, request, invokeType, options, id,
323 thread, clazz, method, instance,
324 arguments, argumentCount);
325 }
326 debugMonitorExit(invokerLock);
327
328 if (error == JVMTI_ERROR_NONE) {
329 if (options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED)0x01 ) {
330 /* true means it is okay to unblock the commandLoop thread */
331 (void)threadControl_resumeThread(thread, JNI_TRUE1);
332 } else {
333 (void)threadControl_resumeAll();
334 }
335 }
336
337 return error;
338}
339
340static void
341invokeConstructor(JNIEnv *env, InvokeRequest *request)
342{
343 jobject object;
344
345 JDI_ASSERT_MSG(request->clazz, "Request clazz null")do { if (gdata && gdata->assertOn && !(request
->clazz)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 345, "Request clazz null"); } } while (0)
;
346 object = JNI_FUNC_PTR(env,NewObjectA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,346), log_message_end ("%s()","NewObjectA")):((void)0)), (env
))))->NewObjectA))
(env, request->clazz,
347 request->method,
348 request->arguments);
349 request->returnValue.l = NULL((void*)0);
350 if (object != NULL((void*)0)) {
351 saveGlobalRef(env, object, &(request->returnValue.l));
352 }
353}
354
355static void
356invokeStatic(JNIEnv *env, InvokeRequest *request)
357{
358 jbyte returnType = methodSignature_returnTag(request->methodSignature);
359
360 if (isReferenceTag(returnType)) {
361 jobject object;
362 JDI_ASSERT_MSG(request->clazz, "Request clazz null")do { if (gdata && gdata->assertOn && !(request
->clazz)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 362, "Request clazz null"); } } while (0)
;
363 object = JNI_FUNC_PTR(env,CallStaticObjectMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,363), log_message_end ("%s()","CallStaticObjectMethodA")):((
void)0)), (env))))->CallStaticObjectMethodA))
(env,
364 request->clazz,
365 request->method,
366 request->arguments);
367 request->returnValue.l = NULL((void*)0);
368 if (object != NULL((void*)0)) {
369 saveGlobalRef(env, object, &(request->returnValue.l));
370 }
371 return;
372 }
373
374 switch (returnType) {
375 case JDWP_TAG(BYTE)66:
376 request->returnValue.b = JNI_FUNC_PTR(env,CallStaticByteMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,376), log_message_end ("%s()","CallStaticByteMethodA")):((void
)0)), (env))))->CallStaticByteMethodA))
(env,
377 request->clazz,
378 request->method,
379 request->arguments);
380 break;
381
382 case JDWP_TAG(CHAR)67:
383 request->returnValue.c = JNI_FUNC_PTR(env,CallStaticCharMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,383), log_message_end ("%s()","CallStaticCharMethodA")):((void
)0)), (env))))->CallStaticCharMethodA))
(env,
384 request->clazz,
385 request->method,
386 request->arguments);
387 break;
388
389 case JDWP_TAG(FLOAT)70:
390 request->returnValue.f = JNI_FUNC_PTR(env,CallStaticFloatMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,390), log_message_end ("%s()","CallStaticFloatMethodA")):((void
)0)), (env))))->CallStaticFloatMethodA))
(env,
391 request->clazz,
392 request->method,
393 request->arguments);
394 break;
395
396 case JDWP_TAG(DOUBLE)68:
397 request->returnValue.d = JNI_FUNC_PTR(env,CallStaticDoubleMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,397), log_message_end ("%s()","CallStaticDoubleMethodA")):((
void)0)), (env))))->CallStaticDoubleMethodA))
(env,
398 request->clazz,
399 request->method,
400 request->arguments);
401 break;
402
403 case JDWP_TAG(INT)73:
404 request->returnValue.i = JNI_FUNC_PTR(env,CallStaticIntMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,404), log_message_end ("%s()","CallStaticIntMethodA")):((void
)0)), (env))))->CallStaticIntMethodA))
(env,
405 request->clazz,
406 request->method,
407 request->arguments);
408 break;
409
410 case JDWP_TAG(LONG)74:
411 request->returnValue.j = JNI_FUNC_PTR(env,CallStaticLongMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,411), log_message_end ("%s()","CallStaticLongMethodA")):((void
)0)), (env))))->CallStaticLongMethodA))
(env,
412 request->clazz,
413 request->method,
414 request->arguments);
415 break;
416
417 case JDWP_TAG(SHORT)83:
418 request->returnValue.s = JNI_FUNC_PTR(env,CallStaticShortMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,418), log_message_end ("%s()","CallStaticShortMethodA")):((void
)0)), (env))))->CallStaticShortMethodA))
(env,
419 request->clazz,
420 request->method,
421 request->arguments);
422 break;
423
424 case JDWP_TAG(BOOLEAN)90:
425 request->returnValue.z = JNI_FUNC_PTR(env,CallStaticBooleanMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,425), log_message_end ("%s()","CallStaticBooleanMethodA")):(
(void)0)), (env))))->CallStaticBooleanMethodA))
(env,
426 request->clazz,
427 request->method,
428 request->arguments);
429 break;
430
431 case JDWP_TAG(VOID)86:
432 JNI_FUNC_PTR(env,CallStaticVoidMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,432), log_message_end ("%s()","CallStaticVoidMethodA")):((void
)0)), (env))))->CallStaticVoidMethodA))
(env,
433 request->clazz,
434 request->method,
435 request->arguments);
436 break;
437
438 default:
439 EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"Invalid method signature"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+21))), ((jvmtiError)(JVMTI_ERROR_MAX+64+21)), ("Invalid method signature"
==((void*)0)?"":"Invalid method signature"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 439); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+21)), "Invalid method signature"); }
;
440 break;
441 }
442}
443
444static void
445invokeVirtual(JNIEnv *env, InvokeRequest *request)
446{
447 jbyte returnType = methodSignature_returnTag(request->methodSignature);
448 if (isReferenceTag(returnType)) {
449 jobject object;
450 JDI_ASSERT_MSG(request->instance, "Request instance null")do { if (gdata && gdata->assertOn && !(request
->instance)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 450, "Request instance null"); } } while (0)
;
451 object = JNI_FUNC_PTR(env,CallObjectMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,451), log_message_end ("%s()","CallObjectMethodA")):((void)0
)), (env))))->CallObjectMethodA))
(env,
452 request->instance,
453 request->method,
454 request->arguments);
455 request->returnValue.l = NULL((void*)0);
456 if (object != NULL((void*)0)) {
457 saveGlobalRef(env, object, &(request->returnValue.l));
458 }
459 return;
460 }
461
462 switch (returnType) {
463 case JDWP_TAG(BYTE)66:
464 request->returnValue.b = JNI_FUNC_PTR(env,CallByteMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,464), log_message_end ("%s()","CallByteMethodA")):((void)0))
, (env))))->CallByteMethodA))
(env,
465 request->instance,
466 request->method,
467 request->arguments);
468 break;
469
470 case JDWP_TAG(CHAR)67:
471 request->returnValue.c = JNI_FUNC_PTR(env,CallCharMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,471), log_message_end ("%s()","CallCharMethodA")):((void)0))
, (env))))->CallCharMethodA))
(env,
472 request->instance,
473 request->method,
474 request->arguments);
475 break;
476
477 case JDWP_TAG(FLOAT)70:
478 request->returnValue.f = JNI_FUNC_PTR(env,CallFloatMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,478), log_message_end ("%s()","CallFloatMethodA")):((void)0)
), (env))))->CallFloatMethodA))
(env,
479 request->instance,
480 request->method,
481 request->arguments);
482 break;
483
484 case JDWP_TAG(DOUBLE)68:
485 request->returnValue.d = JNI_FUNC_PTR(env,CallDoubleMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,485), log_message_end ("%s()","CallDoubleMethodA")):((void)0
)), (env))))->CallDoubleMethodA))
(env,
486 request->instance,
487 request->method,
488 request->arguments);
489 break;
490
491 case JDWP_TAG(INT)73:
492 request->returnValue.i = JNI_FUNC_PTR(env,CallIntMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,492), log_message_end ("%s()","CallIntMethodA")):((void)0)),
(env))))->CallIntMethodA))
(env,
493 request->instance,
494 request->method,
495 request->arguments);
496 break;
497
498 case JDWP_TAG(LONG)74:
499 request->returnValue.j = JNI_FUNC_PTR(env,CallLongMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,499), log_message_end ("%s()","CallLongMethodA")):((void)0))
, (env))))->CallLongMethodA))
(env,
500 request->instance,
501 request->method,
502 request->arguments);
503 break;
504
505 case JDWP_TAG(SHORT)83:
506 request->returnValue.s = JNI_FUNC_PTR(env,CallShortMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,506), log_message_end ("%s()","CallShortMethodA")):((void)0)
), (env))))->CallShortMethodA))
(env,
507 request->instance,
508 request->method,
509 request->arguments);
510 break;
511
512 case JDWP_TAG(BOOLEAN)90:
513 request->returnValue.z = JNI_FUNC_PTR(env,CallBooleanMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,513), log_message_end ("%s()","CallBooleanMethodA")):((void)
0)), (env))))->CallBooleanMethodA))
(env,
514 request->instance,
515 request->method,
516 request->arguments);
517 break;
518
519 case JDWP_TAG(VOID)86:
520 JNI_FUNC_PTR(env,CallVoidMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,520), log_message_end ("%s()","CallVoidMethodA")):((void)0))
, (env))))->CallVoidMethodA))
(env,
521 request->instance,
522 request->method,
523 request->arguments);
524 break;
525
526 default:
527 EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"Invalid method signature"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+21))), ((jvmtiError)(JVMTI_ERROR_MAX+64+21)), ("Invalid method signature"
==((void*)0)?"":"Invalid method signature"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 527); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+21)), "Invalid method signature"); }
;
528 break;
529 }
530}
531
532static void
533invokeNonvirtual(JNIEnv *env, InvokeRequest *request)
534{
535 jbyte returnType = methodSignature_returnTag(request->methodSignature);
536 if (isReferenceTag(returnType)) {
537 jobject object;
538 JDI_ASSERT_MSG(request->clazz, "Request clazz null")do { if (gdata && gdata->assertOn && !(request
->clazz)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 538, "Request clazz null"); } } while (0)
;
539 JDI_ASSERT_MSG(request->instance, "Request instance null")do { if (gdata && gdata->assertOn && !(request
->instance)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 539, "Request instance null"); } } while (0)
;
540 object = JNI_FUNC_PTR(env,CallNonvirtualObjectMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,540), log_message_end ("%s()","CallNonvirtualObjectMethodA")
):((void)0)), (env))))->CallNonvirtualObjectMethodA))
(env,
541 request->instance,
542 request->clazz,
543 request->method,
544 request->arguments);
545 request->returnValue.l = NULL((void*)0);
546 if (object != NULL((void*)0)) {
547 saveGlobalRef(env, object, &(request->returnValue.l));
548 }
549 return;
550 }
551
552 switch (returnType) {
553 case JDWP_TAG(BYTE)66:
554 request->returnValue.b = JNI_FUNC_PTR(env,CallNonvirtualByteMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,554), log_message_end ("%s()","CallNonvirtualByteMethodA")):
((void)0)), (env))))->CallNonvirtualByteMethodA))
(env,
555 request->instance,
556 request->clazz,
557 request->method,
558 request->arguments);
559 break;
560
561 case JDWP_TAG(CHAR)67:
562 request->returnValue.c = JNI_FUNC_PTR(env,CallNonvirtualCharMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,562), log_message_end ("%s()","CallNonvirtualCharMethodA")):
((void)0)), (env))))->CallNonvirtualCharMethodA))
(env,
563 request->instance,
564 request->clazz,
565 request->method,
566 request->arguments);
567 break;
568
569 case JDWP_TAG(FLOAT)70:
570 request->returnValue.f = JNI_FUNC_PTR(env,CallNonvirtualFloatMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,570), log_message_end ("%s()","CallNonvirtualFloatMethodA"))
:((void)0)), (env))))->CallNonvirtualFloatMethodA))
(env,
571 request->instance,
572 request->clazz,
573 request->method,
574 request->arguments);
575 break;
576
577 case JDWP_TAG(DOUBLE)68:
578 request->returnValue.d = JNI_FUNC_PTR(env,CallNonvirtualDoubleMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,578), log_message_end ("%s()","CallNonvirtualDoubleMethodA")
):((void)0)), (env))))->CallNonvirtualDoubleMethodA))
(env,
579 request->instance,
580 request->clazz,
581 request->method,
582 request->arguments);
583 break;
584
585 case JDWP_TAG(INT)73:
586 request->returnValue.i = JNI_FUNC_PTR(env,CallNonvirtualIntMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,586), log_message_end ("%s()","CallNonvirtualIntMethodA")):(
(void)0)), (env))))->CallNonvirtualIntMethodA))
(env,
587 request->instance,
588 request->clazz,
589 request->method,
590 request->arguments);
591 break;
592
593 case JDWP_TAG(LONG)74:
594 request->returnValue.j = JNI_FUNC_PTR(env,CallNonvirtualLongMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,594), log_message_end ("%s()","CallNonvirtualLongMethodA")):
((void)0)), (env))))->CallNonvirtualLongMethodA))
(env,
595 request->instance,
596 request->clazz,
597 request->method,
598 request->arguments);
599 break;
600
601 case JDWP_TAG(SHORT)83:
602 request->returnValue.s = JNI_FUNC_PTR(env,CallNonvirtualShortMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,602), log_message_end ("%s()","CallNonvirtualShortMethodA"))
:((void)0)), (env))))->CallNonvirtualShortMethodA))
(env,
603 request->instance,
604 request->clazz,
605 request->method,
606 request->arguments);
607 break;
608
609 case JDWP_TAG(BOOLEAN)90:
610 request->returnValue.z = JNI_FUNC_PTR(env,CallNonvirtualBooleanMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,610), log_message_end ("%s()","CallNonvirtualBooleanMethodA"
)):((void)0)), (env))))->CallNonvirtualBooleanMethodA))
(env,
611 request->instance,
612 request->clazz,
613 request->method,
614 request->arguments);
615 break;
616
617 case JDWP_TAG(VOID)86:
618 JNI_FUNC_PTR(env,CallNonvirtualVoidMethodA)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,618), log_message_end ("%s()","CallNonvirtualVoidMethodA")):
((void)0)), (env))))->CallNonvirtualVoidMethodA))
(env,
619 request->instance,
620 request->clazz,
621 request->method,
622 request->arguments);
623 break;
624
625 default:
626 EXIT_ERROR(AGENT_ERROR_NULL_POINTER,"Invalid method signature"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+21))), ((jvmtiError)(JVMTI_ERROR_MAX+64+21)), ("Invalid method signature"
==((void*)0)?"":"Invalid method signature"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 626); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+21)), "Invalid method signature"); }
;
627 break;
628 }
629}
630
631jboolean
632invoker_doInvoke(jthread thread)
633{
634 JNIEnv *env;
635 jboolean startNow;
636 InvokeRequest *request;
637 jbyte options;
638 jbyte invokeType;
639
640 JDI_ASSERT(thread)do { if (gdata && gdata->assertOn && !(thread
)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 640, "thread"); } } while (0)
;
641
642 debugMonitorEnter(invokerLock);
643
644 request = threadControl_getInvokeRequest(thread);
645 if (request == NULL((void*)0)) {
646 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+23))), ((jvmtiError)(JVMTI_ERROR_MAX+64+23)), ("getting thread invoke request"
==((void*)0)?"":"getting thread invoke request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 646); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting thread invoke request"); }
;
647 }
648
649 request->available = JNI_FALSE0;
650 startNow = request->pending && !request->started;
651
652 if (startNow) {
653 request->started = JNI_TRUE1;
654 }
655 options = request->options;
656 invokeType = request->invokeType;
657
658 debugMonitorExit(invokerLock);
659
660 if (!startNow) {
661 return JNI_FALSE0;
662 }
663
664 env = getEnv();
665
666 WITH_LOCAL_REFS(env, 2)createLocalRefSpace(env, 2); { { /* 1 for obj return values, 1 for exception */
667
668 jobject exception;
669
670 JNI_FUNC_PTR(env,ExceptionClear)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,670), log_message_end ("%s()","ExceptionClear")):((void)0)),
(env))))->ExceptionClear))
(env);
671
672 switch (invokeType) {
673 case INVOKE_CONSTRUCTOR1:
674 invokeConstructor(env, request);
675 break;
676 case INVOKE_STATIC2:
677 invokeStatic(env, request);
678 break;
679 case INVOKE_INSTANCE3:
680 if (options & JDWP_INVOKE_OPTIONS(NONVIRTUAL)0x02 ) {
681 invokeNonvirtual(env, request);
682 } else {
683 invokeVirtual(env, request);
684 }
685 break;
686 default:
687 JDI_ASSERT(JNI_FALSE)do { if (gdata && gdata->assertOn && !(0))
{ jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 687, "JNI_FALSE"); } } while (0)
;
688 }
689 request->exception = NULL((void*)0);
690 exception = JNI_FUNC_PTR(env,ExceptionOccurred)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,690), log_message_end ("%s()","ExceptionOccurred")):((void)0
)), (env))))->ExceptionOccurred))
(env);
691 if (exception != NULL((void*)0)) {
692 JNI_FUNC_PTR(env,ExceptionClear)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,692), log_message_end ("%s()","ExceptionClear")):((void)0)),
(env))))->ExceptionClear))
(env);
693 saveGlobalRef(env, exception, &(request->exception));
694 }
695
696 } END_WITH_LOCAL_REFS(env)(*((*((((gdata->log_flags & (0x00000002)) ?(log_message_begin
("JNI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
,696), log_message_end ("%s()","PopLocalFrame")):((void)0)), (
env))))->PopLocalFrame))(env, ((void*)0)); }
;
697
698 return JNI_TRUE1;
699}
700
701void
702invoker_completeInvokeRequest(jthread thread)
703{
704 JNIEnv *env = getEnv();
705 PacketOutputStream out;
706 jbyte tag;
707 jobject exc;
708 jvalue returnValue;
709 jint id;
710 InvokeRequest *request;
711 jboolean detached;
712 jboolean mustReleaseReturnValue = JNI_FALSE0;
713
714 JDI_ASSERT(thread)do { if (gdata && gdata->assertOn && !(thread
)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 714, "thread"); } } while (0)
;
1
Assuming 'gdata' is null
2
Loop condition is false. Exiting loop
715
716 /* Prevent gcc errors on uninitialized variables. */
717 tag = 0;
718 exc = NULL((void*)0);
719 id = 0;
720
721 eventHandler_lock(); /* for proper lock order */
722 debugMonitorEnter(invokerLock);
723
724 request = threadControl_getInvokeRequest(thread);
3
Value assigned to 'request'
725 if (request == NULL((void*)0)) {
4
Assuming 'request' is equal to NULL
5
Taking true branch
726 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+23))), ((jvmtiError)(JVMTI_ERROR_MAX+64+23)), ("getting thread invoke request"
==((void*)0)?"":"getting thread invoke request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 726); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting thread invoke request"); }
;
6
'?' condition is false
727 }
728
729 JDI_ASSERT(request->pending)do { if (gdata && gdata->assertOn && !(request
->pending)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 729, "request->pending"); } } while (0)
;
7
Assuming 'gdata' is non-null
8
Assuming field 'assertOn' is not equal to 0
9
Access to field 'pending' results in a dereference of a null pointer (loaded from variable 'request')
730 JDI_ASSERT(request->started)do { if (gdata && gdata->assertOn && !(request
->started)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 730, "request->started"); } } while (0)
;
731
732 request->pending = JNI_FALSE0;
733 request->started = JNI_FALSE0;
734 request->available = JNI_TRUE1; /* For next time around */
735
736 detached = request->detached;
737 if (!detached) {
738 if (request->options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED)0x01) {
739 (void)threadControl_suspendThread(thread, JNI_FALSE0);
740 } else {
741 (void)threadControl_suspendAll();
742 }
743
744 if (request->invokeType == INVOKE_CONSTRUCTOR1) {
745 /*
746 * Although constructors technically have a return type of
747 * void, we return the object created.
748 */
749 tag = specificTypeKey(env, request->returnValue.l);
750 } else {
751 tag = methodSignature_returnTag(request->methodSignature);
752 }
753 id = request->id;
754 exc = request->exception;
755 returnValue = request->returnValue;
756
757 /* Release return value and exception references, but delay the release
758 * until after the return packet was sent. */
759 jbyte returnType = methodSignature_returnTag(request->methodSignature);
760 mustReleaseReturnValue = request->invokeType == INVOKE_CONSTRUCTOR1 ||
761 isReferenceTag(returnType);
762 }
763
764 /*
765 * At this time, there's no need to retain global references on
766 * arguments since the reply is processed. No one will deal with
767 * this request ID anymore, so we must call deleteGlobalArgumentRefs().
768 *
769 * We cannot delete saved exception or return value references
770 * since otherwise a deleted handle would escape when writing
771 * the response to the stream. Instead, we clean those refs up
772 * after writing the respone.
773 */
774 deleteGlobalArgumentRefs(env, request);
775
776 /* From now on, do not access the request structure anymore
777 * for this request id, because once we give up the invokerLock it may
778 * be immediately reused by a new invoke request.
779 */
780 request = NULL((void*)0);
781
782 /*
783 * Give up the lock before I/O operation
784 */
785 debugMonitorExit(invokerLock);
786 eventHandler_unlock();
787
788 if (!detached) {
789 outStream_initReply(&out, id);
790 (void)outStream_writeValue(env, &out, tag, returnValue);
791 (void)outStream_writeObjectTag(env, &out, exc);
792 (void)outStream_writeObjectRef(env, &out, exc);
793 outStream_sendReply(&out);
794 }
795
796 /*
797 * Delete potentially saved global references of return value
798 * and exception
799 */
800 eventHandler_lock(); // for proper lock order
801 debugMonitorEnter(invokerLock);
802 if (mustReleaseReturnValue && returnValue.l != NULL((void*)0)) {
803 tossGlobalRef(env, &returnValue.l);
804 }
805 if (exc != NULL((void*)0)) {
806 tossGlobalRef(env, &exc);
807 }
808 debugMonitorExit(invokerLock);
809 eventHandler_unlock();
810}
811
812jboolean
813invoker_isEnabled(jthread thread)
814{
815 InvokeRequest *request;
816 jboolean isEnabled;
817
818 JDI_ASSERT(thread)do { if (gdata && gdata->assertOn && !(thread
)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 818, "thread"); } } while (0)
;
819 debugMonitorEnter(invokerLock);
820 request = threadControl_getInvokeRequest(thread);
821 if (request == NULL((void*)0)) {
822 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+23))), ((jvmtiError)(JVMTI_ERROR_MAX+64+23)), ("getting thread invoke request"
==((void*)0)?"":"getting thread invoke request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 822); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting thread invoke request"); }
;
823 }
824 isEnabled = request->available;
825 debugMonitorExit(invokerLock);
826 return isEnabled;
827}
828
829void
830invoker_detach(InvokeRequest *request)
831{
832 JDI_ASSERT(request)do { if (gdata && gdata->assertOn && !(request
)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c"
, 832, "request"); } } while (0)
;
833 debugMonitorEnter(invokerLock);
834 request->detached = JNI_TRUE1;
835 debugMonitorExit(invokerLock);
836}