1.1 --- a/src/share/vm/utilities/debug.cpp Mon Dec 15 18:11:51 2014 +0400 1.2 +++ b/src/share/vm/utilities/debug.cpp Wed Sep 24 12:19:07 2014 -0700 1.3 @@ -666,6 +666,13 @@ 1.4 tty->print_cr(" pm(int pc) - print Method* given compiled PC"); 1.5 tty->print_cr(" findm(intptr_t pc) - finds Method*"); 1.6 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it"); 1.7 + tty->print_cr(" pns(void* sp, void* fp, void* pc) - print native (i.e. mixed) stack trace. E.g."); 1.8 + tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64 or"); 1.9 + tty->print_cr(" pns($sp, $ebp, $pc) on Linux/x86 or"); 1.10 + tty->print_cr(" pns($sp, 0, $pc) on Linux/ppc64 or"); 1.11 + tty->print_cr(" pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC"); 1.12 + tty->print_cr(" - in gdb do 'set overload-resolution off' before calling pns()"); 1.13 + tty->print_cr(" - in dbx do 'frame 1' before calling pns()"); 1.14 1.15 tty->print_cr("misc."); 1.16 tty->print_cr(" flush() - flushes the log file"); 1.17 @@ -678,3 +685,56 @@ 1.18 } 1.19 1.20 #endif // !PRODUCT 1.21 + 1.22 +void print_native_stack(outputStream* st, frame fr, Thread* t, char* buf, int buf_size) { 1.23 + 1.24 + // see if it's a valid frame 1.25 + if (fr.pc()) { 1.26 + st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); 1.27 + 1.28 + int count = 0; 1.29 + while (count++ < StackPrintLimit) { 1.30 + fr.print_on_error(st, buf, buf_size); 1.31 + st->cr(); 1.32 + // Compiled code may use EBP register on x86 so it looks like 1.33 + // non-walkable C frame. Use frame.sender() for java frames. 1.34 + if (t && t->is_Java_thread()) { 1.35 + // Catch very first native frame by using stack address. 1.36 + // For JavaThread stack_base and stack_size should be set. 1.37 + if (!t->on_local_stack((address)(fr.real_fp() + 1))) { 1.38 + break; 1.39 + } 1.40 + if (fr.is_java_frame() || fr.is_native_frame() || fr.is_runtime_frame()) { 1.41 + RegisterMap map((JavaThread*)t, false); // No update 1.42 + fr = fr.sender(&map); 1.43 + } else { 1.44 + fr = os::get_sender_for_C_frame(&fr); 1.45 + } 1.46 + } else { 1.47 + // is_first_C_frame() does only simple checks for frame pointer, 1.48 + // it will pass if java compiled code has a pointer in EBP. 1.49 + if (os::is_first_C_frame(&fr)) break; 1.50 + fr = os::get_sender_for_C_frame(&fr); 1.51 + } 1.52 + } 1.53 + 1.54 + if (count > StackPrintLimit) { 1.55 + st->print_cr("...<more frames>..."); 1.56 + } 1.57 + 1.58 + st->cr(); 1.59 + } 1.60 +} 1.61 + 1.62 +#ifndef PRODUCT 1.63 + 1.64 +extern "C" void pns(void* sp, void* fp, void* pc) { // print native stack 1.65 + Command c("pns"); 1.66 + static char buf[O_BUFLEN]; 1.67 + Thread* t = ThreadLocalStorage::get_thread_slow(); 1.68 + // Call generic frame constructor (certain arguments may be ignored) 1.69 + frame fr(sp, fp, pc); 1.70 + print_native_stack(tty, fr, t, buf, sizeof(buf)); 1.71 +} 1.72 + 1.73 +#endif // !PRODUCT