1 /*
  2  * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "jvm.h"
 27 #include "classfile/systemDictionary.hpp"
 28 #include "code/codeCache.hpp"
 29 #include "code/icBuffer.hpp"
 30 #include "code/nmethod.hpp"
 31 #include "code/vtableStubs.hpp"
 32 #include "compiler/compileBroker.hpp"
 33 #include "compiler/disassembler.hpp"
 34 #include "gc/shared/collectedHeap.hpp"
 35 #include "interpreter/interpreter.hpp"
 36 #include "memory/allocation.hpp"
 37 #include "memory/resourceArea.hpp"
 38 #include "memory/universe.hpp"
 39 #include "oops/klass.inline.hpp"
 40 #include "oops/oop.inline.hpp"
 41 #include "runtime/atomic.hpp"
 42 #include "runtime/flags/flagSetting.hpp"
 43 #include "runtime/frame.inline.hpp"
 44 #include "runtime/handles.inline.hpp"
 45 #include "runtime/java.hpp"
 46 #include "runtime/os.hpp"
 47 #include "runtime/sharedRuntime.hpp"
 48 #include "runtime/stubCodeGenerator.hpp"
 49 #include "runtime/stubRoutines.hpp"
 50 #include "runtime/thread.inline.hpp"
 51 #include "runtime/vframe.hpp"
 52 #include "runtime/vm_version.hpp"
 53 #include "services/heapDumper.hpp"
 54 #include "services/memTracker.hpp"
 55 #include "utilities/defaultStream.hpp"
 56 #include "utilities/events.hpp"
 57 #include "utilities/formatBuffer.hpp"
 58 #include "utilities/globalDefinitions.hpp"
 59 #include "utilities/macros.hpp"
 60 #include "utilities/vmError.hpp"
 61 
 62 #include <stdio.h>
 63 #include <stdarg.h>
 64 
 65 // Support for showing register content on asserts/guarantees.
 66 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
 67 static char g_dummy;
 68 char* g_assert_poison = &g_dummy;
 69 static intx g_asserting_thread = 0;
 70 static void* g_assertion_context = NULL;
 71 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
 72 
 73 // Set to suppress secondary error reporting.
 74 bool Debugging = false;
 75 
 76 #ifndef ASSERT
 77 #  ifdef _DEBUG
 78    // NOTE: don't turn the lines below into a comment -- if you're getting
 79    // a compile error here, change the settings to define ASSERT
 80    ASSERT should be defined when _DEBUG is defined.  It is not intended to be used for debugging
 81    functions that do not slow down the system too much and thus can be left in optimized code.
 82    On the other hand, the code should not be included in a production version.
 83 #  endif // _DEBUG
 84 #endif // ASSERT
 85 
 86 
 87 #ifdef _DEBUG
 88 #  ifndef ASSERT
 89      configuration error: ASSERT must be defined in debug version
 90 #  endif // ASSERT
 91 #endif // _DEBUG
 92 
 93 
 94 #ifdef PRODUCT
 95 #  if -defined _DEBUG || -defined ASSERT
 96      configuration error: ASSERT et al. must not be defined in PRODUCT version
 97 #  endif
 98 #endif // PRODUCT
 99 
100 #ifdef ASSERT
101 // This is to test that error reporting works if we assert during dynamic
102 // initialization of the hotspot. See JDK-8214975.
103 struct Crasher {
104   Crasher() {
105     // Using getenv - no other mechanism would work yet.
106     const char* s = ::getenv("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
107     if (s != NULL && ::strcmp(s, "1") == 0) {
108       fatal("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
109     }
110   }
111 };
112 static Crasher g_crasher;
113 #endif // ASSERT
114 
115 ATTRIBUTE_PRINTF(1, 2)
116 void warning(const char* format, ...) {
117   if (PrintWarnings) {
118     FILE* const err = defaultStream::error_stream();
119     jio_fprintf(err, "%s warning: ", VM_Version::vm_name());
120     va_list ap;
121     va_start(ap, format);
122     vfprintf(err, format, ap);
123     va_end(ap);
124     fputc('\n', err);
125   }
126 }
127 
128 #ifndef PRODUCT
129 
130 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
131 
132 static const char* last_file_name = NULL;
133 static int         last_line_no   = -1;
134 
135 // assert/guarantee/... may happen very early during VM initialization.
136 // Don't rely on anything that is initialized by Threads::create_vm(). For
137 // example, don't use tty.
138 bool error_is_suppressed(const char* file_name, int line_no) {
139   // The following 1-element cache requires that passed-in
140   // file names are always only constant literals.
141   if (file_name == last_file_name && line_no == last_line_no)  return true;
142 
143   int file_name_len = (int)strlen(file_name);
144   char separator = os::file_separator()[0];
145   const char* base_name = strrchr(file_name, separator);
146   if (base_name == NULL)
147     base_name = file_name;
148 
149   // scan the SuppressErrorAt option
150   const char* cp = SuppressErrorAt;
151   for (;;) {
152     const char* sfile;
153     int sfile_len;
154     int sline;
155     bool noisy;
156     while ((*cp) != '\0' && is_token_break(*cp))  cp++;
157     if ((*cp) == '\0')  break;
158     sfile = cp;
159     while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':')  cp++;
160     sfile_len = cp - sfile;
161     if ((*cp) == ':')  cp++;
162     sline = 0;
163     while ((*cp) != '\0' && isdigit(*cp)) {
164       sline *= 10;
165       sline += (*cp) - '0';
166       cp++;
167     }
168     // "file:line!" means the assert suppression is not silent
169     noisy = ((*cp) == '!');
170     while ((*cp) != '\0' && !is_token_break(*cp))  cp++;
171     // match the line
172     if (sline != 0) {
173       if (sline != line_no)  continue;
174     }
175     // match the file
176     if (sfile_len > 0) {
177       const char* look = file_name;
178       const char* look_max = file_name + file_name_len - sfile_len;
179       const char* foundp;
180       bool match = false;
181       while (!match
182              && (foundp = strchr(look, sfile[0])) != NULL
183              && foundp <= look_max) {
184         match = true;
185         for (int i = 1; i < sfile_len; i++) {
186           if (sfile[i] != foundp[i]) {
187             match = false;
188             break;
189           }
190         }
191         look = foundp + 1;
192       }
193       if (!match)  continue;
194     }
195     // got a match!
196     if (noisy) {
197       fdStream out(defaultStream::output_fd());
198       out.print_raw("[error suppressed at ");
199       out.print_raw(base_name);
200       char buf[16];
201       jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
202       out.print_raw_cr(buf);
203     } else {
204       // update 1-element cache for fast silent matches
205       last_file_name = file_name;
206       last_line_no   = line_no;
207     }
208     return true;
209   }
210 
211   if (!VMError::is_error_reported() && !SuppressFatalErrorMessage) {
212     // print a friendly hint:
213     fdStream out(defaultStream::output_fd());
214     out.print_raw_cr("# To suppress the following error report, specify this argument");
215     out.print_raw   ("# after -XX: or in .hotspotrc:  SuppressErrorAt=");
216     out.print_raw   (base_name);
217     char buf[16];
218     jio_snprintf(buf, sizeof(buf), ":%d", line_no);
219     out.print_raw_cr(buf);
220   }
221   return false;
222 }
223 
224 #undef is_token_break
225 
226 #else
227 
228 // Place-holder for non-existent suppression check:
229 #define error_is_suppressed(file_name, line_no) (false)
230 
231 #endif // !PRODUCT
232 
233 void report_vm_error(const char* file, int line, const char* error_msg)
234 {
235   report_vm_error(file, line, error_msg, "%s", "");
236 }
237 
238 
239 static void print_error_for_unit_test(const char* message, const char* detail_fmt, va_list detail_args) {
240 #ifdef ASSERT
241   if (ExecutingUnitTests) {
242     char detail_msg[256];
243     if (detail_fmt != NULL) {
244       // Special handling for the sake of gtest death tests which expect the assert
245       // message to be printed in one short line to stderr (see TEST_VM_ASSERT_MSG) and
246       // cannot be tweaked to accept our normal assert message.
247       va_list detail_args_copy;
248       va_copy(detail_args_copy, detail_args);
249       jio_vsnprintf(detail_msg, sizeof(detail_msg), detail_fmt, detail_args_copy);
250 
251       // the VM assert tests look for "assert failed: "
252       if (message == NULL) {
253         fprintf(stderr, "assert failed: %s", detail_msg);
254       } else {
255         if (strlen(detail_msg) > 0) {
256           fprintf(stderr, "assert failed: %s: %s", message, detail_msg);
257         } else {
258           fprintf(stderr, "assert failed: Error: %s", message);
259         }
260       }
261       ::fflush(stderr);
262       va_end(detail_args_copy);
263     }
264   }
265 #endif // ASSERT
266 }
267 
268 void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)
269 {
270   if (Debugging || error_is_suppressed(file, line)) return;
271   va_list detail_args;
272   va_start(detail_args, detail_fmt);
273   void* context = NULL;
274 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
275   if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
276     context = g_assertion_context;
277   }
278 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
279 
280   print_error_for_unit_test(error_msg, detail_fmt, detail_args);
281 
282   VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args);
283   va_end(detail_args);
284 }
285 
286 void report_vm_status_error(const char* file, int line, const char* error_msg,
287                             int status, const char* detail) {
288   report_vm_error(file, line, error_msg, "error %s(%d), %s", os::errno_name(status), status, detail);
289 }
290 
291 void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...) {
292   if (Debugging || error_is_suppressed(file, line)) return;
293   va_list detail_args;
294   va_start(detail_args, detail_fmt);
295   void* context = NULL;
296 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
297   if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {
298     context = g_assertion_context;
299   }
300 #endif // CAN_SHOW_REGISTERS_ON_ASSERT
301 
302   print_error_for_unit_test("fatal error", detail_fmt, detail_args);
303 
304   VMError::report_and_die(error_type, "fatal error", detail_fmt, detail_args,
305                           Thread::current_or_null(), NULL, NULL, context,
306                           file, line, 0);
307   va_end(detail_args);
308 }
309 
310 void report_vm_out_of_memory(const char* file, int line, size_t size,
311                              VMErrorType vm_err_type, const char* detail_fmt, ...) {
312   if (Debugging) return;
313   va_list detail_args;
314   va_start(detail_args, detail_fmt);
315 
316   print_error_for_unit_test(NULL, detail_fmt, detail_args);
317 
318   VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);
319   va_end(detail_args);
320 
321   // The UseOSErrorReporting option in report_and_die() may allow a return
322   // to here. If so then we'll have to figure out how to handle it.
323   guarantee(false, "report_and_die() should not return here");
324 }
325 
326 void report_should_not_call(const char* file, int line) {
327   report_vm_error(file, line, "ShouldNotCall()");
328 }
329 
330 void report_should_not_reach_here(const char* file, int line) {
331   report_vm_error(file, line, "ShouldNotReachHere()");
332 }
333 
334 void report_unimplemented(const char* file, int line) {
335   report_vm_error(file, line, "Unimplemented()");
336 }
337 
338 void report_untested(const char* file, int line, const char* message) {
339 #ifndef PRODUCT
340   warning("Untested: %s in %s: %d\n", message, file, line);
341 #endif // !PRODUCT
342 }
343 
344 void report_java_out_of_memory(const char* message) {
345   static int out_of_memory_reported = 0;
346 
347   // A number of threads may attempt to report OutOfMemoryError at around the
348   // same time. To avoid dumping the heap or executing the data collection
349   // commands multiple times we just do it once when the first threads reports
350   // the error.
351   if (Atomic::cmpxchg(&out_of_memory_reported, 0, 1) == 0) {
352     // create heap dump before OnOutOfMemoryError commands are executed
353     if (HeapDumpOnOutOfMemoryError) {
354       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
355       HeapDumper::dump_heap_from_oome();
356     }
357 
358     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
359       VMError::report_java_out_of_memory(message);
360     }
361 
362     if (CrashOnOutOfMemoryError) {
363       tty->print_cr("Aborting due to java.lang.OutOfMemoryError: %s", message);
364       report_fatal(OOM_JAVA_HEAP_FATAL, __FILE__, __LINE__, "OutOfMemory encountered: %s", message);
365     }
366 
367     if (ExitOnOutOfMemoryError) {
368       tty->print_cr("Terminating due to java.lang.OutOfMemoryError: %s", message);
369       os::_exit(3); // quick exit with no cleanup hooks run
370     }
371   }
372 }
373 
374 // ------ helper functions for debugging go here ------------
375 
376 // All debug entries should be wrapped with a stack allocated
377 // Command object. It makes sure a resource mark is set and
378 // flushes the logfile to prevent file sharing problems.
379 
380 class Command : public StackObj {
381  private:
382   ResourceMark rm;
383   bool debug_save;
384  public:
385   static int level;
386   Command(const char* str) {
387     debug_save = Debugging;
388     Debugging = true;
389     if (level++ > 0)  return;
390     tty->cr();
391     tty->print_cr("\"Executing %s\"", str);
392   }
393 
394   ~Command() {
395     tty->flush();
396     Debugging = debug_save;
397     level--;
398   }
399 };
400 
401 int Command::level = 0;
402 
403 extern "C" JNIEXPORT void blob(CodeBlob* cb) {
404   Command c("blob");
405   cb->print();
406 }
407 
408 
409 extern "C" JNIEXPORT void dump_vtable(address p) {
410   Command c("dump_vtable");
411   Klass* k = (Klass*)p;
412   k->vtable().print();
413 }
414 
415 
416 extern "C" JNIEXPORT void nm(intptr_t p) {
417   // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
418   Command c("nm");
419   CodeBlob* cb = CodeCache::find_blob((address)p);
420   if (cb == NULL) {
421     tty->print_cr("NULL");
422   } else {
423     cb->print();
424   }
425 }
426 
427 
428 extern "C" JNIEXPORT void disnm(intptr_t p) {
429   Command c("disnm");
430   CodeBlob* cb = CodeCache::find_blob((address) p);
431   if (cb != NULL) {
432     nmethod* nm = cb->as_nmethod_or_null();
433     if (nm != NULL) {
434       nm->print();
435     } else {
436       cb->print();
437     }
438     Disassembler::decode(cb);
439   }
440 }
441 
442 
443 extern "C" JNIEXPORT void printnm(intptr_t p) {
444   char buffer[256];
445   sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
446   Command c(buffer);
447   CodeBlob* cb = CodeCache::find_blob((address) p);
448   if (cb->is_nmethod()) {
449     nmethod* nm = (nmethod*)cb;
450     nm->print_nmethod(true);
451   }
452 }
453 
454 
455 extern "C" JNIEXPORT void universe() {
456   Command c("universe");
457   Universe::print_on(tty);
458 }
459 
460 
461 extern "C" JNIEXPORT void verify() {
462   // try to run a verify on the entire system
463   // note: this may not be safe if we're not at a safepoint; for debugging,
464   // this manipulates the safepoint settings to avoid assertion failures
465   Command c("universe verify");
466   bool safe = SafepointSynchronize::is_at_safepoint();
467   if (!safe) {
468     tty->print_cr("warning: not at safepoint -- verify may fail");
469     SafepointSynchronize::set_is_at_safepoint();
470   }
471   // Ensure Eden top is correct before verification
472   Universe::heap()->prepare_for_verify();
473   Universe::verify();
474   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
475 }
476 
477 
478 extern "C" JNIEXPORT void pp(void* p) {
479   Command c("pp");
480   FlagSetting fl(DisplayVMOutput, true);
481   if (Universe::heap()->is_in(p)) {
482     oop obj = cast_to_oop(p);
483     obj->print();
484   } else {
485     tty->print(PTR_FORMAT, p2i(p));
486   }
487 }
488 
489 
490 extern "C" JNIEXPORT void findpc(intptr_t x);
491 
492 extern "C" JNIEXPORT void ps() { // print stack
493   if (Thread::current_or_null() == NULL) return;
494   Command c("ps");
495 
496   // Prints the stack of the current Java thread
497   JavaThread* p = JavaThread::active();
498   tty->print(" for thread: ");
499   p->print();
500   tty->cr();
501 
502   if (p->has_last_Java_frame()) {
503     // If the last_Java_fp is set we are in C land and
504     // can call the standard stack_trace function.
505     p->print_stack();
506 #ifndef PRODUCT
507     if (Verbose) p->trace_stack();
508   } else {
509     frame f = os::current_frame();
510     RegisterMap reg_map(p);
511     f = f.sender(&reg_map);
512     tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id()));
513     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
514 #endif
515   }
516 }
517 
518 extern "C" JNIEXPORT void pfl() {
519   // print frame layout
520   Command c("pfl");
521   JavaThread* p = JavaThread::active();
522   tty->print(" for thread: ");
523   p->print();
524   tty->cr();
525   if (p->has_last_Java_frame()) {
526     p->print_frame_layout();
527   }
528 }
529 
530 extern "C" JNIEXPORT void psf() { // print stack frames
531   {
532     Command c("psf");
533     JavaThread* p = JavaThread::active();
534     tty->print(" for thread: ");
535     p->print();
536     tty->cr();
537     if (p->has_last_Java_frame()) {
538       p->trace_frames();
539     }
540   }
541 }
542 
543 
544 extern "C" JNIEXPORT void threads() {
545   Command c("threads");
546   Threads::print(false, true);
547 }
548 
549 
550 extern "C" JNIEXPORT void psd() {
551   Command c("psd");
552   SystemDictionary::print();
553 }
554 
555 
556 extern "C" JNIEXPORT void pss() { // print all stacks
557   if (Thread::current_or_null() == NULL) return;
558   Command c("pss");
559   Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
560 }
561 
562 // #ifndef PRODUCT
563 
564 extern "C" JNIEXPORT void debug() {               // to set things up for compiler debugging
565   Command c("debug");
566   NOT_PRODUCT(WizardMode = true;)
567   PrintCompilation = true;
568   PrintInlining = PrintAssembly = true;
569   tty->flush();
570 }
571 
572 
573 extern "C" JNIEXPORT void ndebug() {              // undo debug()
574   Command c("ndebug");
575   PrintCompilation = false;
576   PrintInlining = PrintAssembly = false;
577   tty->flush();
578 }
579 
580 
581 extern "C" JNIEXPORT void flush()  {
582   Command c("flush");
583   tty->flush();
584 }
585 
586 extern "C" JNIEXPORT void events() {
587   Command c("events");
588   Events::print();
589 }
590 
591 extern "C" JNIEXPORT Method* findm(intptr_t pc) {
592   Command c("findm");
593   nmethod* nm = CodeCache::find_nmethod((address)pc);
594   return (nm == NULL) ? (Method*)NULL : nm->method();
595 }
596 
597 
598 extern "C" JNIEXPORT nmethod* findnm(intptr_t addr) {
599   Command c("findnm");
600   return  CodeCache::find_nmethod((address)addr);
601 }
602 
603 extern "C" JNIEXPORT void find(intptr_t x) {
604   Command c("find");
605   os::print_location(tty, x, false);
606 }
607 
608 
609 extern "C" JNIEXPORT void findpc(intptr_t x) {
610   Command c("findpc");
611   os::print_location(tty, x, true);
612 }
613 
614 
615 // Need method pointer to find bcp, when not in permgen.
616 extern "C" JNIEXPORT void findbcp(intptr_t method, intptr_t bcp) {
617   Command c("findbcp");
618   Method* mh = (Method*)method;
619   if (!mh->is_native()) {
620     tty->print_cr("bci_from(%p) = %d; print_codes():",
621                         mh, mh->bci_from(address(bcp)));
622     mh->print_codes_on(tty);
623   }
624 }
625 
626 // int versions of all methods to avoid having to type type casts in the debugger
627 
628 void pp(intptr_t p)          { pp((void*)p); }
629 void pp(oop p)               { pp((void*)p); }
630 
631 void help() {
632   Command c("help");
633   tty->print_cr("basic");
634   tty->print_cr("  pp(void* p)   - try to make sense of p");
635   tty->print_cr("  ps()          - print current thread stack");
636   tty->print_cr("  pss()         - print all thread stacks");
637   tty->print_cr("  pm(int pc)    - print Method* given compiled PC");
638   tty->print_cr("  findm(intptr_t pc) - finds Method*");
639   tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
640   tty->print_cr("  pns(void* sp, void* fp, void* pc)  - print native (i.e. mixed) stack trace. E.g.");
641   tty->print_cr("                   pns($sp, $rbp, $pc) on Linux/amd64 or");
642   tty->print_cr("                   pns($sp, $ebp, $pc) on Linux/x86 or");
643   tty->print_cr("                   pns($sp, $fp, $pc)  on Linux/AArch64 or");
644   tty->print_cr("                   pns($sp, 0, $pc)    on Linux/ppc64 or");
645   tty->print_cr("                   pns($sp, $s8, $pc)  on Linux/mips or");
646   tty->print_cr("                 - in gdb do 'set overload-resolution off' before calling pns()");
647   tty->print_cr("                 - in dbx do 'frame 1' before calling pns()");
648 
649   tty->print_cr("misc.");
650   tty->print_cr("  flush()       - flushes the log file");
651   tty->print_cr("  events()      - dump events from ring buffers");
652 
653 
654   tty->print_cr("compiler debugging");
655   tty->print_cr("  debug()       - to set things up for compiler debugging");
656   tty->print_cr("  ndebug()      - undo debug");
657 }
658 
659 #ifndef PRODUCT
660 extern "C" JNIEXPORT void pns(void* sp, void* fp, void* pc) { // print native stack
661   Command c("pns");
662   static char buf[O_BUFLEN];
663   Thread* t = Thread::current_or_null();
664   // Call generic frame constructor (certain arguments may be ignored)
665   frame fr(sp, fp, pc);
666   VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
667 }
668 
669 //
670 // This version of pns() will not work when called from the debugger, but is
671 // useful when called from within hotspot code. The advantages over pns()
672 // are not having to pass in any arguments, and it will work on Windows/x64.
673 //
674 // WARNING: Only intended for use when debugging. Do not leave calls to
675 // pns2() in committed source (product or debug).
676 //
677 extern "C" JNIEXPORT void pns2() { // print native stack
678   Command c("pns2");
679   static char buf[O_BUFLEN];
680   if (os::platform_print_native_stack(tty, NULL, buf, sizeof(buf))) {
681     // We have printed the native stack in platform-specific code,
682     // so nothing else to do in this case.
683   } else {
684     Thread* t = Thread::current_or_null();
685     frame fr = os::current_frame();
686     VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));
687   }
688 }
689 #endif
690 
691 
692 //////////////////////////////////////////////////////////////////////////////
693 // Test multiple STATIC_ASSERT forms in various scopes.
694 
695 #ifndef PRODUCT
696 
697 // namespace scope
698 STATIC_ASSERT(true);
699 STATIC_ASSERT(true);
700 STATIC_ASSERT(1 == 1);
701 STATIC_ASSERT(0 == 0);
702 
703 void test_multiple_static_assert_forms_in_function_scope() {
704   STATIC_ASSERT(true);
705   STATIC_ASSERT(true);
706   STATIC_ASSERT(0 == 0);
707   STATIC_ASSERT(1 == 1);
708 }
709 
710 // class scope
711 struct TestMultipleStaticAssertFormsInClassScope {
712   STATIC_ASSERT(true);
713   STATIC_ASSERT(true);
714   STATIC_ASSERT(0 == 0);
715   STATIC_ASSERT(1 == 1);
716 };
717 
718 #endif // !PRODUCT
719 
720 // Support for showing register content on asserts/guarantees.
721 #ifdef CAN_SHOW_REGISTERS_ON_ASSERT
722 
723 static ucontext_t g_stored_assertion_context;
724 
725 void initialize_assert_poison() {
726   char* page = os::reserve_memory(os::vm_page_size());
727   if (page) {
728     MemTracker::record_virtual_memory_type(page, mtInternal);
729     if (os::commit_memory(page, os::vm_page_size(), false) &&
730         os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) {
731       g_assert_poison = page;
732     }
733   }
734 }
735 
736 void disarm_assert_poison() {
737   g_assert_poison = &g_dummy;
738 }
739 
740 static void store_context(const void* context) {
741   memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t));
742 #if defined(LINUX) && defined(PPC64)
743   // on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up
744   //  after copying the context (see comment in sys/ucontext.h):
745   *((void**) &g_stored_assertion_context.uc_mcontext.regs) = &(g_stored_assertion_context.uc_mcontext.gp_regs);
746 #endif
747 }
748 
749 bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {
750   if (faulting_address == g_assert_poison) {
751     // Disarm poison page.
752     if (os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX) == false) {
753 #ifdef ASSERT
754       fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)",
755               errno, os::strerror(errno));
756       fflush(stderr);
757 #endif
758       return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds.
759     }
760     // Store Context away.
761     if (ucVoid) {
762       const intx my_tid = os::current_thread_id();
763       if (Atomic::cmpxchg(&g_asserting_thread, (intx)0, my_tid) == 0) {
764         store_context(ucVoid);
765         g_assertion_context = &g_stored_assertion_context;
766       }
767     }
768     return true;
769   }
770   return false;
771 }
772 #endif // CAN_SHOW_REGISTERS_ON_ASSERT