Bug Summary

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

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 stepControl.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/stepControl.c
1/*
2 * Copyright (c) 1998, 2021, 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 "stepControl.h"
28#include "eventHandler.h"
29#include "eventHelper.h"
30#include "threadControl.h"
31#include "SDE.h"
32
33static jrawMonitorID stepLock;
34
35static jint
36getFrameCount(jthread thread)
37{
38 jint count = 0;
39 jvmtiError error;
40
41 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)(*((*((((gdata->log_flags & (0x00000004))?(log_message_begin
("JVMTI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,41), log_message_end ("%s()","GetFrameCount")):((void)0)),(gdata
->jvmti))))->GetFrameCount))
42 (gdata->jvmti, thread, &count);
43 if (error != JVMTI_ERROR_NONE) {
44 EXIT_ERROR(error, "getting frame count"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("getting frame count"
==((void*)0)?"":"getting frame count"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 44); debugInit_exit((jvmtiError)error, "getting frame count"
); }
;
45 }
46 return count;
47}
48
49/*
50 * Most enabling/disabling of JVMTI events happens implicitly through
51 * the inserting and freeing of handlers for those events. Stepping is
52 * different because requested steps are usually not identical to JVMTI steps.
53 * They usually require multiple events step, and otherwise, before they
54 * complete. While a step request is pending, we may need to temporarily
55 * disable and re-enable stepping, but we can't just remove the handlers
56 * because that would break the application's ability to remove the
57 * events. So, for step events only, we directly enable and disable stepping.
58 * This is safe because there can only ever be one pending step request
59 * per thread.
60 */
61static void
62enableStepping(jthread thread)
63{
64 jvmtiError error;
65
66 LOG_STEP(("enableStepping: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,66), log_message_end ("enableStepping: thread=%p", thread)):
((void)0))
;
67
68 error = threadControl_setEventMode(JVMTI_ENABLE, EI_SINGLE_STEP,
69 thread);
70 if (error != JVMTI_ERROR_NONE) {
71 EXIT_ERROR(error, "enabling single step"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("enabling single step"
==((void*)0)?"":"enabling single step"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 71); debugInit_exit((jvmtiError)error, "enabling single step"
); }
;
72 }
73}
74
75static void
76disableStepping(jthread thread)
77{
78 jvmtiError error;
79
80 LOG_STEP(("disableStepping: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,80), log_message_end ("disableStepping: thread=%p", thread))
:((void)0))
;
81
82 error = threadControl_setEventMode(JVMTI_DISABLE, EI_SINGLE_STEP,
83 thread);
84 if (error != JVMTI_ERROR_NONE) {
85 EXIT_ERROR(error, "disabling single step"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("disabling single step"
==((void*)0)?"":"disabling single step"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 85); debugInit_exit((jvmtiError)error, "disabling single step"
); }
;
86 }
87}
88
89static jvmtiError
90getFrameLocation(jthread thread,
91 jclass *pclazz, jmethodID *pmethod, jlocation *plocation)
92{
93 jvmtiError error;
94
95 *pclazz = NULL((void*)0);
96 *pmethod = NULL((void*)0);
97 *plocation = -1;
98
99 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)(*((*((((gdata->log_flags & (0x00000004))?(log_message_begin
("JVMTI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,99), log_message_end ("%s()","GetFrameLocation")):((void)0))
,(gdata->jvmti))))->GetFrameLocation))
100 (gdata->jvmti, thread, 0, pmethod, plocation);
101 if (error == JVMTI_ERROR_NONE && *pmethod!=NULL((void*)0) ) {
102 /* This also serves to verify that the methodID is valid */
103 error = methodClass(*pmethod, pclazz);
104 }
105 return error;
106}
107
108static void
109getLineNumberTable(jmethodID method, jint *pcount,
110 jvmtiLineNumberEntry **ptable)
111{
112 jvmtiError error;
113
114 *pcount = 0;
115 *ptable = NULL((void*)0);
116
117 /* If the method is native or obsolete, don't even ask for the line table */
118 if ( isMethodObsolete(method) || isMethodNative(method)) {
119 return;
120 }
121
122 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLineNumberTable)(*((*((((gdata->log_flags & (0x00000004))?(log_message_begin
("JVMTI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,122), log_message_end ("%s()","GetLineNumberTable")):((void)
0)),(gdata->jvmti))))->GetLineNumberTable))
123 (gdata->jvmti, method, pcount, ptable);
124 if (error != JVMTI_ERROR_NONE) {
125 *pcount = 0;
126 }
127}
128
129static jint
130findLineNumber(jthread thread, jlocation location,
131 jvmtiLineNumberEntry *lines, jint count)
132{
133 jint line = -1;
134
135 if (location != -1) {
136 if (count > 0) {
137 jint i;
138 /* any preface before first line is assigned to first line */
139 for (i=1; i<count; i++) {
140 if (location < lines[i].start_location) {
141 break;
142 }
143 }
144 line = lines[i-1].line_number;
145 }
146 }
147 return line;
148}
149
150static jboolean
151hasLineNumbers(jmethodID method)
152{
153 jint count;
154 jvmtiLineNumberEntry *table;
155
156 getLineNumberTable(method, &count, &table);
157 if ( count == 0 ) {
158 return JNI_FALSE0;
159 } else {
160 jvmtiDeallocate(table);
161 }
162 return JNI_TRUE1;
163}
164
165static jvmtiError
166initState(JNIEnv *env, jthread thread, StepRequest *step)
167{
168 jvmtiError error;
169
170 /*
171 * Initial values that may be changed below
172 */
173 step->fromLine = -1;
174 step->fromNative = JNI_FALSE0;
175 step->frameExited = JNI_FALSE0;
176 step->fromStackDepth = getFrameCount(thread);
177
178 if (step->fromStackDepth <= 0) {
179 /*
180 * If there are no stack frames, treat the step as though
181 * from a native frame. This is most likely to occur at the
182 * beginning of a debug session, right after the VM_INIT event,
183 * so we need to do something intelligent.
184 */
185 step->fromNative = JNI_TRUE1;
186 return JVMTI_ERROR_NONE;
187 }
188
189 /*
190 * Try to get a notification on frame pop. If we're in an opaque frame
191 * we won't be able to, but we can use other methods to detect that
192 * a native frame has exited.
193 *
194 * TO DO: explain the need for this notification.
195 */
196 error = JVMTI_FUNC_PTR(gdata->jvmti,NotifyFramePop)(*((*((((gdata->log_flags & (0x00000004))?(log_message_begin
("JVMTI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,196), log_message_end ("%s()","NotifyFramePop")):((void)0)),
(gdata->jvmti))))->NotifyFramePop))
197 (gdata->jvmti, thread, 0);
198 if (error == JVMTI_ERROR_OPAQUE_FRAME) {
199 step->fromNative = JNI_TRUE1;
200 error = JVMTI_ERROR_NONE;
201 /* continue without error */
202 } else if (error == JVMTI_ERROR_DUPLICATE) {
203 error = JVMTI_ERROR_NONE;
204 /* Already being notified, continue without error */
205 } else if (error != JVMTI_ERROR_NONE) {
206 return error;
207 }
208
209 LOG_STEP(("initState(): frame=%d", step->fromStackDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,209), log_message_end ("initState(): frame=%d", step->fromStackDepth
)):((void)0))
;
210
211 /*
212 * Note: we can't undo the frame pop notify, so
213 * we'll just have to let the handler ignore it if
214 * there are any errors below.
215 */
216
217 if (step->granularity == JDWP_STEP_SIZE(LINE)1 ) {
218
219 LOG_STEP(("initState(): Begin line step"))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,219), log_message_end ("initState(): Begin line step")):((void
)0))
;
220
221 WITH_LOCAL_REFS(env, 1)createLocalRefSpace(env, 1); { {
222
223 jclass clazz;
224 jmethodID method;
225 jlocation location;
226
227 error = getFrameLocation(thread, &clazz, &method, &location);
228 if (error == JVMTI_ERROR_NONE) {
229 /* Clear out previous line table only if we changed methods */
230 if ( method != step->method ) {
231 step->lineEntryCount = 0;
232 if (step->lineEntries != NULL((void*)0)) {
233 jvmtiDeallocate(step->lineEntries);
234 step->lineEntries = NULL((void*)0);
235 }
236 step->method = method;
237 getLineNumberTable(step->method,
238 &step->lineEntryCount, &step->lineEntries);
239 if (step->lineEntryCount > 0) {
240 convertLineNumberTable(env, clazz,
241 &step->lineEntryCount, &step->lineEntries);
242 }
243 }
244 step->fromLine = findLineNumber(thread, location,
245 step->lineEntries, step->lineEntryCount);
246 }
247
248 } 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/stepControl.c"
,248), log_message_end ("%s()","PopLocalFrame")):((void)0)), (
env))))->PopLocalFrame))(env, ((void*)0)); }
;
249
250 }
251
252 return error;
253}
254
255/*
256 * TO DO: The step handlers (handleFrameChange and handleStep can
257 * be broken down and made simpler now that we can install and de-install event
258 * handlers.
259 */
260static void
261handleFramePopEvent(JNIEnv *env, EventInfo *evinfo,
262 HandlerNode *node,
263 struct bag *eventBag)
264{
265 StepRequest *step;
266 jthread thread = evinfo->thread;
267
268 stepControl_lock();
269
270 step = threadControl_getStepRequest(thread);
271 if (step == NULL((void*)0)) {
272 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step 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 step request"
==((void*)0)?"":"getting step request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 272); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting step request"); }
;
273 }
274
275 if (step->pending) {
276 /*
277 * Note: current depth is reported as *before* the pending frame
278 * pop.
279 */
280 jint currentDepth;
281 jint fromDepth;
282 jint afterPopDepth;
283
284 currentDepth = getFrameCount(thread);
285 fromDepth = step->fromStackDepth;
286 afterPopDepth = currentDepth-1;
287
288 LOG_STEP(("handleFramePopEvent: BEGIN fromDepth=%d, currentDepth=%d",((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,289), log_message_end ("handleFramePopEvent: BEGIN fromDepth=%d, currentDepth=%d"
, fromDepth, currentDepth)):((void)0))
289 fromDepth, currentDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,289), log_message_end ("handleFramePopEvent: BEGIN fromDepth=%d, currentDepth=%d"
, fromDepth, currentDepth)):((void)0))
;
290
291 /*
292 * If we are exiting the original stepping frame, record that
293 * fact here. Once the next step event comes in, we can safely
294 * stop stepping there.
295 */
296 if (fromDepth > afterPopDepth ) {
297 step->frameExited = JNI_TRUE1;
298 }
299
300 if (step->depth == JDWP_STEP_DEPTH(OVER)1) {
301 /*
302 * Either
303 * 1) the original stepping frame is about to be popped
304 * [fromDepth == currentDepth]. Re-enable stepping to
305 * reach a point where we can stop.
306 * 2) a method called from the stepping frame has returned
307 * (during which we had stepping disabled)
308 * [fromDepth == currentDepth - 1]. Re-enable stepping
309 * so that we can continue instructions steps in the
310 * original stepping frame.
311 * 3) a method further down the call chain has notified
312 * of a frame pop [fromDepth < currentDepth - 1]. This
313 * *might* represent case (2) above if the stepping frame
314 * was calling a native method which in turn called a
315 * java method. If so, we must enable stepping to
316 * ensure that we get control back after the intervening
317 * native frame is popped (you can't get frame pop
318 * notifications on native frames). If the native caller
319 * calls another Java method before returning,
320 * stepping will be diabled again and another frame pop
321 * will be awaited.
322 *
323 * If it turns out that this is not case (2) with native
324 * methods, then the enabled stepping is benign and
325 * will be disabled again on the next step event.
326 *
327 * Note that the condition not covered above,
328 * [fromDepth > currentDepth] shouldn't happen since it means
329 * that too many frames have been popped. For robustness,
330 * we enable stepping in that case too, so that the errant
331 * step-over can be stopped.
332 *
333 */
334 LOG_STEP(("handleFramePopEvent: starting singlestep, depth==OVER"))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,334), log_message_end ("handleFramePopEvent: starting singlestep, depth==OVER"
)):((void)0))
;
335 enableStepping(thread);
336 } else if (step->depth == JDWP_STEP_DEPTH(OUT)2 &&
337 fromDepth > afterPopDepth) {
338 /*
339 * The original stepping frame is about to be popped. Step
340 * until we reach the next safe place to stop.
341 */
342 LOG_STEP(("handleFramePopEvent: starting singlestep, depth==OUT && fromDepth > afterPopDepth (%d>%d)",fromDepth, afterPopDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,342), log_message_end ("handleFramePopEvent: starting singlestep, depth==OUT && fromDepth > afterPopDepth (%d>%d)"
,fromDepth, afterPopDepth)):((void)0))
;
343 enableStepping(thread);
344 } else if (step->methodEnterHandlerNode != NULL((void*)0)) {
345 /* We installed a method entry event handler as part of a step into operation. */
346 JDI_ASSERT(step->depth == JDWP_STEP_DEPTH(INTO))do { if (gdata && gdata->assertOn && !(step
->depth == 0)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 346, "step->depth == JDWP_STEP_DEPTH(INTO)"); } } while (
0)
;
347 if (fromDepth >= afterPopDepth) {
348 /*
349 * We've popped back to the original stepping frame without finding a place to stop.
350 * Resume stepping in the original frame.
351 */
352 LOG_STEP(("handleFramePopEvent: starting singlestep, have methodEnter handler && depth==INTO && fromDepth >= afterPopDepth (%d>=%d)", fromDepth, afterPopDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,352), log_message_end ("handleFramePopEvent: starting singlestep, have methodEnter handler && depth==INTO && fromDepth >= afterPopDepth (%d>=%d)"
, fromDepth, afterPopDepth)):((void)0))
;
353 enableStepping(thread);
354 (void)eventHandler_free(step->methodEnterHandlerNode);
355 step->methodEnterHandlerNode = NULL((void*)0);
356 } else {
357 LOG_STEP(("handleFramePopEvent: starting singlestep, have methodEnter handler && depth==INTO && fromDepth < afterPopDepth (%d<%d)", fromDepth, afterPopDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,357), log_message_end ("handleFramePopEvent: starting singlestep, have methodEnter handler && depth==INTO && fromDepth < afterPopDepth (%d<%d)"
, fromDepth, afterPopDepth)):((void)0))
;
358 }
359 }
360 LOG_STEP(("handleFramePopEvent: finished"))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,360), log_message_end ("handleFramePopEvent: finished")):((void
)0))
;
361 }
362
363 stepControl_unlock();
364}
365
366static void
367handleExceptionCatchEvent(JNIEnv *env, EventInfo *evinfo,
368 HandlerNode *node,
369 struct bag *eventBag)
370{
371 StepRequest *step;
372 jthread thread = evinfo->thread;
373
374 stepControl_lock();
375
376 step = threadControl_getStepRequest(thread);
1
Value assigned to 'step'
377 if (step == NULL((void*)0)) {
2
Assuming 'step' is equal to NULL
3
Taking true branch
378 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step 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 step request"
==((void*)0)?"":"getting step request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 378); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting step request"); }
;
4
'?' condition is false
379 }
380
381 if (step->pending) {
5
Access to field 'pending' results in a dereference of a null pointer (loaded from variable 'step')
382 /*
383 * Determine where we are on the call stack relative to where
384 * we started.
385 */
386 jint currentDepth = getFrameCount(thread);
387 jint fromDepth = step->fromStackDepth;
388
389 LOG_STEP(("handleExceptionCatchEvent: fromDepth=%d, currentDepth=%d",((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,390), log_message_end ("handleExceptionCatchEvent: fromDepth=%d, currentDepth=%d"
, fromDepth, currentDepth)):((void)0))
390 fromDepth, currentDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,390), log_message_end ("handleExceptionCatchEvent: fromDepth=%d, currentDepth=%d"
, fromDepth, currentDepth)):((void)0))
;
391
392 /*
393 * If we are exiting the original stepping frame, record that
394 * fact here. Once the next step event comes in, we can safely
395 * stop stepping there.
396 */
397 if (fromDepth > currentDepth) {
398 step->frameExited = JNI_TRUE1;
399 }
400
401 if (step->depth == JDWP_STEP_DEPTH(OVER)1 &&
402 fromDepth >= currentDepth) {
403 /*
404 * Either the original stepping frame is done,
405 * or a called method has returned (during which we had stepping
406 * disabled). In either case we must resume stepping.
407 */
408 enableStepping(thread);
409 } else if (step->depth == JDWP_STEP_DEPTH(OUT)2 &&
410 fromDepth > currentDepth) {
411 /*
412 * The original stepping frame is done. Step
413 * until we reach the next safe place to stop.
414 */
415 enableStepping(thread);
416 } else if (step->methodEnterHandlerNode != NULL((void*)0) &&
417 fromDepth >= currentDepth) {
418 /*
419 * We installed a method entry event handler as part of a
420 * step into operation. We've popped back to the original
421 * stepping frame or higher without finding a place to stop.
422 * Resume stepping in the original frame.
423 */
424 enableStepping(thread);
425 (void)eventHandler_free(step->methodEnterHandlerNode);
426 step->methodEnterHandlerNode = NULL((void*)0);
427 }
428 }
429
430 stepControl_unlock();
431}
432
433static void
434handleMethodEnterEvent(JNIEnv *env, EventInfo *evinfo,
435 HandlerNode *node,
436 struct bag *eventBag)
437{
438 StepRequest *step;
439 jthread thread;
440
441 thread = evinfo->thread;
442
443 stepControl_lock();
444
445 step = threadControl_getStepRequest(thread);
446 if (step == NULL((void*)0)) {
447 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step 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 step request"
==((void*)0)?"":"getting step request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 447); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting step request"); }
;
448 }
449
450 if (step->pending) {
451 jclass clazz;
452 jmethodID method;
453 char *classname;
454
455 LOG_STEP(("handleMethodEnterEvent: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,455), log_message_end ("handleMethodEnterEvent: thread=%p", thread
)):((void)0))
;
456
457 clazz = evinfo->clazz;
458 method = evinfo->method;
459 classname = getClassname(clazz);
460
461 /*
462 * This handler is relevant only to step into
463 */
464 JDI_ASSERT(step->depth == JDWP_STEP_DEPTH(INTO))do { if (gdata && gdata->assertOn && !(step
->depth == 0)) { jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 464, "step->depth == JDWP_STEP_DEPTH(INTO)"); } } while (
0)
;
465
466 if ( (!eventFilter_predictFiltering(step->stepHandlerNode,
467 clazz, classname))
468 && ( step->granularity != JDWP_STEP_SIZE(LINE)1
469 || hasLineNumbers(method) ) ) {
470 /*
471 * We've found a suitable method in which to stop. Step
472 * until we reach the next safe location to complete the step->,
473 * and we can get rid of the method entry handler.
474 */
475 enableStepping(thread);
476 if ( step->methodEnterHandlerNode != NULL((void*)0) ) {
477 (void)eventHandler_free(step->methodEnterHandlerNode);
478 step->methodEnterHandlerNode = NULL((void*)0);
479 }
480 }
481 jvmtiDeallocate(classname);
482 classname = NULL((void*)0);
483 }
484
485 stepControl_unlock();
486}
487
488static void
489completeStep(JNIEnv *env, jthread thread, StepRequest *step)
490{
491 jvmtiError error;
492
493 /*
494 * We've completed a step; reset state for the next one, if any
495 */
496
497 LOG_STEP(("completeStep: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,497), log_message_end ("completeStep: thread=%p", thread)):(
(void)0))
;
498
499 if (step->methodEnterHandlerNode != NULL((void*)0)) {
500 (void)eventHandler_free(step->methodEnterHandlerNode);
501 step->methodEnterHandlerNode = NULL((void*)0);
502 }
503
504 error = initState(env, thread, step);
505 if (error != JVMTI_ERROR_NONE) {
506 /*
507 * None of the initState errors should happen after one step
508 * has successfully completed.
509 */
510 EXIT_ERROR(error, "initializing step state"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("initializing step state"
==((void*)0)?"":"initializing step state"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 510); debugInit_exit((jvmtiError)error, "initializing step state"
); }
;
511 }
512}
513
514jboolean
515stepControl_handleStep(JNIEnv *env, jthread thread,
516 jclass clazz, jmethodID method)
517{
518 jboolean completed = JNI_FALSE0;
519 StepRequest *step;
520 jint currentDepth;
521 jint fromDepth;
522 jvmtiError error;
523 char *classname;
524
525 classname = NULL((void*)0);
526 stepControl_lock();
527
528 step = threadControl_getStepRequest(thread);
529 if (step == NULL((void*)0)) {
530 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step 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 step request"
==((void*)0)?"":"getting step request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 530); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting step request"); }
;
531 }
532
533 /*
534 * If no step is currently pending, ignore the event
535 */
536 if (!step->pending) {
537 goto done;
538 }
539
540 LOG_STEP(("stepControl_handleStep: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,540), log_message_end ("stepControl_handleStep: thread=%p", thread
)):((void)0))
;
541
542 /*
543 * We never filter step into instruction. It's always over on the
544 * first step event.
545 */
546 if (step->depth == JDWP_STEP_DEPTH(INTO)0 &&
547 step->granularity == JDWP_STEP_SIZE(MIN)0) {
548 completed = JNI_TRUE1;
549 LOG_STEP(("stepControl_handleStep: completed, into min"))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,549), log_message_end ("stepControl_handleStep: completed, into min"
)):((void)0))
;
550 goto done;
551 }
552
553 /*
554 * If we have left the method in which
555 * stepping started, the step is always complete.
556 */
557 if (step->frameExited) {
558 completed = JNI_TRUE1;
559 LOG_STEP(("stepControl_handleStep: completed, frame exited"))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,559), log_message_end ("stepControl_handleStep: completed, frame exited"
)):((void)0))
;
560 goto done;
561 }
562
563 /*
564 * Determine where we are on the call stack relative to where
565 * we started.
566 */
567 currentDepth = getFrameCount(thread);
568 fromDepth = step->fromStackDepth;
569
570 if (fromDepth > currentDepth) {
571 /*
572 * We have returned from the caller. There are cases where
573 * we don't get frame pop notifications
574 * (e.g. stepping from opaque frames), and that's when
575 * this code will be reached. Complete the step->
576 */
577 completed = JNI_TRUE1;
578 LOG_STEP(("stepControl_handleStep: completed, fromDepth>currentDepth(%d>%d)", fromDepth, currentDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,578), log_message_end ("stepControl_handleStep: completed, fromDepth>currentDepth(%d>%d)"
, fromDepth, currentDepth)):((void)0))
;
579 } else if (fromDepth < currentDepth) {
580 /* We have dropped into a called method. */
581 if ( step->depth == JDWP_STEP_DEPTH(INTO)0
582 && (!eventFilter_predictFiltering(step->stepHandlerNode, clazz,
583 (classname = getClassname(clazz))))
584 && hasLineNumbers(method) ) {
585
586 /* Stepped into a method with lines, so we're done */
587 completed = JNI_TRUE1;
588 LOG_STEP(("stepControl_handleStep: completed, fromDepth<currentDepth(%d<%d) and into method with lines", fromDepth, currentDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,588), log_message_end ("stepControl_handleStep: completed, fromDepth<currentDepth(%d<%d) and into method with lines"
, fromDepth, currentDepth)):((void)0))
;
589 } else {
590 /*
591 * We need to continue, but don't want the overhead of step
592 * events from this method. So, we disable stepping and
593 * enable a frame pop. If we're stepping into, we also
594 * enable method enter events because a called frame may be
595 * where we want to stop.
596 */
597 disableStepping(thread);
598
599 if (step->depth == JDWP_STEP_DEPTH(INTO)0) {
600 step->methodEnterHandlerNode =
601 eventHandler_createInternalThreadOnly(
602 EI_METHOD_ENTRY,
603 handleMethodEnterEvent, thread);
604 if (step->methodEnterHandlerNode == NULL((void*)0)) {
605 EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,{ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+24))), ((jvmtiError)(JVMTI_ERROR_MAX+64+24)), ("installing event method enter handler"
==((void*)0)?"":"installing event method enter handler"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 606); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+24)), "installing event method enter handler"); }
606 "installing event method enter handler"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+24))), ((jvmtiError)(JVMTI_ERROR_MAX+64+24)), ("installing event method enter handler"
==((void*)0)?"":"installing event method enter handler"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 606); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+24)), "installing event method enter handler"); }
;
607 }
608 }
609 LOG_STEP(("stepControl_handleStep: NotifyFramePop (fromDepth=%d currentDepth=%d)",((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,610), log_message_end ("stepControl_handleStep: NotifyFramePop (fromDepth=%d currentDepth=%d)"
, fromDepth, currentDepth)):((void)0))
610 fromDepth, currentDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,610), log_message_end ("stepControl_handleStep: NotifyFramePop (fromDepth=%d currentDepth=%d)"
, fromDepth, currentDepth)):((void)0))
;
611
612 error = JVMTI_FUNC_PTR(gdata->jvmti,NotifyFramePop)(*((*((((gdata->log_flags & (0x00000004))?(log_message_begin
("JVMTI","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,612), log_message_end ("%s()","NotifyFramePop")):((void)0)),
(gdata->jvmti))))->NotifyFramePop))
613 (gdata->jvmti, thread, 0);
614 if (error == JVMTI_ERROR_DUPLICATE) {
615 error = JVMTI_ERROR_NONE;
616 } else if (error != JVMTI_ERROR_NONE) {
617 EXIT_ERROR(error, "setting up notify frame pop"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("setting up notify frame pop"
==((void*)0)?"":"setting up notify frame pop"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 617); debugInit_exit((jvmtiError)error, "setting up notify frame pop"
); }
;
618 }
619 }
620 jvmtiDeallocate(classname);
621 classname = NULL((void*)0);
622 } else {
623 /*
624 * We are at the same stack depth where stepping started.
625 * Instruction steps are complete at this point. For line
626 * steps we must check to see whether we've moved to a
627 * different line.
628 */
629 if (step->granularity == JDWP_STEP_SIZE(MIN)0) {
630 completed = JNI_TRUE1;
631 LOG_STEP(("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and min", fromDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,631), log_message_end ("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and min"
, fromDepth)):((void)0))
;
632 } else {
633 if (step->fromLine != -1) {
634 jint line = -1;
635 jlocation location;
636 jmethodID method;
637 WITH_LOCAL_REFS(env, 1)createLocalRefSpace(env, 1); { {
638 jclass clazz;
639 error = getFrameLocation(thread,
640 &clazz, &method, &location);
641 if ( isMethodObsolete(method)) {
642 method = NULL((void*)0);
643 location = -1;
644 }
645 if (error != JVMTI_ERROR_NONE || location == -1) {
646 EXIT_ERROR(error, "getting frame location"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("getting frame location"
==((void*)0)?"":"getting frame location"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 646); debugInit_exit((jvmtiError)error, "getting frame location"
); }
;
647 }
648 if ( method == step->method ) {
649 LOG_STEP(("stepControl_handleStep: checking line location"))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,649), log_message_end ("stepControl_handleStep: checking line location"
)):((void)0))
;
650 log_debugee_location("stepControl_handleStep: checking line loc",
651 thread, method, location);
652 line = findLineNumber(thread, location,
653 step->lineEntries, step->lineEntryCount);
654 }
655 if (line != step->fromLine) {
656 completed = JNI_TRUE1;
657 LOG_STEP(("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and different line", fromDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,657), log_message_end ("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and different line"
, fromDepth)):((void)0))
;
658 }
659 } 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/stepControl.c"
,659), log_message_end ("%s()","PopLocalFrame")):((void)0)), (
env))))->PopLocalFrame))(env, ((void*)0)); }
;
660 } else {
661 /*
662 * This is a rare case. We have stepped from a location
663 * inside a native method to a location within a Java
664 * method at the same stack depth. This means that
665 * the original native method returned to another
666 * native method which, in turn, invoked a Java method.
667 *
668 * Since the original frame was native, we were unable
669 * to ask for a frame pop event, and, thus, could not
670 * set the step->frameExited flag when the original
671 * method was done. Instead we end up here
672 * and act just as though the frameExited flag was set
673 * and complete the step immediately.
674 */
675 completed = JNI_TRUE1;
676 LOG_STEP(("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and no line", fromDepth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,676), log_message_end ("stepControl_handleStep: completed, fromDepth==currentDepth(%d) and no line"
, fromDepth)):((void)0))
;
677 }
678 }
679 LOG_STEP(("stepControl_handleStep: finished"))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,679), log_message_end ("stepControl_handleStep: finished")):
((void)0))
;
680 }
681done:
682 if (completed) {
683 completeStep(env, thread, step);
684 }
685 stepControl_unlock();
686 return completed;
687}
688
689
690void
691stepControl_initialize(void)
692{
693 stepLock = debugMonitorCreate("JDWP Step Handler Lock");
694}
695
696void
697stepControl_reset(void)
698{
699}
700
701/*
702 * Reset step control request stack depth and line number.
703 */
704void
705stepControl_resetRequest(jthread thread)
706{
707
708 StepRequest *step;
709 jvmtiError error;
710
711 LOG_STEP(("stepControl_resetRequest: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,711), log_message_end ("stepControl_resetRequest: thread=%p"
, thread)):((void)0))
;
712
713 stepControl_lock();
714
715 step = threadControl_getStepRequest(thread);
716
717 if (step != NULL((void*)0)) {
718 JNIEnv *env;
719 env = getEnv();
720 error = initState(env, thread, step);
721 if (error != JVMTI_ERROR_NONE) {
722 EXIT_ERROR(error, "initializing step state"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("initializing step state"
==((void*)0)?"":"initializing step state"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 722); debugInit_exit((jvmtiError)error, "initializing step state"
); }
;
723 }
724 } else {
725 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting step 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 step request"
==((void*)0)?"":"getting step request"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 725); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+23)), "getting step request"); }
;
726 }
727
728 stepControl_unlock();
729}
730
731static void
732initEvents(jthread thread, StepRequest *step)
733{
734 /* Need to install frame pop handler and exception catch handler when
735 * single-stepping is enabled (i.e. step-into or step-over/step-out
736 * when fromStackDepth > 0).
737 */
738 if (step->depth == JDWP_STEP_DEPTH(INTO)0 || step->fromStackDepth > 0) {
739 /*
740 * TO DO: These might be able to applied more selectively to
741 * boost performance.
742 */
743 step->catchHandlerNode = eventHandler_createInternalThreadOnly(
744 EI_EXCEPTION_CATCH,
745 handleExceptionCatchEvent,
746 thread);
747 JDI_ASSERT(step->framePopHandlerNode == NULL)do { if (gdata && gdata->assertOn && !(step
->framePopHandlerNode == ((void*)0))) { jdiAssertionFailed
("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 747, "step->framePopHandlerNode == NULL"); } } while (0)
;
748 step->framePopHandlerNode = eventHandler_createInternalThreadOnly(
749 EI_FRAME_POP,
750 handleFramePopEvent,
751 thread);
752
753 if (step->catchHandlerNode == NULL((void*)0) ||
754 step->framePopHandlerNode == NULL((void*)0)) {
755 EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,{ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+24))), ((jvmtiError)(JVMTI_ERROR_MAX+64+24)), ("installing step event handlers"
==((void*)0)?"":"installing step event handlers"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 756); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+24)), "installing step event handlers"); }
756 "installing step event handlers"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX+64
+24))), ((jvmtiError)(JVMTI_ERROR_MAX+64+24)), ("installing step event handlers"
==((void*)0)?"":"installing step event handlers"), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 756); debugInit_exit((jvmtiError)((jvmtiError)(JVMTI_ERROR_MAX
+64+24)), "installing step event handlers"); }
;
757 }
758
759 }
760 /*
761 * Initially enable stepping:
762 * 1) For step into, always
763 * 2) For step over, unless right after the VM_INIT.
764 * Enable stepping for STEP_MIN or STEP_LINE with or without line numbers.
765 * If the class is redefined then non EMCP methods may not have line
766 * number info. So enable line stepping for non line number so that it
767 * behaves like STEP_MIN/STEP_OVER.
768 * 3) For step out, only if stepping from native, except right after VM_INIT
769 *
770 * (right after VM_INIT, a step->over or out is identical to running
771 * forever)
772 */
773 switch (step->depth) {
774 case JDWP_STEP_DEPTH(INTO)0:
775 enableStepping(thread);
776 break;
777 case JDWP_STEP_DEPTH(OVER)1:
778 if (step->fromStackDepth > 0 && !step->fromNative ) {
779 enableStepping(thread);
780 }
781 break;
782 case JDWP_STEP_DEPTH(OUT)2:
783 if (step->fromNative &&
784 (step->fromStackDepth > 0)) {
785 enableStepping(thread);
786 }
787 break;
788 default:
789 JDI_ASSERT(JNI_FALSE)do { if (gdata && gdata->assertOn && !(0))
{ jdiAssertionFailed("/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 789, "JNI_FALSE"); } } while (0)
;
790 }
791}
792
793jvmtiError
794stepControl_beginStep(JNIEnv *env, jthread thread, jint size, jint depth,
795 HandlerNode *node)
796{
797 StepRequest *step;
798 jvmtiError error;
799 jvmtiError error2;
800
801 LOG_STEP(("stepControl_beginStep: thread=%p,size=%d,depth=%d",((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,802), log_message_end ("stepControl_beginStep: thread=%p,size=%d,depth=%d"
, thread, size, depth)):((void)0))
802 thread, size, depth))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,802), log_message_end ("stepControl_beginStep: thread=%p,size=%d,depth=%d"
, thread, size, depth)):((void)0))
;
803
804 eventHandler_lock(); /* for proper lock order */
805 stepControl_lock();
806
807 step = threadControl_getStepRequest(thread);
808 if (step == NULL((void*)0)) {
809 error = AGENT_ERROR_INVALID_THREAD((jvmtiError)(JVMTI_ERROR_MAX+64+23));
810 /* Normally not getting a StepRequest struct pointer is a fatal error
811 * but on a beginStep, we just return an error code.
812 */
813 } else {
814 /*
815 * In case the thread isn't already suspended, do it again.
816 */
817 error = threadControl_suspendThread(thread, JNI_FALSE0);
818 if (error == JVMTI_ERROR_NONE) {
819 /*
820 * Overwrite any currently executing step.
821 */
822 step->granularity = size;
823 step->depth = depth;
824 step->catchHandlerNode = NULL((void*)0);
825 step->framePopHandlerNode = NULL((void*)0);
826 step->methodEnterHandlerNode = NULL((void*)0);
827 step->stepHandlerNode = node;
828 error = initState(env, thread, step);
829 if (error == JVMTI_ERROR_NONE) {
830 initEvents(thread, step);
831 }
832 /* false means it is not okay to unblock the commandLoop thread */
833 error2 = threadControl_resumeThread(thread, JNI_FALSE0);
834 if (error2 != JVMTI_ERROR_NONE && error == JVMTI_ERROR_NONE) {
835 error = error2;
836 }
837
838 /*
839 * If everything went ok, indicate a step is pending.
840 */
841 if (error == JVMTI_ERROR_NONE) {
842 step->pending = JNI_TRUE1;
843 }
844 } else {
845 EXIT_ERROR(error, "stepControl_beginStep: cannot suspend thread"){ print_message(stderr, "JDWP exit error ", "\n", "%s(%d): %s [%s:%d]"
, jvmtiErrorText((jvmtiError)error), error, ("stepControl_beginStep: cannot suspend thread"
==((void*)0)?"":"stepControl_beginStep: cannot suspend thread"
), "/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
, 845); debugInit_exit((jvmtiError)error, "stepControl_beginStep: cannot suspend thread"
); }
;
846 }
847 }
848
849 stepControl_unlock();
850 eventHandler_unlock();
851
852 return error;
853}
854
855
856static void
857clearStep(jthread thread, StepRequest *step)
858{
859 if (step->pending) {
860
861 disableStepping(thread);
862 if ( step->catchHandlerNode != NULL((void*)0) ) {
863 (void)eventHandler_free(step->catchHandlerNode);
864 step->catchHandlerNode = NULL((void*)0);
865 }
866 if ( step->framePopHandlerNode!= NULL((void*)0) ) {
867 (void)eventHandler_free(step->framePopHandlerNode);
868 step->framePopHandlerNode = NULL((void*)0);
869 }
870 if ( step->methodEnterHandlerNode != NULL((void*)0) ) {
871 (void)eventHandler_free(step->methodEnterHandlerNode);
872 step->methodEnterHandlerNode = NULL((void*)0);
873 }
874 step->pending = JNI_FALSE0;
875
876 /*
877 * Warning: Do not clear step->method, step->lineEntryCount,
878 * or step->lineEntries here, they will likely
879 * be needed on the next step.
880 */
881
882 }
883}
884
885jvmtiError
886stepControl_endStep(jthread thread)
887{
888 StepRequest *step;
889 jvmtiError error;
890
891 LOG_STEP(("stepControl_endStep: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,891), log_message_end ("stepControl_endStep: thread=%p", thread
)):((void)0))
;
892
893 eventHandler_lock(); /* for proper lock order */
894 stepControl_lock();
895
896 step = threadControl_getStepRequest(thread);
897 if (step != NULL((void*)0)) {
898 clearStep(thread, step);
899 error = JVMTI_ERROR_NONE;
900 } else {
901 /* If the stepRequest can't be gotten, then this thread no longer
902 * exists, just return, don't die here, this is normal at
903 * termination time. Return JVMTI_ERROR_NONE so the thread Ref
904 * can be tossed.
905 */
906 error = JVMTI_ERROR_NONE;
907 }
908
909 stepControl_unlock();
910 eventHandler_unlock();
911
912 return error;
913}
914
915void
916stepControl_clearRequest(jthread thread, StepRequest *step)
917{
918 LOG_STEP(("stepControl_clearRequest: thread=%p", thread))((gdata->log_flags & (0x00000010)) ?(log_message_begin
("STEP","/home/daniel/Projects/java/jdk/src/jdk.jdwp.agent/share/native/libjdwp/stepControl.c"
,918), log_message_end ("stepControl_clearRequest: thread=%p"
, thread)):((void)0))
;
919 clearStep(thread, step);
920}
921
922void
923stepControl_lock(void)
924{
925 debugMonitorEnter(stepLock);
926}
927
928void
929stepControl_unlock(void)
930{
931 debugMonitorExit(stepLock);
932}