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 |