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
|