--- old/src/share/vm/utilities/debug.cpp 2017-06-16 19:50:09.992959084 -0400 +++ new/src/share/vm/utilities/debug.cpp 2017-06-16 19:50:09.860952483 -0400 @@ -583,19 +583,17 @@ if (p->has_last_Java_frame()) { // If the last_Java_fp is set we are in C land and // can call the standard stack_trace function. -#ifdef PRODUCT p->print_stack(); } else { +#ifdef PRODUCT tty->print_cr("Cannot find the last Java frame, printing stack disabled."); #else // !PRODUCT - p->trace_stack(); - } else { frame f = os::current_frame(); RegisterMap reg_map(p); f = f.sender(®_map); tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id())); p->trace_stack_from(vframe::new_vframe(&f, ®_map, p)); - pd_ps(f); + pd_ps(f); #endif // PRODUCT } @@ -759,57 +757,13 @@ tty->print_cr(" ndebug() - undo debug"); } -#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, A=aot 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() || fr.is_runtime_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(void* sp, void* fp, void* pc) { // print native stack Command c("pns"); static char buf[O_BUFLEN]; Thread* t = Thread::current_or_null(); // Call generic frame constructor (certain arguments may be ignored) frame fr(sp, fp, pc); - print_native_stack(tty, fr, t, buf, sizeof(buf)); + VMError::print_native_stack(tty, fr, t, buf, sizeof(buf)); } #endif // !PRODUCT --- old/src/share/vm/utilities/debug.hpp 2017-06-16 19:50:10.604989676 -0400 +++ new/src/share/vm/utilities/debug.hpp 2017-06-16 19:50:10.472983082 -0400 @@ -221,10 +221,7 @@ // for test purposes, which is not NULL and contains bits in every word NOT_PRODUCT(void* get_segfault_address();) +class frame; 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 --- old/src/share/vm/utilities/globalDefinitions.hpp 2017-06-16 19:50:11.205019681 -0400 +++ new/src/share/vm/utilities/globalDefinitions.hpp 2017-06-16 19:50:11.073013076 -0400 @@ -950,8 +950,6 @@ class CompiledRFrame; class InterpretedRFrame; -class frame; - class vframe; class javaVFrame; class interpretedVFrame; --- old/src/share/vm/utilities/vmError.cpp 2017-06-16 19:50:11.761047474 -0400 +++ new/src/share/vm/utilities/vmError.cpp 2017-06-16 19:50:11.633041075 -0400 @@ -204,6 +204,46 @@ #endif // ZERO } +void VMError::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, A=aot 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() || fr.is_runtime_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(); + } +} + static void print_oom_reasons(outputStream* st) { st->print_cr("# Possible reasons:"); st->print_cr("# The system is out of physical RAM or swap space"); --- old/src/share/vm/utilities/vmError.hpp 2017-06-16 19:50:12.325075678 -0400 +++ new/src/share/vm/utilities/vmError.hpp 2017-06-16 19:50:12.193069073 -0400 @@ -28,6 +28,7 @@ #include "utilities/globalDefinitions.hpp" class Decoder; +class frame; class VM_ReportJavaOutOfMemory; class VMError : public AllStatic { @@ -99,6 +100,12 @@ static void print_stack_trace(outputStream* st, JavaThread* jt, char* buf, int buflen, bool verbose = false); + // public for use by the internal non-product debugger. + NOT_PRODUCT(public:) + static void print_native_stack(outputStream* st, frame fr, Thread* t, + char* buf, int buf_size); + NOT_PRODUCT(private:) + static bool should_report_bug(unsigned int id) { return (id != OOM_MALLOC_ERROR) && (id != OOM_MMAP_ERROR); }