src/hotspot/share/utilities/debug.cpp
changeset 49653 a569cb4425f3
parent 49480 d7df2dd501ce
child 49671 015af70b9a1d
equal deleted inserted replaced
49652:a74836b05c28 49653:a569cb4425f3
    52 #include "runtime/vm_version.hpp"
    52 #include "runtime/vm_version.hpp"
    53 #include "services/heapDumper.hpp"
    53 #include "services/heapDumper.hpp"
    54 #include "utilities/defaultStream.hpp"
    54 #include "utilities/defaultStream.hpp"
    55 #include "utilities/events.hpp"
    55 #include "utilities/events.hpp"
    56 #include "utilities/formatBuffer.hpp"
    56 #include "utilities/formatBuffer.hpp"
       
    57 #include "utilities/globalDefinitions.hpp"
    57 #include "utilities/macros.hpp"
    58 #include "utilities/macros.hpp"
    58 #include "utilities/vmError.hpp"
    59 #include "utilities/vmError.hpp"
    59 
    60 
    60 #include <stdio.h>
    61 #include <stdio.h>
       
    62 
       
    63 // Support for showing register content on asserts/guarantees.
       
    64 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
       
    65 static char g_dummy;
       
    66 char* g_assert_poison = &g_dummy;
       
    67 static intx g_asserting_thread = 0;
       
    68 static void* g_assertion_context = NULL;
       
    69 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
    61 
    70 
    62 #ifndef ASSERT
    71 #ifndef ASSERT
    63 #  ifdef _DEBUG
    72 #  ifdef _DEBUG
    64    // NOTE: don't turn the lines below into a comment -- if you're getting
    73    // NOTE: don't turn the lines below into a comment -- if you're getting
    65    // a compile error here, change the settings to define ASSERT
    74    // a compile error here, change the settings to define ASSERT
   210 void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
   219 void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
   211 {
   220 {
   212   if (Debugging || error_is_suppressed(file, line)) return;
   221   if (Debugging || error_is_suppressed(file, line)) return;
   213   va_list detail_args;
   222   va_list detail_args;
   214   va_start(detail_args, detail_fmt);
   223   va_start(detail_args, detail_fmt);
   215   VMError::report_and_die(Thread::current_or_null(), file, line, error_msg, detail_fmt, detail_args);
   224   void* context = NULL;
       
   225 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
       
   226   if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
       
   227     context = g_assertion_context;
       
   228   }
       
   229 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
       
   230   VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args);
   216   va_end(detail_args);
   231   va_end(detail_args);
   217 }
   232 }
   218 
   233 
   219 void report_vm_status_error(const char* file, int line, const char* error_msg,
   234 void report_vm_status_error(const char* file, int line, const char* error_msg,
   220                             int status, const char* detail) {
   235                             int status, const char* detail) {
   224 void report_fatal(const char* file, int line, const char* detail_fmt, ...)
   239 void report_fatal(const char* file, int line, const char* detail_fmt, ...)
   225 {
   240 {
   226   if (Debugging || error_is_suppressed(file, line)) return;
   241   if (Debugging || error_is_suppressed(file, line)) return;
   227   va_list detail_args;
   242   va_list detail_args;
   228   va_start(detail_args, detail_fmt);
   243   va_start(detail_args, detail_fmt);
   229   VMError::report_and_die(Thread::current_or_null(), file, line, "fatal error", detail_fmt, detail_args);
   244   void* context = NULL;
       
   245 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
       
   246   if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
       
   247     context = g_assertion_context;
       
   248   }
       
   249 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
       
   250   VMError::report_and_die(Thread::current_or_null(), context, file, line, "fatal error", detail_fmt, detail_args);
   230   va_end(detail_args);
   251   va_end(detail_args);
   231 }
   252 }
   232 
   253 
   233 void report_vm_out_of_memory(const char* file, int line, size_t size,
   254 void report_vm_out_of_memory(const char* file, int line, size_t size,
   234                              VMErrorType vm_err_type, const char* detail_fmt, ...) {
   255                              VMErrorType vm_err_type, const char* detail_fmt, ...) {
   674   STATIC_ASSERT(0 == 0);
   695   STATIC_ASSERT(0 == 0);
   675   STATIC_ASSERT(1 == 1);
   696   STATIC_ASSERT(1 == 1);
   676 };
   697 };
   677 
   698 
   678 #endif // !PRODUCT
   699 #endif // !PRODUCT
       
   700 
       
   701 // Support for showing register content on asserts/guarantees.
       
   702 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
       
   703 
       
   704 static ucontext_t g_stored_assertion_context;
       
   705 
       
   706 void initialize_assert_poison() {
       
   707   char* page = os::reserve_memory(os::vm_page_size());
       
   708   if (page) {
       
   709     if (os::commit_memory(page, os::vm_page_size(), false) &&
       
   710         os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) {
       
   711       g_assert_poison = page;
       
   712     }
       
   713   }
       
   714 }
       
   715 
       
   716 static bool store_context(const void* context) {
       
   717   if (memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t)) == false) {
       
   718     return false;
       
   719   }
       
   720 #if defined(__linux) && defined(PPC64)
       
   721   // on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up
       
   722   //  after copying the context (see comment in sys/ucontext.h):
       
   723   *((void**) &g_stored_assertion_context.uc_mcontext.regs) = &(g_stored_assertion_context.uc_mcontext.gp_regs);
       
   724 #endif
       
   725   return true;
       
   726 }
       
   727 
       
   728 bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {
       
   729   if (faulting_address == g_assert_poison) {
       
   730     // Disarm poison page.
       
   731     os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX);
       
   732     // Store Context away.
       
   733     if (ucVoid) {
       
   734       const jlong my_tid = os::current_thread_id();
       
   735       if (Atomic::cmpxchg(my_tid, &g_asserting_thread, (intx)0) == 0) {
       
   736         if (store_context(ucVoid)) {
       
   737           g_assertion_context = &g_stored_assertion_context;
       
   738         }
       
   739       }
       
   740     }
       
   741     return true;
       
   742   }
       
   743   return false;
       
   744 }
       
   745 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
       
   746