Пример #1
0
// Unpacks one or more frames into user-supplied buffers.
// Updates the end index, and returns the number of unpacked frames.
// Always start with the existing vfst.method and bci.
// Do not call vfst.next to advance over the last returned value.
// In other words, do not leave any stale data in the vfst.
//
// Parameters:
//   mode             Restrict which frames to be decoded.
//   BaseFrameStream  stream of frames
//   max_nframes      Maximum number of frames to be filled.
//   start_index      Start index to the user-supplied buffers.
//   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
//                    frames array is a Class<?>[] array when only getting caller
//                    reference, and a StackFrameInfo[] array (or derivative)
//                    otherwise. It should never be null.
//   end_index        End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
int StackWalk::fill_in_frames(jlong mode, BaseFrameStream& stream,
                              int max_nframes, int start_index,
                              objArrayHandle  frames_array,
                              int& end_index, TRAPS) {
    log_debug(stackwalk)("fill_in_frames limit=%d start=%d frames length=%d",
                         max_nframes, start_index, frames_array->length());
    assert(max_nframes > 0, "invalid max_nframes");
    assert(start_index + max_nframes <= frames_array->length(), "oob");

    int frames_decoded = 0;
    for (; !stream.at_end(); stream.next()) {
        Method* method = stream.method();

        if (method == NULL) continue;

        // skip hidden frames for default StackWalker option (i.e. SHOW_HIDDEN_FRAMES
        // not set) and when StackWalker::getCallerClass is called
        if (!ShowHiddenFrames && (skip_hidden_frames(mode) || get_caller_class(mode))) {
            if (method->is_hidden()) {
                if (log_is_enabled(Debug, stackwalk)) {
                    ResourceMark rm(THREAD);
                    outputStream* st = Log(stackwalk)::debug_stream();
                    st->print("  hidden method: ");
                    method->print_short_name(st);
                    st->cr();
                }
                continue;
            }
        }

        int index = end_index++;
        if (log_is_enabled(Debug, stackwalk)) {
            ResourceMark rm(THREAD);
            outputStream* st = Log(stackwalk)::debug_stream();
            st->print("  %d: frame method: ", index);
            method->print_short_name(st);
            st->print_cr(" bci=%d", stream.bci());
        }

        if (!need_method_info(mode) && get_caller_class(mode) &&
                index == start_index && method->caller_sensitive()) {
            ResourceMark rm(THREAD);
            THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(),
                        err_msg("StackWalker::getCallerClass called from @CallerSensitive %s method",
                                method->name_and_sig_as_C_string()));
        }
        // fill in StackFrameInfo and initialize MemberName
        stream.fill_frame(index, frames_array, method, CHECK_0);
        if (++frames_decoded >= max_nframes)  break;
    }
    return frames_decoded;
}
Пример #2
0
// Unpacks one or more frames into user-supplied buffers.
// Updates the end index, and returns the number of unpacked frames.
// Always start with the existing vfst.method and bci.
// Do not call vfst.next to advance over the last returned value.
// In other words, do not leave any stale data in the vfst.
//
// Parameters:
//   mode             Restrict which frames to be decoded.
//   JavaFrameStream  stream of javaVFrames
//   max_nframes      Maximum number of frames to be filled.
//   start_index      Start index to the user-supplied buffers.
//   frames_array     Buffer to store Class or StackFrame in, starting at start_index.
//                    frames array is a Class<?>[] array when only getting caller
//                    reference, and a StackFrameInfo[] array (or derivative)
//                    otherwise. It should never be null.
//   end_index        End index to the user-supplied buffers with unpacked frames.
//
// Returns the number of frames whose information was transferred into the buffers.
//
int StackWalk::fill_in_frames(jlong mode, JavaFrameStream& stream,
                              int max_nframes, int start_index,
                              objArrayHandle  frames_array,
                              int& end_index, TRAPS) {
  if (TraceStackWalk) {
    tty->print_cr("fill_in_frames limit=%d start=%d frames length=%d",
                  max_nframes, start_index, frames_array->length());
  }
  assert(max_nframes > 0, "invalid max_nframes");
  assert(start_index + max_nframes <= frames_array->length(), "oob");

  int frames_decoded = 0;
  for (; !stream.at_end(); stream.next()) {
    Method* method = stream.method();
    int bci = stream.bci();

    if (method == NULL) continue;
    if (!ShowHiddenFrames && StackWalk::skip_hidden_frames(mode)) {
      if (method->is_hidden()) {
        if (TraceStackWalk) {
          tty->print("  hidden method: "); method->print_short_name();
          tty->print("\n");
        }
        continue;
      }
    }

    int index = end_index++;
    if (TraceStackWalk) {
      tty->print("  %d: frame method: ", index); method->print_short_name();
      tty->print_cr(" bci=%d", bci);
    }

    // fill in StackFrameInfo and initialize MemberName
    if (live_frame_info(mode)) {
      assert (use_frames_array(mode), "Bad mode for get live frame");
      Handle stackFrame(frames_array->obj_at(index));
      fill_live_stackframe(stackFrame, method, bci, stream.java_frame(), CHECK_0);
    } else if (need_method_info(mode)) {
      assert (use_frames_array(mode), "Bad mode for get stack frame");
      Handle stackFrame(frames_array->obj_at(index));
      fill_stackframe(stackFrame, method, bci);
    } else {
      assert (use_frames_array(mode) == false, "Bad mode for get caller class");
      frames_array->obj_at_put(index, method->method_holder()->java_mirror());
    }
    if (++frames_decoded >= max_nframes)  break;
  }
  return frames_decoded;
}