1 /*
2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.hpp"
27 #include "classfile/javaClasses.inline.hpp"
28 #include "classfile/vmSymbols.hpp"
29 #include "logging/log.hpp"
30 #include "logging/logStream.hpp"
31 #include "memory/oopFactory.hpp"
32 #include "memory/universe.hpp"
33 #include "oops/oop.inline.hpp"
34 #include "oops/objArrayOop.inline.hpp"
35 #include "prims/stackwalk.hpp"
36 #include "runtime/globals.hpp"
37 #include "runtime/handles.inline.hpp"
38 #include "runtime/javaCalls.hpp"
39 #include "runtime/thread.inline.hpp"
40 #include "runtime/vframe.inline.hpp"
41 #include "utilities/globalDefinitions.hpp"
42 
43 // setup and cleanup actions
setup_magic_on_entry(objArrayHandle frames_array)44 void BaseFrameStream::setup_magic_on_entry(objArrayHandle frames_array) {
45   frames_array->obj_at_put(magic_pos, _thread->threadObj());
46   _anchor = address_value();
47   assert(check_magic(frames_array), "invalid magic");
48 }
49 
check_magic(objArrayHandle frames_array)50 bool BaseFrameStream::check_magic(objArrayHandle frames_array) {
51   oop   m1 = frames_array->obj_at(magic_pos);
52   jlong m2 = _anchor;
53   if (m1 == _thread->threadObj() && m2 == address_value())  return true;
54   return false;
55 }
56 
cleanup_magic_on_exit(objArrayHandle frames_array)57 bool BaseFrameStream::cleanup_magic_on_exit(objArrayHandle frames_array) {
58   bool ok = check_magic(frames_array);
59   frames_array->obj_at_put(magic_pos, NULL);
60   _anchor = 0L;
61   return ok;
62 }
63 
JavaFrameStream(JavaThread * thread,int mode)64 JavaFrameStream::JavaFrameStream(JavaThread* thread, int mode)
65   : BaseFrameStream(thread), _vfst(thread) {
66   _need_method_info = StackWalk::need_method_info(mode);
67 }
68 
next()69 void JavaFrameStream::next() { _vfst.next();}
70 
71 // Returns the BaseFrameStream for the current stack being traversed.
72 //
73 // Parameters:
74 //  thread         Current Java thread.
75 //  magic          Magic value used for each stack walking
76 //  frames_array   User-supplied buffers.  The 0th element is reserved
77 //                 for this BaseFrameStream to use
78 //
from_current(JavaThread * thread,jlong magic,objArrayHandle frames_array)79 BaseFrameStream* BaseFrameStream::from_current(JavaThread* thread, jlong magic,
80                                                objArrayHandle frames_array)
81 {
82   assert(thread != NULL && thread->is_Java_thread(), "");
83   oop m1 = frames_array->obj_at(magic_pos);
84   if (m1 != thread->threadObj()) return NULL;
85   if (magic == 0L)                    return NULL;
86   BaseFrameStream* stream = (BaseFrameStream*) (intptr_t) magic;
87   if (!stream->is_valid_in(thread, frames_array))   return NULL;
88   return stream;
89 }
90 
91 // Unpacks one or more frames into user-supplied buffers.
92 // Updates the end index, and returns the number of unpacked frames.
93 // Always start with the existing vfst.method and bci.
94 // Do not call vfst.next to advance over the last returned value.
95 // In other words, do not leave any stale data in the vfst.
96 //
97 // Parameters:
98 //   mode             Restrict which frames to be decoded.
99 //   BaseFrameStream  stream of frames
100 //   max_nframes      Maximum number of frames to be filled.
101 //   start_index      Start index to the user-supplied buffers.
102 //   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
103 //                    frames array is a Class<?>[] array when only getting caller
104 //                    reference, and a StackFrameInfo[] array (or derivative)
105 //                    otherwise. It should never be null.
106 //   end_index        End index to the user-supplied buffers with unpacked frames.
107 //
108 // Returns the number of frames whose information was transferred into the buffers.
109 //
fill_in_frames(jlong mode,BaseFrameStream & stream,int max_nframes,int start_index,objArrayHandle frames_array,int & end_index,TRAPS)110 int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream,
111                               int max_nframes, int start_index,
112                               objArrayHandle  frames_array,
113                               int& end_index, TRAPS) {
114   log_debug(stackwalk)("fill_in_frames limit=%d start=%d frames length=%d",
115                        max_nframes, start_index, frames_array->length());
116   assert(max_nframes > 0, "invalid max_nframes");
117   assert(start_index + max_nframes <= frames_array->length(), "oob");
118 
119   int frames_decoded = 0;
120   for (; !stream.at_end(); stream.next()) {
121     Method* method = stream.method();
122 
123     if (method == NULL) continue;
124 
125     // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES
126     // not set) and when StackWalker::getCallerClass is called
127     if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) {
128       if (method->is_hidden()) {
129         LogTarget(Debug, stackwalk) lt;
130         if (lt.is_enabled()) {
131           ResourceMark rm(THREAD);
132           LogStream ls(lt);
133           ls.print("  hidden method: ");
134           method->print_short_name(&ls);
135           ls.cr();
136         }
137         continue;
138       }
139     }
140 
141     int index = end_index++;
142     LogTarget(Debug, stackwalk) lt;
143     if (lt.is_enabled()) {
144       ResourceMark rm(THREAD);
145       LogStream ls(lt);
146       ls.print("  %d: frame method: ", index);
147       method->print_short_name(&ls);
148       ls.print_cr(" bci=%d", stream.bci());
149     }
150 
151     if (!need_method_info(mode) && get_caller_class(mode) &&
152           index == start_index && method->caller_sensitive()) {
153       ResourceMark rm(THREAD);
154       THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(),
155         err_msg("StackWalker::getCallerClass called from @CallerSensitive '%s' method",
156                 method->external_name()));
157     }
158     // fill in StackFrameInfo and initialize MemberName
159     stream.fill_frame(index, frames_array, methodHandle(THREAD, method), CHECK_0);
160     if (++frames_decoded >= max_nframes)  break;
161   }
162   return frames_decoded;
163 }
164 
165 // Fill in the LiveStackFrameInfo at the given index in frames_array
fill_frame(int index,objArrayHandle frames_array,const methodHandle & method,TRAPS)166 void LiveFrameStream::fill_frame(int index, objArrayHandle  frames_array,
167                                  const methodHandle& method, TRAPS) {
168   HandleMark hm(THREAD);
169   Handle stackFrame(THREAD, frames_array->obj_at(index));
170   fill_live_stackframe(stackFrame, method, CHECK);
171 }
172 
173 // Fill in the StackFrameInfo at the given index in frames_array
fill_frame(int index,objArrayHandle frames_array,const methodHandle & method,TRAPS)174 void JavaFrameStream::fill_frame(int index, objArrayHandle  frames_array,
175                                  const methodHandle& method, TRAPS) {
176   if (_need_method_info) {
177     HandleMark hm(THREAD);
178     Handle stackFrame(THREAD, frames_array->obj_at(index));
179     fill_stackframe(stackFrame, method, CHECK);
180   } else {
181     frames_array->obj_at_put(index, method->method_holder()->java_mirror());
182   }
183 }
184 
185 // Create and return a LiveStackFrame.PrimitiveSlot (if needed) for the
186 // StackValue at the given index. 'type' is expected to be T_INT, T_LONG,
187 // T_OBJECT, or T_CONFLICT.
create_primitive_slot_instance(StackValueCollection * values,int i,BasicType type,TRAPS)188 oop LiveFrameStream::create_primitive_slot_instance(StackValueCollection* values,
189                                                     int i, BasicType type, TRAPS) {
190   Klass* k = SystemDictionary::resolve_or_null(vmSymbols::java_lang_LiveStackFrameInfo(), CHECK_NULL);
191   InstanceKlass* ik = InstanceKlass::cast(k);
192 
193   JavaValue result(T_OBJECT);
194   JavaCallArguments args;
195   Symbol* signature = NULL;
196 
197   // ## TODO: type is only available in LocalVariable table, if present.
198   // ## StackValue type is T_INT or T_OBJECT (or converted to T_LONG on 64-bit)
199   switch (type) {
200     case T_INT:
201       args.push_int(values->int_at(i));
202       signature = vmSymbols::asPrimitive_int_signature();
203       break;
204 
205     case T_LONG:
206       args.push_long(values->long_at(i));
207       signature = vmSymbols::asPrimitive_long_signature();
208       break;
209 
210     case T_FLOAT:
211     case T_DOUBLE:
212     case T_BYTE:
213     case T_SHORT:
214     case T_CHAR:
215     case T_BOOLEAN:
216       THROW_MSG_(vmSymbols::java_lang_InternalError(), "Unexpected StackValue type", NULL);
217 
218     case T_OBJECT:
219       return values->obj_at(i)();
220 
221     case T_CONFLICT:
222       // put a non-null slot
223       #ifdef _LP64
224         args.push_long(0);
225         signature = vmSymbols::asPrimitive_long_signature();
226       #else
227         args.push_int(0);
228         signature = vmSymbols::asPrimitive_int_signature();
229       #endif
230 
231       break;
232 
233     default: ShouldNotReachHere();
234   }
235   JavaCalls::call_static(&result,
236                          ik,
237                          vmSymbols::asPrimitive_name(),
238                          signature,
239                          &args,
240                          CHECK_NULL);
241   return (instanceOop) result.get_jobject();
242 }
243 
values_to_object_array(StackValueCollection * values,TRAPS)244 objArrayHandle LiveFrameStream::values_to_object_array(StackValueCollection* values, TRAPS) {
245   objArrayHandle empty;
246   int length = values->size();
247   objArrayOop array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(),
248                                                    length, CHECK_(empty));
249   objArrayHandle array_h(THREAD, array_oop);
250   for (int i = 0; i < values->size(); i++) {
251     StackValue* st = values->at(i);
252     BasicType type = st->type();
253     int index = i;
254 #ifdef _LP64
255     if (type != T_OBJECT && type != T_CONFLICT) {
256         intptr_t ret = st->get_int(); // read full 64-bit slot
257         type = T_LONG;                // treat as long
258         index--;                      // undo +1 in StackValueCollection::long_at
259     }
260 #endif
261     oop obj = create_primitive_slot_instance(values, index, type, CHECK_(empty));
262     if (obj != NULL) {
263       array_h->obj_at_put(i, obj);
264     }
265   }
266   return array_h;
267 }
268 
monitors_to_object_array(GrowableArray<MonitorInfo * > * monitors,TRAPS)269 objArrayHandle LiveFrameStream::monitors_to_object_array(GrowableArray<MonitorInfo*>* monitors, TRAPS) {
270   int length = monitors->length();
271   objArrayOop array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(),
272                                                    length, CHECK_(objArrayHandle()));
273   objArrayHandle array_h(THREAD, array_oop);
274   for (int i = 0; i < length; i++) {
275     MonitorInfo* monitor = monitors->at(i);
276     array_h->obj_at_put(i, monitor->owner());
277   }
278   return array_h;
279 }
280 
281 // Fill StackFrameInfo with bci and initialize memberName
fill_stackframe(Handle stackFrame,const methodHandle & method,TRAPS)282 void BaseFrameStream::fill_stackframe(Handle stackFrame, const methodHandle& method, TRAPS) {
283   java_lang_StackFrameInfo::set_method_and_bci(stackFrame, method, bci(), THREAD);
284 }
285 
286 // Fill LiveStackFrameInfo with locals, monitors, and expressions
fill_live_stackframe(Handle stackFrame,const methodHandle & method,TRAPS)287 void LiveFrameStream::fill_live_stackframe(Handle stackFrame,
288                                            const methodHandle& method, TRAPS) {
289   fill_stackframe(stackFrame, method, CHECK);
290   if (_jvf != NULL) {
291     StackValueCollection* locals = _jvf->locals();
292     StackValueCollection* expressions = _jvf->expressions();
293     GrowableArray<MonitorInfo*>* monitors = _jvf->monitors();
294 
295     int mode = 0;
296     if (_jvf->is_interpreted_frame()) {
297       mode = MODE_INTERPRETED;
298     } else if (_jvf->is_compiled_frame()) {
299       mode = MODE_COMPILED;
300     }
301 
302     if (!locals->is_empty()) {
303       objArrayHandle locals_h = values_to_object_array(locals, CHECK);
304       java_lang_LiveStackFrameInfo::set_locals(stackFrame(), locals_h());
305     }
306     if (!expressions->is_empty()) {
307       objArrayHandle expressions_h = values_to_object_array(expressions, CHECK);
308       java_lang_LiveStackFrameInfo::set_operands(stackFrame(), expressions_h());
309     }
310     if (monitors->length() > 0) {
311       objArrayHandle monitors_h = monitors_to_object_array(monitors, CHECK);
312       java_lang_LiveStackFrameInfo::set_monitors(stackFrame(), monitors_h());
313     }
314     java_lang_LiveStackFrameInfo::set_mode(stackFrame(), mode);
315   }
316 }
317 
318 // Begins stack walking.
319 //
320 // Parameters:
321 //   stackStream    StackStream object
322 //   mode           Stack walking mode.
323 //   skip_frames    Number of frames to be skipped.
324 //   frame_count    Number of frames to be traversed.
325 //   start_index    Start index to the user-supplied buffers.
326 //   frames_array   Buffer to store StackFrame in, starting at start_index.
327 //                  frames array is a Class<?>[] array when only getting caller
328 //                  reference, and a StackFrameInfo[] array (or derivative)
329 //                  otherwise. It should never be null.
330 //
331 // Returns Object returned from AbstractStackWalker::doStackWalk call.
332 //
walk(Handle stackStream,jlong mode,int skip_frames,int frame_count,int start_index,objArrayHandle frames_array,TRAPS)333 oop StackWalk::walk(Handle stackStream, jlong mode,
334                     int skip_frames, int frame_count, int start_index,
335                     objArrayHandle frames_array,
336                     TRAPS) {
337   ResourceMark rm(THREAD);
338   JavaThread* jt = (JavaThread*)THREAD;
339   log_debug(stackwalk)("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
340                        mode, skip_frames, frame_count);
341 
342   if (frames_array.is_null()) {
343     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
344   }
345 
346   // Setup traversal onto my stack.
347   if (live_frame_info(mode)) {
348     assert (use_frames_array(mode), "Bad mode for get live frame");
349     RegisterMap regMap(jt, true);
350     LiveFrameStream stream(jt, &regMap);
351     return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count,
352                            start_index, frames_array, THREAD);
353   } else {
354     JavaFrameStream stream(jt, mode);
355     return fetchFirstBatch(stream, stackStream, mode, skip_frames, frame_count,
356                            start_index, frames_array, THREAD);
357   }
358 }
359 
fetchFirstBatch(BaseFrameStream & stream,Handle stackStream,jlong mode,int skip_frames,int frame_count,int start_index,objArrayHandle frames_array,TRAPS)360 oop StackWalk::fetchFirstBatch(BaseFrameStream& stream, Handle stackStream,
361                                jlong mode, int skip_frames, int frame_count,
362                                int start_index, objArrayHandle frames_array, TRAPS) {
363   methodHandle m_doStackWalk(THREAD, Universe::do_stack_walk_method());
364 
365   {
366     Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
367     Klass* abstractStackWalker_klass = SystemDictionary::AbstractStackWalker_klass();
368     while (!stream.at_end()) {
369       InstanceKlass* ik = stream.method()->method_holder();
370       if (ik != stackWalker_klass &&
371             ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass)  {
372         break;
373       }
374 
375       LogTarget(Debug, stackwalk) lt;
376       if (lt.is_enabled()) {
377         ResourceMark rm(THREAD);
378         LogStream ls(lt);
379         ls.print("  skip ");
380         stream.method()->print_short_name(&ls);
381         ls.cr();
382       }
383       stream.next();
384     }
385 
386     // stack frame has been traversed individually and resume stack walk
387     // from the stack frame at depth == skip_frames.
388     for (int n=0; n < skip_frames && !stream.at_end(); stream.next(), n++) {
389       LogTarget(Debug, stackwalk) lt;
390       if (lt.is_enabled()) {
391         ResourceMark rm(THREAD);
392         LogStream ls(lt);
393         ls.print("  skip ");
394         stream.method()->print_short_name(&ls);
395         ls.cr();
396       }
397     }
398   }
399 
400   int end_index = start_index;
401   int numFrames = 0;
402   if (!stream.at_end()) {
403     numFrames = fill_in_frames(mode, stream, frame_count, start_index,
404                                frames_array, end_index, CHECK_NULL);
405     if (numFrames < 1) {
406       THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
407     }
408   }
409 
410   // JVM_CallStackWalk walks the stack and fills in stack frames, then calls to
411   // Java method java.lang.StackStreamFactory.AbstractStackWalker::doStackWalk
412   // which calls the implementation to consume the stack frames.
413   // When JVM_CallStackWalk returns, it invalidates the stack stream.
414   JavaValue result(T_OBJECT);
415   JavaCallArguments args(stackStream);
416   args.push_long(stream.address_value());
417   args.push_int(skip_frames);
418   args.push_int(frame_count);
419   args.push_int(start_index);
420   args.push_int(end_index);
421 
422   // Link the thread and vframe stream into the callee-visible object
423   stream.setup_magic_on_entry(frames_array);
424 
425   JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
426 
427   // Do this before anything else happens, to disable any lingering stream objects
428   bool ok = stream.cleanup_magic_on_exit(frames_array);
429 
430   // Throw pending exception if we must
431   (void) (CHECK_NULL);
432 
433   if (!ok) {
434     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers on exit", NULL);
435   }
436 
437   // Return normally
438   return (oop)result.get_jobject();
439 }
440 
441 // Walk the next batch of stack frames
442 //
443 // Parameters:
444 //   stackStream    StackStream object
445 //   mode           Stack walking mode.
446 //   magic          Must be valid value to continue the stack walk
447 //   frame_count    Number of frames to be decoded.
448 //   start_index    Start index to the user-supplied buffers.
449 //   frames_array   Buffer to store StackFrame in, starting at start_index.
450 //
451 // Returns the end index of frame filled in the buffer.
452 //
fetchNextBatch(Handle stackStream,jlong mode,jlong magic,int frame_count,int start_index,objArrayHandle frames_array,TRAPS)453 jint StackWalk::fetchNextBatch(Handle stackStream, jlong mode, jlong magic,
454                                int frame_count, int start_index,
455                                objArrayHandle frames_array,
456                                TRAPS)
457 {
458   JavaThread* jt = (JavaThread*)THREAD;
459   BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array);
460   if (existing_stream == NULL) {
461     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
462   }
463 
464   if (frames_array.is_null()) {
465     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
466   }
467 
468   log_debug(stackwalk)("StackWalk::fetchNextBatch frame_count %d existing_stream "
469                        PTR_FORMAT " start %d frames %d",
470                        frame_count, p2i(existing_stream), start_index, frames_array->length());
471   int end_index = start_index;
472   if (frame_count <= 0) {
473     return end_index;        // No operation.
474   }
475 
476   int count = frame_count + start_index;
477   assert (frames_array->length() >= count, "not enough space in buffers");
478 
479   BaseFrameStream& stream = (*existing_stream);
480   if (!stream.at_end()) {
481     stream.next(); // advance past the last frame decoded in previous batch
482     if (!stream.at_end()) {
483       int n = fill_in_frames(mode, stream, frame_count, start_index,
484                              frames_array, end_index, CHECK_0);
485       if (n < 1) {
486         THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
487       }
488       return end_index;
489     }
490   }
491   return end_index;
492 }
493