src/share/vm/utilities/debug.cpp

Print this page
rev 7023 : 8058345: Refactor native stack printing from vmError.cpp to debug.cpp to make it available in gdb as well

*** 663,667 **** --- 663,718 ---- tty->print_cr(" debug() - to set things up for compiler debugging"); 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, 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.sender_sp() + 1))) { + break; + } + if (fr.is_java_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("...<more frames>..."); + } + + 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