src/share/vm/utilities/debug.cpp

changeset 7553
f43fad8786fc
parent 7300
03e6d34be1f5
child 7994
04ff2f6cd0eb
child 8209
8641949eb21f
     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

mercurial