< prev index next >

src/hotspot/share/utilities/debug.cpp

Print this page
rev 49255 : 8191101: Show register content in hs-err file on assert
Reviewed-by:


  36 #include "interpreter/interpreter.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "memory/universe.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "prims/privilegedStack.hpp"
  41 #include "runtime/arguments.hpp"
  42 #include "runtime/atomic.hpp"
  43 #include "runtime/frame.hpp"
  44 #include "runtime/java.hpp"
  45 #include "runtime/os.hpp"
  46 #include "runtime/sharedRuntime.hpp"
  47 #include "runtime/stubCodeGenerator.hpp"
  48 #include "runtime/stubRoutines.hpp"
  49 #include "runtime/thread.inline.hpp"
  50 #include "runtime/vframe.hpp"
  51 #include "runtime/vm_version.hpp"
  52 #include "services/heapDumper.hpp"
  53 #include "utilities/defaultStream.hpp"
  54 #include "utilities/events.hpp"
  55 #include "utilities/formatBuffer.hpp"

  56 #include "utilities/macros.hpp"
  57 #include "utilities/vmError.hpp"
  58 
  59 #include <stdio.h>
  60 








  61 #ifndef ASSERT
  62 #  ifdef _DEBUG
  63    // NOTE: don't turn the lines below into a comment -- if you're getting
  64    // a compile error here, change the settings to define ASSERT
  65    ASSERT should be defined when _DEBUG is defined.  It is not intended to be used for debugging
  66    functions that do not slow down the system too much and thus can be left in optimized code.
  67    On the other hand, the code should not be included in a production version.
  68 #  endif // _DEBUG
  69 #endif // ASSERT
  70 
  71 
  72 #ifdef _DEBUG
  73 #  ifndef ASSERT
  74      configuration error: ASSERT must be defined in debug version
  75 #  endif // ASSERT
  76 #endif // _DEBUG
  77 
  78 
  79 #ifdef PRODUCT
  80 #  if -defined _DEBUG || -defined ASSERT


 194 
 195 #undef is_token_break
 196 
 197 #else
 198 
 199 // Place-holder for non-existent suppression check:
 200 #define error_is_suppressed(file_name, line_no) (false)
 201 
 202 #endif // !PRODUCT
 203 
 204 void report_vm_error(const char* file, int line, const char* error_msg)
 205 {
 206   report_vm_error(file, line, error_msg, "%s", "");
 207 }
 208 
 209 void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
 210 {
 211   if (Debugging || error_is_suppressed(file, line)) return;
 212   va_list detail_args;
 213   va_start(detail_args, detail_fmt);
 214   VMError::report_and_die(Thread::current_or_null(), file, line, error_msg, detail_fmt, detail_args);






 215   va_end(detail_args);
 216 }
 217 
 218 void report_vm_status_error(const char* file, int line, const char* error_msg,
 219                             int status, const char* detail) {
 220   report_vm_error(file, line, error_msg, "error %s(%d), %s", os::errno_name(status), status, detail);
 221 }
 222 
 223 void report_fatal(const char* file, int line, const char* detail_fmt, ...)
 224 {
 225   if (Debugging || error_is_suppressed(file, line)) return;
 226   va_list detail_args;
 227   va_start(detail_args, detail_fmt);
 228   VMError::report_and_die(Thread::current_or_null(), file, line, "fatal error", detail_fmt, detail_args);






 229   va_end(detail_args);
 230 }
 231 
 232 void report_vm_out_of_memory(const char* file, int line, size_t size,
 233                              VMErrorType vm_err_type, const char* detail_fmt, ...) {
 234   if (Debugging) return;
 235   va_list detail_args;
 236   va_start(detail_args, detail_fmt);
 237   VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
 238   va_end(detail_args);
 239 
 240   // The UseOSErrorReporting option in report_and_die() may allow a return
 241   // to here. If so then we'll have to figure out how to handle it.
 242   guarantee(false, "report_and_die() should not return here");
 243 }
 244 
 245 void report_should_not_call(const char* file, int line) {
 246   report_vm_error(file, line, "ShouldNotCall()");
 247 }
 248 


 658 STATIC_ASSERT(true);
 659 STATIC_ASSERT(1 == 1);
 660 STATIC_ASSERT(0 == 0);
 661 
 662 void test_multiple_static_assert_forms_in_function_scope() {
 663   STATIC_ASSERT(true);
 664   STATIC_ASSERT(true);
 665   STATIC_ASSERT(0 == 0);
 666   STATIC_ASSERT(1 == 1);
 667 }
 668 
 669 // class scope
 670 struct TestMultipleStaticAssertFormsInClassScope {
 671   STATIC_ASSERT(true);
 672   STATIC_ASSERT(true);
 673   STATIC_ASSERT(0 == 0);
 674   STATIC_ASSERT(1 == 1);
 675 };
 676 
 677 #endif // !PRODUCT






















































  36 #include "interpreter/interpreter.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "memory/universe.hpp"
  39 #include "oops/oop.inline.hpp"
  40 #include "prims/privilegedStack.hpp"
  41 #include "runtime/arguments.hpp"
  42 #include "runtime/atomic.hpp"
  43 #include "runtime/frame.hpp"
  44 #include "runtime/java.hpp"
  45 #include "runtime/os.hpp"
  46 #include "runtime/sharedRuntime.hpp"
  47 #include "runtime/stubCodeGenerator.hpp"
  48 #include "runtime/stubRoutines.hpp"
  49 #include "runtime/thread.inline.hpp"
  50 #include "runtime/vframe.hpp"
  51 #include "runtime/vm_version.hpp"
  52 #include "services/heapDumper.hpp"
  53 #include "utilities/defaultStream.hpp"
  54 #include "utilities/events.hpp"
  55 #include "utilities/formatBuffer.hpp"
  56 #include "utilities/globalDefinitions.hpp"
  57 #include "utilities/macros.hpp"
  58 #include "utilities/vmError.hpp"
  59 
  60 #include <stdio.h>
  61 
  62 // Support for showing register content on asserts/guarantees.
  63 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
  64 static intptr_t g_dummy;
  65 void* volatile g_assert_poison = &g_dummy;
  66 static intx g_asserting_thread = 0;
  67 static void* g_assertion_context = NULL;
  68 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
  69 
  70 #ifndef ASSERT
  71 #  ifdef _DEBUG
  72    // NOTE: don't turn the lines below into a comment -- if you're getting
  73    // a compile error here, change the settings to define ASSERT
  74    ASSERT should be defined when _DEBUG is defined.  It is not intended to be used for debugging
  75    functions that do not slow down the system too much and thus can be left in optimized code.
  76    On the other hand, the code should not be included in a production version.
  77 #  endif // _DEBUG
  78 #endif // ASSERT
  79 
  80 
  81 #ifdef _DEBUG
  82 #  ifndef ASSERT
  83      configuration error: ASSERT must be defined in debug version
  84 #  endif // ASSERT
  85 #endif // _DEBUG
  86 
  87 
  88 #ifdef PRODUCT
  89 #  if -defined _DEBUG || -defined ASSERT


 203 
 204 #undef is_token_break
 205 
 206 #else
 207 
 208 // Place-holder for non-existent suppression check:
 209 #define error_is_suppressed(file_name, line_no) (false)
 210 
 211 #endif // !PRODUCT
 212 
 213 void report_vm_error(const char* file, int line, const char* error_msg)
 214 {
 215   report_vm_error(file, line, error_msg, "%s", "");
 216 }
 217 
 218 void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
 219 {
 220   if (Debugging || error_is_suppressed(file, line)) return;
 221   va_list detail_args;
 222   va_start(detail_args, detail_fmt);
 223   void* context = NULL;
 224 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
 225   if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
 226     context = g_assertion_context;
 227   }
 228 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
 229   VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args);
 230   va_end(detail_args);
 231 }
 232 
 233 void report_vm_status_error(const char* file, int line, const char* error_msg,
 234                             int status, const char* detail) {
 235   report_vm_error(file, line, error_msg, "error %s(%d), %s", os::errno_name(status), status, detail);
 236 }
 237 
 238 void report_fatal(const char* file, int line, const char* detail_fmt, ...)
 239 {
 240   if (Debugging || error_is_suppressed(file, line)) return;
 241   va_list detail_args;
 242   va_start(detail_args, detail_fmt);
 243   void* context = NULL;
 244 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
 245   if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
 246     context = g_assertion_context;
 247   }
 248 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
 249   VMError::report_and_die(Thread::current_or_null(), context, file, line, "fatal error", detail_fmt, detail_args);
 250   va_end(detail_args);
 251 }
 252 
 253 void report_vm_out_of_memory(const char* file, int line, size_t size,
 254                              VMErrorType vm_err_type, const char* detail_fmt, ...) {
 255   if (Debugging) return;
 256   va_list detail_args;
 257   va_start(detail_args, detail_fmt);
 258   VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
 259   va_end(detail_args);
 260 
 261   // The UseOSErrorReporting option in report_and_die() may allow a return
 262   // to here. If so then we'll have to figure out how to handle it.
 263   guarantee(false, "report_and_die() should not return here");
 264 }
 265 
 266 void report_should_not_call(const char* file, int line) {
 267   report_vm_error(file, line, "ShouldNotCall()");
 268 }
 269 


 679 STATIC_ASSERT(true);
 680 STATIC_ASSERT(1 == 1);
 681 STATIC_ASSERT(0 == 0);
 682 
 683 void test_multiple_static_assert_forms_in_function_scope() {
 684   STATIC_ASSERT(true);
 685   STATIC_ASSERT(true);
 686   STATIC_ASSERT(0 == 0);
 687   STATIC_ASSERT(1 == 1);
 688 }
 689 
 690 // class scope
 691 struct TestMultipleStaticAssertFormsInClassScope {
 692   STATIC_ASSERT(true);
 693   STATIC_ASSERT(true);
 694   STATIC_ASSERT(0 == 0);
 695   STATIC_ASSERT(1 == 1);
 696 };
 697 
 698 #endif // !PRODUCT
 699 
 700 // Support for showing register content on asserts/guarantees.
 701 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
 702 #ifdef _WIN32
 703 typedef CONTEXT context_t;
 704 #else
 705 typedef ucontext_t context_t;
 706 #endif
 707 
 708 static context_t g_stored_assertion_context;
 709 
 710 void initialize_assert_poison() {
 711   char* page = os::reserve_memory(os::vm_page_size());
 712   if (page) {
 713     if (os::commit_memory(page, os::vm_page_size(), false) &&
 714         os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) {
 715       g_assert_poison = page;
 716     }
 717   }
 718 }
 719 
 720 static bool store_context(const void* context) {
 721   if (memcpy(&g_stored_assertion_context, context, sizeof(context_t)) == false) {
 722     return false;
 723   }
 724 #if defined(__linux) && defined(PPC64)
 725   // on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up
 726   //  after copying the context (see comment in sys/ucontext.h):
 727   *((void**) &g_stored_assertion_context.uc_mcontext.regs) = &(g_stored_assertion_context.uc_mcontext.gp_regs);
 728 #endif
 729   return true;
 730 }
 731 
 732 bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {
 733   if (faulting_address == g_assert_poison) {
 734     // Disarm poison page.
 735     os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX);
 736     // Store Context away.
 737     if (ucVoid) {
 738       const jlong my_tid = os::current_thread_id();
 739       if (Atomic::cmpxchg(my_tid, &g_asserting_thread, (intx)0) == 0) {
 740         if (store_context(ucVoid)) {
 741           g_assertion_context = &g_stored_assertion_context;
 742         }
 743       }
 744     }
 745     return true;
 746   }
 747   return false;
 748 }
 749 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
 750 
< prev index next >