提交 330543aa 编写于 作者: N never

6936709: AsyncGetCallTrace doesn't handle inexact stack walking properly

Reviewed-by: kvn
上级 357affb3
......@@ -55,12 +55,11 @@ class vframeStreamForte : public vframeStreamCommon {
};
static void is_decipherable_compiled_frame(frame* fr, RegisterMap* map,
bool* is_compiled_p, bool* is_walkable_p);
static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm);
static bool is_decipherable_interpreted_frame(JavaThread* thread,
frame* fr,
methodOop* method_p,
int* bci_p);
frame* fr,
methodOop* method_p,
int* bci_p);
......@@ -122,41 +121,43 @@ void vframeStreamForte::forte_next() {
// Determine if 'fr' is a decipherable compiled frame. We are already
// assured that fr is for a java nmethod.
static bool is_decipherable_compiled_frame(frame* fr) {
assert(fr->cb() != NULL && fr->cb()->is_nmethod(), "invariant");
nmethod* nm = (nmethod*) fr->cb();
static bool is_decipherable_compiled_frame(JavaThread* thread, frame* fr, nmethod* nm) {
assert(nm->is_java_method(), "invariant");
// First try and find an exact PcDesc
PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
// Did we find a useful PcDesc?
if (pc_desc != NULL &&
pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
address probe_pc = fr->pc() + 1;
pc_desc = nm->pc_desc_near(probe_pc);
// Now do we have a useful PcDesc?
if (thread->has_last_Java_frame() && thread->last_Java_pc() == fr->pc()) {
// We're stopped at a call into the JVM so look for a PcDesc with
// the actual pc reported by the frame.
PcDesc* pc_desc = nm->pc_desc_at(fr->pc());
// Did we find a useful PcDesc?
if (pc_desc != NULL &&
pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
// No debug information available for this pc
// vframeStream would explode if we try and walk the frames.
return false;
pc_desc->scope_decode_offset() != DebugInformationRecorder::serialized_null) {
return true;
}
}
// This PcDesc is useful however we must adjust the frame's pc
// so that the vframeStream lookups will use this same pc
// We're at some random pc in the nmethod so search for the PcDesc
// whose pc is greater than the current PC. It's done this way
// because the extra PcDescs that are recorded for improved debug
// info record the end of the region covered by the ScopeDesc
// instead of the beginning.
PcDesc* pc_desc = nm->pc_desc_near(fr->pc() + 1);
fr->set_pc(pc_desc->real_pc(nm));
// Now do we have a useful PcDesc?
if (pc_desc == NULL ||
pc_desc->scope_decode_offset() == DebugInformationRecorder::serialized_null) {
// No debug information available for this pc
// vframeStream would explode if we try and walk the frames.
return false;
}
// This PcDesc is useful however we must adjust the frame's pc
// so that the vframeStream lookups will use this same pc
fr->set_pc(pc_desc->real_pc(nm));
return true;
}
// Determine if 'fr' is a walkable interpreted frame. Returns false
// if it is not. *method_p, and *bci_p are not set when false is
// returned. *method_p is non-NULL if frame was executing a Java
......@@ -166,9 +167,9 @@ static bool is_decipherable_compiled_frame(frame* fr) {
// even if a valid BCI cannot be found.
static bool is_decipherable_interpreted_frame(JavaThread* thread,
frame* fr,
methodOop* method_p,
int* bci_p) {
frame* fr,
methodOop* method_p,
int* bci_p) {
assert(fr->is_interpreted_frame(), "just checking");
// top frame is an interpreted frame
......@@ -323,13 +324,15 @@ static bool find_initial_Java_frame(JavaThread* thread,
// have a PCDesc that can get us a bci however we did find
// a method
if (!is_decipherable_compiled_frame(&candidate)) {
if (!is_decipherable_compiled_frame(thread, &candidate, nm)) {
return false;
}
// is_decipherable_compiled_frame may modify candidate's pc
*initial_frame_p = candidate;
assert(nm->pc_desc_at(candidate.pc()) != NULL, "if it's decipherable then pc must be valid");
return true;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册