--- old/hotspot/src/share/vm/prims/stackwalk.cpp 2016-07-13 18:11:33.000000000 +0800 +++ new/hotspot/src/share/vm/prims/stackwalk.cpp 2016-07-13 18:11:33.000000000 +0800 @@ -107,19 +107,30 @@ assert(max_nframes > 0, "invalid max_nframes"); assert(start_index + max_nframes <= frames_array->length(), "oob"); + Method* caller_sensitive_method = NULL; + 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"); + + if (caller_sensitive_method != NULL) { + // JVM_GetCallerClass may return a hidden method + // StackWalker::getCallerClass should return the same caller as JVM_GetCallerClass + // even the jdk implementation does not use it for performance reason + if (method->is_ignored_by_security_stack_walk()) continue; + } else { + // filter hidden frames + 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; } - continue; } } @@ -141,6 +152,10 @@ } 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 (StackWalk::get_caller_class(mode) && + caller_sensitive_method == NULL && method->caller_sensitive()) { + caller_sensitive_method = method; + } } if (++frames_decoded >= max_nframes) break; }