hotspot/src/os/aix/vm/porting_aix.cpp
changeset 46576 0b817584e8a9
parent 46567 30efdd5f0dc9
child 46619 a3919f5e8d2b
equal deleted inserted replaced
46575:d6fb8a7a7843 46576:0b817584e8a9
    33 #include "runtime/thread.hpp"
    33 #include "runtime/thread.hpp"
    34 #include "utilities/debug.hpp"
    34 #include "utilities/debug.hpp"
    35 
    35 
    36 #include <demangle.h>
    36 #include <demangle.h>
    37 #include <sys/debug.h>
    37 #include <sys/debug.h>
       
    38 #include <pthread.h>
    38 #include <ucontext.h>
    39 #include <ucontext.h>
    39 
    40 
    40 //////////////////////////////////
    41 //////////////////////////////////
    41 // Provide implementation for dladdr based on LoadedLibraries pool and
    42 // Provide implementation for dladdr based on LoadedLibraries pool and
    42 // traceback table scan
    43 // traceback table scan
   678 
   679 
   679   // Retrieve current stack base, size from the current thread. If there is none,
   680   // Retrieve current stack base, size from the current thread. If there is none,
   680   // retrieve it from the OS.
   681   // retrieve it from the OS.
   681   stackptr_t stack_base = NULL;
   682   stackptr_t stack_base = NULL;
   682   size_t stack_size = NULL;
   683   size_t stack_size = NULL;
   683   Thread* const thread = Thread::current_or_null_safe();
   684   {
   684   if (thread) {
   685     AixMisc::stackbounds_t stackbounds;
   685     stack_base = (stackptr_t) thread->stack_base();
   686     if (!AixMisc::query_stack_bounds_for_current_thread(&stackbounds)) {
   686     stack_size = thread->stack_size();
   687       st->print_cr("Cannot retrieve stack bounds.");
   687   } else {
   688       return;
   688     stack_base = (stackptr_t) os::current_stack_base();
   689     }
   689     stack_size = os::current_stack_size();
   690     stack_base = (stackptr_t)stackbounds.base;
       
   691     stack_size = stackbounds.size;
   690   }
   692   }
   691 
   693 
   692   st->print_cr("------ current frame:");
   694   st->print_cr("------ current frame:");
   693   st->print("iar:  " PTR64_FORMAT " ", p2i(cur_iar));
   695   st->print("iar:  " PTR64_FORMAT " ", p2i(cur_iar));
   694   print_info_for_pc(st, cur_iar, buf, buf_size, demangle);
   696   print_info_for_pc(st, cur_iar, buf, buf_size, demangle);
   807   return;
   809   return;
   808 
   810 
   809 }
   811 }
   810 
   812 
   811 
   813 
   812 
   814 bool AixMisc::query_stack_bounds_for_current_thread(stackbounds_t* out) {
   813 
   815 
       
   816   // Information about this api can be found (a) in the pthread.h header and
       
   817   // (b) in http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_getthrds_np.htm
       
   818   //
       
   819   // The use of this API to find out the current stack is kind of undefined.
       
   820   // But after a lot of tries and asking IBM about it, I concluded that it is safe
       
   821   // enough for cases where I let the pthread library create its stacks. For cases
       
   822   // where I create an own stack and pass this to pthread_create, it seems not to
       
   823   // work (the returned stack size in that case is 0).
       
   824 
       
   825   pthread_t tid = pthread_self();
       
   826   struct __pthrdsinfo pinfo;
       
   827   char dummy[1]; // Just needed to satisfy pthread_getthrds_np.
       
   828   int dummy_size = sizeof(dummy);
       
   829 
       
   830   memset(&pinfo, 0, sizeof(pinfo));
       
   831 
       
   832   const int rc = pthread_getthrds_np(&tid, PTHRDSINFO_QUERY_ALL, &pinfo,
       
   833                                      sizeof(pinfo), dummy, &dummy_size);
       
   834 
       
   835   if (rc != 0) {
       
   836     fprintf(stderr, "pthread_getthrds_np failed (%d)\n", rc);
       
   837     fflush(stdout);
       
   838     return false;
       
   839   }
       
   840 
       
   841   // The following may happen when invoking pthread_getthrds_np on a pthread
       
   842   // running on a user provided stack (when handing down a stack to pthread
       
   843   // create, see pthread_attr_setstackaddr).
       
   844   // Not sure what to do then.
       
   845   if (pinfo.__pi_stackend == NULL || pinfo.__pi_stackaddr == NULL) {
       
   846     fprintf(stderr, "pthread_getthrds_np - invalid values\n");
       
   847     fflush(stdout);
       
   848     return false;
       
   849   }
       
   850 
       
   851   // Note: we get three values from pthread_getthrds_np:
       
   852   //       __pi_stackaddr, __pi_stacksize, __pi_stackend
       
   853   //
       
   854   // high addr    ---------------------                                                           base, high
       
   855   //
       
   856   //    |         pthread internal data, like ~2K
       
   857   //    |
       
   858   //    |         ---------------------   __pi_stackend   (usually not page aligned, (xxxxF890))
       
   859   //    |
       
   860   //    |
       
   861   //    |
       
   862   //    |
       
   863   //    |
       
   864   //    |
       
   865   //    |          ---------------------   (__pi_stackend - __pi_stacksize)
       
   866   //    |
       
   867   //    |          padding to align the following AIX guard pages, if enabled.
       
   868   //    |
       
   869   //    V          ---------------------   __pi_stackaddr                                        low, base - size
       
   870   //
       
   871   // low addr      AIX guard pages, if enabled (AIXTHREAD_GUARDPAGES > 0)
       
   872   //
       
   873 
       
   874   out->base = (address)pinfo.__pi_stackend;
       
   875   address low = (address)pinfo.__pi_stackaddr;
       
   876   out->size = out->base - low;
       
   877   return true;
       
   878 
       
   879 }
       
   880 
       
   881 
       
   882 
       
   883