# HG changeset patch # User simonis # Date 1410884619 -7200 # Node ID 7a1c900c90d890cd84a5b468bd57655183d79bbf # Parent e7748e052f657a3ce50fd80ab49d0caac8eeb92f 8058345: Refactor native stack printing from vmError.cpp to debug.cpp to make it available in gdb as well diff --git a/src/cpu/ppc/vm/frame_ppc.cpp b/src/cpu/ppc/vm/frame_ppc.cpp --- a/src/cpu/ppc/vm/frame_ppc.cpp +++ b/src/cpu/ppc/vm/frame_ppc.cpp @@ -308,3 +308,9 @@ // unused... but returns fp() to minimize changes introduced by 7087445 return fp(); } + +#ifndef PRODUCT +extern "C" frame make_frame(intptr_t* sp, address pc) { + return frame(sp, pc); +} +#endif diff --git a/src/cpu/x86/vm/frame_x86.cpp b/src/cpu/x86/vm/frame_x86.cpp --- a/src/cpu/x86/vm/frame_x86.cpp +++ b/src/cpu/x86/vm/frame_x86.cpp @@ -715,3 +715,9 @@ assert(! is_compiled_frame(), "unknown compiled frame size"); return fp(); } + +#ifndef PRODUCT +extern "C" frame make_frame(intptr_t* sp, intptr_t* fp, address pc) { + return frame(sp, fp, pc); +} +#endif diff --git a/src/share/vm/utilities/debug.cpp b/src/share/vm/utilities/debug.cpp --- a/src/share/vm/utilities/debug.cpp +++ b/src/share/vm/utilities/debug.cpp @@ -665,3 +665,54 @@ } #endif // !PRODUCT + +void print_native_stack(outputStream* st, frame fr, Thread* t, char* buf, int buf_size) { + + // see if it's a valid frame + if (fr.pc()) { + st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); + + int count = 0; + while (count++ < StackPrintLimit) { + fr.print_on_error(st, buf, buf_size); + st->cr(); + // Compiled code may use EBP register on x86 so it looks like + // non-walkable C frame. Use frame.sender() for java frames. + if (t && t->is_Java_thread()) { + // Catch very first native frame by using stack address. + // For JavaThread stack_base and stack_size should be set. + if (!t->on_local_stack((address)(fr.real_fp() + 1))) { + break; + } + if (fr.is_java_frame() || fr.is_native_frame()) { + RegisterMap map((JavaThread*)t, false); // No update + fr = fr.sender(&map); + } else { + fr = os::get_sender_for_C_frame(&fr); + } + } else { + // is_first_C_frame() does only simple checks for frame pointer, + // it will pass if java compiled code has a pointer in EBP. + if (os::is_first_C_frame(&fr)) break; + fr = os::get_sender_for_C_frame(&fr); + } + } + + if (count > StackPrintLimit) { + st->print_cr("......"); + } + + st->cr(); + } +} + +#ifndef PRODUCT + +extern "C" void pns(frame fr) { // print native stack + Command c("pns"); + static char buf[O_BUFLEN]; + Thread* t = ThreadLocalStorage::get_thread_slow(); + print_native_stack(tty, fr, t, buf, sizeof(buf)); +} + +#endif // !PRODUCT diff --git a/src/share/vm/utilities/debug.hpp b/src/share/vm/utilities/debug.hpp --- a/src/share/vm/utilities/debug.hpp +++ b/src/share/vm/utilities/debug.hpp @@ -263,4 +263,7 @@ void pd_ps(frame f); void pd_obfuscate_location(char *buf, size_t buflen); +class outputStream; +void print_native_stack(outputStream* st, frame fr, Thread* t, char* buf, int buf_size); + #endif // SHARE_VM_UTILITIES_DEBUG_HPP diff --git a/src/share/vm/utilities/vmError.cpp b/src/share/vm/utilities/vmError.cpp --- a/src/share/vm/utilities/vmError.cpp +++ b/src/share/vm/utilities/vmError.cpp @@ -577,7 +577,7 @@ STEP(120, "(printing native stack)" ) - if (_verbose) { + if (_verbose) { if (os::platform_print_native_stack(st, _context, buf, sizeof(buf))) { // We have printed the native stack in platform-specific code // Windows/x64 needs special handling. @@ -585,43 +585,7 @@ frame fr = _context ? os::fetch_frame_from_context(_context) : os::current_frame(); - // see if it's a valid frame - if (fr.pc()) { - st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); - - - int count = 0; - while (count++ < StackPrintLimit) { - fr.print_on_error(st, buf, sizeof(buf)); - st->cr(); - // Compiled code may use EBP register on x86 so it looks like - // non-walkable C frame. Use frame.sender() for java frames. - if (_thread && _thread->is_Java_thread()) { - // Catch very first native frame by using stack address. - // For JavaThread stack_base and stack_size should be set. - if (!_thread->on_local_stack((address)(fr.sender_sp() + 1))) { - break; - } - if (fr.is_java_frame()) { - RegisterMap map((JavaThread*)_thread, false); // No update - fr = fr.sender(&map); - } else { - fr = os::get_sender_for_C_frame(&fr); - } - } else { - // is_first_C_frame() does only simple checks for frame pointer, - // it will pass if java compiled code has a pointer in EBP. - if (os::is_first_C_frame(&fr)) break; - fr = os::get_sender_for_C_frame(&fr); - } - } - - if (count > StackPrintLimit) { - st->print_cr("......"); - } - - st->cr(); - } + print_native_stack(st, fr, _thread, buf, sizeof(buf)); } }