hotspot/src/share/vm/prims/stackwalk.cpp
changeset 37438 873c4aea8d1b
parent 34253 ba3946143842
child 38213 2f32787e31b1
equal deleted inserted replaced
37437:f824aabc7af8 37438:873c4aea8d1b
    35 #include "runtime/javaCalls.hpp"
    35 #include "runtime/javaCalls.hpp"
    36 #include "runtime/vframe.hpp"
    36 #include "runtime/vframe.hpp"
    37 #include "utilities/globalDefinitions.hpp"
    37 #include "utilities/globalDefinitions.hpp"
    38 
    38 
    39 // setup and cleanup actions
    39 // setup and cleanup actions
    40 void StackWalkAnchor::setup_magic_on_entry(objArrayHandle classes_array) {
    40 void StackWalkAnchor::setup_magic_on_entry(objArrayHandle frames_array) {
    41   classes_array->obj_at_put(magic_pos, _thread->threadObj());
    41   frames_array->obj_at_put(magic_pos, _thread->threadObj());
    42   _anchor = address_value();
    42   _anchor = address_value();
    43   assert(check_magic(classes_array), "invalid magic");
    43   assert(check_magic(frames_array), "invalid magic");
    44 }
    44 }
    45 
    45 
    46 bool StackWalkAnchor::check_magic(objArrayHandle classes_array) {
    46 bool StackWalkAnchor::check_magic(objArrayHandle frames_array) {
    47   oop   m1 = classes_array->obj_at(magic_pos);
    47   oop   m1 = frames_array->obj_at(magic_pos);
    48   jlong m2 = _anchor;
    48   jlong m2 = _anchor;
    49   if (m1 == _thread->threadObj() && m2 == address_value())  return true;
    49   if (m1 == _thread->threadObj() && m2 == address_value())  return true;
    50   return false;
    50   return false;
    51 }
    51 }
    52 
    52 
    53 bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle classes_array) {
    53 bool StackWalkAnchor::cleanup_magic_on_exit(objArrayHandle frames_array) {
    54   bool ok = check_magic(classes_array);
    54   bool ok = check_magic(frames_array);
    55   classes_array->obj_at_put(magic_pos, NULL);
    55   frames_array->obj_at_put(magic_pos, NULL);
    56   _anchor = 0L;
    56   _anchor = 0L;
    57   return ok;
    57   return ok;
    58 }
    58 }
    59 
    59 
    60 // Returns StackWalkAnchor for the current stack being traversed.
    60 // Returns StackWalkAnchor for the current stack being traversed.
    61 //
    61 //
    62 // Parameters:
    62 // Parameters:
    63 //  thread         Current Java thread.
    63 //  thread         Current Java thread.
    64 //  magic          Magic value used for each stack walking
    64 //  magic          Magic value used for each stack walking
    65 //  classes_array  User-supplied buffers.  The 0th element is reserved
    65 //  frames_array   User-supplied buffers.  The 0th element is reserved
    66 //                 to this StackWalkAnchor to use
    66 //                 to this StackWalkAnchor to use
    67 //
    67 //
    68 StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
    68 StackWalkAnchor* StackWalkAnchor::from_current(JavaThread* thread, jlong magic,
    69                                                objArrayHandle classes_array)
    69                                                objArrayHandle frames_array)
    70 {
    70 {
    71   assert(thread != NULL && thread->is_Java_thread(), "");
    71   assert(thread != NULL && thread->is_Java_thread(), "");
    72   oop m1 = classes_array->obj_at(magic_pos);
    72   oop m1 = frames_array->obj_at(magic_pos);
    73   if (m1 != thread->threadObj())      return NULL;
    73   if (m1 != thread->threadObj())      return NULL;
    74   if (magic == 0L)                    return NULL;
    74   if (magic == 0L)                    return NULL;
    75   StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
    75   StackWalkAnchor* anchor = (StackWalkAnchor*) (intptr_t) magic;
    76   if (!anchor->is_valid_in(thread, classes_array))   return NULL;
    76   if (!anchor->is_valid_in(thread, frames_array))   return NULL;
    77   return anchor;
    77   return anchor;
    78 }
    78 }
    79 
    79 
    80 // Unpacks one or more frames into user-supplied buffers.
    80 // Unpacks one or more frames into user-supplied buffers.
    81 // Updates the end index, and returns the number of unpacked frames.
    81 // Updates the end index, and returns the number of unpacked frames.
    86 // Parameters:
    86 // Parameters:
    87 //   mode           Restrict which frames to be decoded.
    87 //   mode           Restrict which frames to be decoded.
    88 //   vfst           vFrameStream.
    88 //   vfst           vFrameStream.
    89 //   max_nframes    Maximum number of frames to be filled.
    89 //   max_nframes    Maximum number of frames to be filled.
    90 //   start_index    Start index to the user-supplied buffers.
    90 //   start_index    Start index to the user-supplied buffers.
    91 //   classes_array  Buffer to store classes in, starting at start_index.
    91 //   frames_array   Buffer to store Class or StackFrame in, starting at start_index.
    92 //   frames_array   Buffer to store StackFrame in, starting at start_index.
    92 //                  frames array is a Class<?>[] array when only getting caller
    93 //                  NULL if not used.
    93 //                  reference, and a StackFrameInfo[] array (or derivative)
       
    94 //                  otherwise. It should never be null.
    94 //   end_index      End index to the user-supplied buffers with unpacked frames.
    95 //   end_index      End index to the user-supplied buffers with unpacked frames.
    95 //
    96 //
    96 // Returns the number of frames whose information was transferred into the buffers.
    97 // Returns the number of frames whose information was transferred into the buffers.
    97 //
    98 //
    98 int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
    99 int StackWalk::fill_in_frames(jlong mode, vframeStream& vfst,
    99                               int max_nframes, int start_index,
   100                               int max_nframes, int start_index,
   100                               objArrayHandle  classes_array,
       
   101                               objArrayHandle  frames_array,
   101                               objArrayHandle  frames_array,
   102                               int& end_index, TRAPS) {
   102                               int& end_index, TRAPS) {
   103   if (TraceStackWalk) {
   103   if (TraceStackWalk) {
   104     tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
   104     tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
   105                   max_nframes, start_index, classes_array->length());
   105                   max_nframes, start_index, frames_array->length());
   106   }
   106   }
   107   assert(max_nframes > 0, "invalid max_nframes");
   107   assert(max_nframes > 0, "invalid max_nframes");
   108   assert(start_index + max_nframes <= classes_array->length(), "oob");
   108   assert(start_index + max_nframes <= frames_array->length(), "oob");
   109 
   109 
   110   int frames_decoded = 0;
   110   int frames_decoded = 0;
   111   for (; !vfst.at_end(); vfst.next()) {
   111   for (; !vfst.at_end(); vfst.next()) {
   112     Method* method = vfst.method();
   112     Method* method = vfst.method();
   113     int bci = vfst.bci();
   113     int bci = vfst.bci();
   127     if (TraceStackWalk) {
   127     if (TraceStackWalk) {
   128       tty->print("  %d: frame method: ", index); method->print_short_name();
   128       tty->print("  %d: frame method: ", index); method->print_short_name();
   129       tty->print_cr(" bci=%d", bci);
   129       tty->print_cr(" bci=%d", bci);
   130     }
   130     }
   131 
   131 
   132     classes_array->obj_at_put(index, method->method_holder()->java_mirror());
       
   133     // fill in StackFrameInfo and initialize MemberName
   132     // fill in StackFrameInfo and initialize MemberName
   134     if (live_frame_info(mode)) {
   133     if (live_frame_info(mode)) {
       
   134       assert (use_frames_array(mode), "Bad mode for get live frame");
   135       Handle stackFrame(frames_array->obj_at(index));
   135       Handle stackFrame(frames_array->obj_at(index));
   136       fill_live_stackframe(stackFrame, method, bci, vfst.java_frame(), CHECK_0);
   136       fill_live_stackframe(stackFrame, method, bci, vfst.java_frame(), CHECK_0);
   137     } else if (need_method_info(mode)) {
   137     } else if (need_method_info(mode)) {
       
   138       assert (use_frames_array(mode), "Bad mode for get stack frame");
   138       Handle stackFrame(frames_array->obj_at(index));
   139       Handle stackFrame(frames_array->obj_at(index));
   139       fill_stackframe(stackFrame, method, bci);
   140       fill_stackframe(stackFrame, method, bci);
       
   141     } else {
       
   142       assert (use_frames_array(mode) == false, "Bad mode for get caller class");
       
   143       frames_array->obj_at_put(index, method->method_holder()->java_mirror());
   140     }
   144     }
   141     if (++frames_decoded >= max_nframes)  break;
   145     if (++frames_decoded >= max_nframes)  break;
   142   }
   146   }
   143   return frames_decoded;
   147   return frames_decoded;
   144 }
   148 }
   277 //   stackStream    StackStream object
   281 //   stackStream    StackStream object
   278 //   mode           Stack walking mode.
   282 //   mode           Stack walking mode.
   279 //   skip_frames    Number of frames to be skipped.
   283 //   skip_frames    Number of frames to be skipped.
   280 //   frame_count    Number of frames to be traversed.
   284 //   frame_count    Number of frames to be traversed.
   281 //   start_index    Start index to the user-supplied buffers.
   285 //   start_index    Start index to the user-supplied buffers.
   282 //   classes_array  Buffer to store classes in, starting at start_index.
       
   283 //   frames_array   Buffer to store StackFrame in, starting at start_index.
   286 //   frames_array   Buffer to store StackFrame in, starting at start_index.
   284 //                  NULL if not used.
   287 //                  frames array is a Class<?>[] array when only getting caller
       
   288 //                  reference, and a StackFrameInfo[] array (or derivative)
       
   289 //                  otherwise. It should never be null.
   285 //
   290 //
   286 // Returns Object returned from AbstractStackWalker::doStackWalk call.
   291 // Returns Object returned from AbstractStackWalker::doStackWalk call.
   287 //
   292 //
   288 oop StackWalk::walk(Handle stackStream, jlong mode,
   293 oop StackWalk::walk(Handle stackStream, jlong mode,
   289                     int skip_frames, int frame_count, int start_index,
   294                     int skip_frames, int frame_count, int start_index,
   290                     objArrayHandle classes_array,
       
   291                     objArrayHandle frames_array,
   295                     objArrayHandle frames_array,
   292                     TRAPS) {
   296                     TRAPS) {
   293   JavaThread* jt = (JavaThread*)THREAD;
   297   JavaThread* jt = (JavaThread*)THREAD;
   294   if (TraceStackWalk) {
   298   if (TraceStackWalk) {
   295     tty->print_cr("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
   299     tty->print_cr("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
   296                   mode, skip_frames, frame_count);
   300                   mode, skip_frames, frame_count);
   297   }
   301   }
   298 
   302 
   299   if (need_method_info(mode)) {
   303   if (frames_array.is_null()) {
   300     if (frames_array.is_null()) {
   304     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
   301       THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", NULL);
       
   302     }
       
   303   }
   305   }
   304 
   306 
   305   Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
   307   Klass* stackWalker_klass = SystemDictionary::StackWalker_klass();
   306   Klass* abstractStackWalker_klass = SystemDictionary::AbstractStackWalker_klass();
   308   Klass* abstractStackWalker_klass = SystemDictionary::AbstractStackWalker_klass();
   307 
   309 
   311   // This stream will be made available by *reference* to the inner Java call.
   313   // This stream will be made available by *reference* to the inner Java call.
   312   StackWalkAnchor anchor(jt);
   314   StackWalkAnchor anchor(jt);
   313   vframeStream& vfst = anchor.vframe_stream();
   315   vframeStream& vfst = anchor.vframe_stream();
   314 
   316 
   315   {
   317   {
   316     // Skip all methods from AbstractStackWalker and StackWalk (enclosing method)
   318     while (!vfst.at_end()) {
   317     if (!fill_in_stacktrace(mode)) {
   319       InstanceKlass* ik = vfst.method()->method_holder();
   318       while (!vfst.at_end()) {
   320       if (ik != stackWalker_klass &&
   319         InstanceKlass* ik = vfst.method()->method_holder();
   321             ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass)  {
   320         if (ik != stackWalker_klass &&
   322         break;
   321               ik != abstractStackWalker_klass && ik->super() != abstractStackWalker_klass)  {
       
   322           break;
       
   323         }
       
   324 
       
   325         if (TraceStackWalk) {
       
   326           tty->print("  skip "); vfst.method()->print_short_name(); tty->print("\n");
       
   327         }
       
   328         vfst.next();
       
   329       }
   323       }
   330     }
   324 
   331 
   325       if (TraceStackWalk) {
   332     // For exceptions, skip Throwable::fillInStackTrace and <init> methods
   326         tty->print("  skip "); vfst.method()->print_short_name(); tty->print("\n");
   333     // of the exception class and superclasses
       
   334     if (fill_in_stacktrace(mode)) {
       
   335       bool skip_to_fillInStackTrace = false;
       
   336       bool skip_throwableInit_check = false;
       
   337       while (!vfst.at_end() && !skip_throwableInit_check) {
       
   338         InstanceKlass* ik = vfst.method()->method_holder();
       
   339         Method* method = vfst.method();
       
   340         if (!skip_to_fillInStackTrace) {
       
   341           if (ik == SystemDictionary::Throwable_klass() &&
       
   342               method->name() == vmSymbols::fillInStackTrace_name()) {
       
   343               // this frame will be skipped
       
   344               skip_to_fillInStackTrace = true;
       
   345           }
       
   346         } else if (!(ik->is_subclass_of(SystemDictionary::Throwable_klass()) &&
       
   347                      method->name() == vmSymbols::object_initializer_name())) {
       
   348             // there are none or we've seen them all - either way stop checking
       
   349             skip_throwableInit_check = true;
       
   350             break;
       
   351         }
       
   352 
       
   353         if (TraceStackWalk) {
       
   354           tty->print("stack walk: skip "); vfst.method()->print_short_name(); tty->print("\n");
       
   355         }
       
   356         vfst.next();
       
   357       }
   327       }
       
   328       vfst.next();
   358     }
   329     }
   359 
   330 
   360     // stack frame has been traversed individually and resume stack walk
   331     // stack frame has been traversed individually and resume stack walk
   361     // from the stack frame at depth == skip_frames.
   332     // from the stack frame at depth == skip_frames.
   362     for (int n=0; n < skip_frames && !vfst.at_end(); vfst.next(), n++) {
   333     for (int n=0; n < skip_frames && !vfst.at_end(); vfst.next(), n++) {
   370 
   341 
   371   // The Method* pointer in the vfst has a very short shelf life.  Grab it now.
   342   // The Method* pointer in the vfst has a very short shelf life.  Grab it now.
   372   int end_index = start_index;
   343   int end_index = start_index;
   373   int numFrames = 0;
   344   int numFrames = 0;
   374   if (!vfst.at_end()) {
   345   if (!vfst.at_end()) {
   375     numFrames = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
   346     numFrames = fill_in_frames(mode, vfst, frame_count, start_index,
   376                                frames_array, end_index, CHECK_NULL);
   347                                frames_array, end_index, CHECK_NULL);
   377     if (numFrames < 1) {
   348     if (numFrames < 1) {
   378       THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
   349       THROW_MSG_(vmSymbols::java_lang_InternalError(), "stack walk: decode failed", NULL);
   379     }
   350     }
   380   }
   351   }
   390   args.push_int(frame_count);
   361   args.push_int(frame_count);
   391   args.push_int(start_index);
   362   args.push_int(start_index);
   392   args.push_int(end_index);
   363   args.push_int(end_index);
   393 
   364 
   394   // Link the thread and vframe stream into the callee-visible object
   365   // Link the thread and vframe stream into the callee-visible object
   395   anchor.setup_magic_on_entry(classes_array);
   366   anchor.setup_magic_on_entry(frames_array);
   396 
   367 
   397   JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
   368   JavaCalls::call(&result, m_doStackWalk, &args, THREAD);
   398 
   369 
   399   // Do this before anything else happens, to disable any lingering stream objects
   370   // Do this before anything else happens, to disable any lingering stream objects
   400   bool ok = anchor.cleanup_magic_on_exit(classes_array);
   371   bool ok = anchor.cleanup_magic_on_exit(frames_array);
   401 
   372 
   402   // Throw pending exception if we must
   373   // Throw pending exception if we must
   403   (void) (CHECK_NULL);
   374   (void) (CHECK_NULL);
   404 
   375 
   405   if (!ok) {
   376   if (!ok) {
   417 //   stackStream    StackStream object
   388 //   stackStream    StackStream object
   418 //   mode           Stack walking mode.
   389 //   mode           Stack walking mode.
   419 //   magic          Must be valid value to continue the stack walk
   390 //   magic          Must be valid value to continue the stack walk
   420 //   frame_count    Number of frames to be decoded.
   391 //   frame_count    Number of frames to be decoded.
   421 //   start_index    Start index to the user-supplied buffers.
   392 //   start_index    Start index to the user-supplied buffers.
   422 //   classes_array  Buffer to store classes in, starting at start_index.
       
   423 //   frames_array   Buffer to store StackFrame in, starting at start_index.
   393 //   frames_array   Buffer to store StackFrame in, starting at start_index.
   424 //                  NULL if not used.
       
   425 //
   394 //
   426 // Returns the end index of frame filled in the buffer.
   395 // Returns the end index of frame filled in the buffer.
   427 //
   396 //
   428 jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
   397 jint StackWalk::moreFrames(Handle stackStream, jlong mode, jlong magic,
   429                            int frame_count, int start_index,
   398                            int frame_count, int start_index,
   430                            objArrayHandle classes_array,
       
   431                            objArrayHandle frames_array,
   399                            objArrayHandle frames_array,
   432                            TRAPS)
   400                            TRAPS)
   433 {
   401 {
   434   JavaThread* jt = (JavaThread*)THREAD;
   402   JavaThread* jt = (JavaThread*)THREAD;
   435   StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, classes_array);
   403   StackWalkAnchor* existing_anchor = StackWalkAnchor::from_current(jt, magic, frames_array);
   436   if (existing_anchor == NULL) {
   404   if (existing_anchor == NULL) {
   437     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
   405     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
   438   }
   406   }
   439 
   407 
   440   if ((need_method_info(mode) || live_frame_info(mode)) && frames_array.is_null()) {
   408   if (frames_array.is_null()) {
   441     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
   409     THROW_MSG_(vmSymbols::java_lang_NullPointerException(), "frames_array is NULL", 0L);
   442   }
   410   }
   443 
   411 
   444   if (TraceStackWalk) {
   412   if (TraceStackWalk) {
   445     tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
   413     tty->print_cr("StackWalk::moreFrames frame_count %d existing_anchor " PTR_FORMAT " start %d frames %d",
   446                   frame_count, p2i(existing_anchor), start_index, classes_array->length());
   414                   frame_count, p2i(existing_anchor), start_index, frames_array->length());
   447   }
   415   }
   448   int end_index = start_index;
   416   int end_index = start_index;
   449   if (frame_count <= 0) {
   417   if (frame_count <= 0) {
   450     return end_index;        // No operation.
   418     return end_index;        // No operation.
   451   }
   419   }
   452 
   420 
   453   int count = frame_count + start_index;
   421   int count = frame_count + start_index;
   454   assert (classes_array->length() >= count, "not enough space in buffers");
   422   assert (frames_array->length() >= count, "not enough space in buffers");
   455 
   423 
   456   StackWalkAnchor& anchor = (*existing_anchor);
   424   StackWalkAnchor& anchor = (*existing_anchor);
   457   vframeStream& vfst = anchor.vframe_stream();
   425   vframeStream& vfst = anchor.vframe_stream();
   458   if (!vfst.at_end()) {
   426   if (!vfst.at_end()) {
   459     vfst.next();  // this was the last frame decoded in the previous batch
   427     vfst.next();  // this was the last frame decoded in the previous batch
   460     if (!vfst.at_end()) {
   428     if (!vfst.at_end()) {
   461       int n = fill_in_frames(mode, vfst, frame_count, start_index, classes_array,
   429       int n = fill_in_frames(mode, vfst, frame_count, start_index,
   462                              frames_array, end_index, CHECK_0);
   430                              frames_array, end_index, CHECK_0);
   463       if (n < 1) {
   431       if (n < 1) {
   464         THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
   432         THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: later decode failed", 0L);
   465       }
   433       }
   466       return end_index;
   434       return end_index;