Path: blob/master/src/hotspot/share/utilities/debug.cpp
40949 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "jvm.h"26#include "classfile/systemDictionary.hpp"27#include "code/codeCache.hpp"28#include "code/icBuffer.hpp"29#include "code/nmethod.hpp"30#include "code/vtableStubs.hpp"31#include "compiler/compileBroker.hpp"32#include "compiler/disassembler.hpp"33#include "gc/shared/collectedHeap.hpp"34#include "interpreter/interpreter.hpp"35#include "memory/allocation.hpp"36#include "memory/resourceArea.hpp"37#include "memory/universe.hpp"38#include "oops/klass.inline.hpp"39#include "oops/oop.inline.hpp"40#include "runtime/atomic.hpp"41#include "runtime/flags/flagSetting.hpp"42#include "runtime/frame.inline.hpp"43#include "runtime/handles.inline.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 "services/memTracker.hpp"54#include "utilities/defaultStream.hpp"55#include "utilities/events.hpp"56#include "utilities/formatBuffer.hpp"57#include "utilities/globalDefinitions.hpp"58#include "utilities/macros.hpp"59#include "utilities/vmError.hpp"6061#include <stdio.h>62#include <stdarg.h>6364// Support for showing register content on asserts/guarantees.65#ifdef CAN_SHOW_REGISTERS_ON_ASSERT66static char g_dummy;67char* g_assert_poison = &g_dummy;68static intx g_asserting_thread = 0;69static void* g_assertion_context = NULL;70#endif // CAN_SHOW_REGISTERS_ON_ASSERT7172// Set to suppress secondary error reporting.73bool Debugging = false;7475#ifndef ASSERT76# ifdef _DEBUG77// NOTE: don't turn the lines below into a comment -- if you're getting78// a compile error here, change the settings to define ASSERT79ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging80functions that do not slow down the system too much and thus can be left in optimized code.81On the other hand, the code should not be included in a production version.82# endif // _DEBUG83#endif // ASSERT848586#ifdef _DEBUG87# ifndef ASSERT88configuration error: ASSERT must be defined in debug version89# endif // ASSERT90#endif // _DEBUG919293#ifdef PRODUCT94# if -defined _DEBUG || -defined ASSERT95configuration error: ASSERT et al. must not be defined in PRODUCT version96# endif97#endif // PRODUCT9899#ifdef ASSERT100// This is to test that error reporting works if we assert during dynamic101// initialization of the hotspot. See JDK-8214975.102struct Crasher {103Crasher() {104// Using getenv - no other mechanism would work yet.105const char* s = ::getenv("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");106if (s != NULL && ::strcmp(s, "1") == 0) {107fatal("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");108}109}110};111static Crasher g_crasher;112#endif // ASSERT113114ATTRIBUTE_PRINTF(1, 2)115void warning(const char* format, ...) {116if (PrintWarnings) {117FILE* const err = defaultStream::error_stream();118jio_fprintf(err, "%s warning: ", VM_Version::vm_name());119va_list ap;120va_start(ap, format);121vfprintf(err, format, ap);122va_end(ap);123fputc('\n', err);124}125}126127#ifndef PRODUCT128129#define is_token_break(ch) (isspace(ch) || (ch) == ',')130131static const char* last_file_name = NULL;132static int last_line_no = -1;133134// assert/guarantee/... may happen very early during VM initialization.135// Don't rely on anything that is initialized by Threads::create_vm(). For136// example, don't use tty.137bool error_is_suppressed(const char* file_name, int line_no) {138// The following 1-element cache requires that passed-in139// file names are always only constant literals.140if (file_name == last_file_name && line_no == last_line_no) return true;141142int file_name_len = (int)strlen(file_name);143char separator = os::file_separator()[0];144const char* base_name = strrchr(file_name, separator);145if (base_name == NULL)146base_name = file_name;147148// scan the SuppressErrorAt option149const char* cp = SuppressErrorAt;150for (;;) {151const char* sfile;152int sfile_len;153int sline;154bool noisy;155while ((*cp) != '\0' && is_token_break(*cp)) cp++;156if ((*cp) == '\0') break;157sfile = cp;158while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++;159sfile_len = cp - sfile;160if ((*cp) == ':') cp++;161sline = 0;162while ((*cp) != '\0' && isdigit(*cp)) {163sline *= 10;164sline += (*cp) - '0';165cp++;166}167// "file:line!" means the assert suppression is not silent168noisy = ((*cp) == '!');169while ((*cp) != '\0' && !is_token_break(*cp)) cp++;170// match the line171if (sline != 0) {172if (sline != line_no) continue;173}174// match the file175if (sfile_len > 0) {176const char* look = file_name;177const char* look_max = file_name + file_name_len - sfile_len;178const char* foundp;179bool match = false;180while (!match181&& (foundp = strchr(look, sfile[0])) != NULL182&& foundp <= look_max) {183match = true;184for (int i = 1; i < sfile_len; i++) {185if (sfile[i] != foundp[i]) {186match = false;187break;188}189}190look = foundp + 1;191}192if (!match) continue;193}194// got a match!195if (noisy) {196fdStream out(defaultStream::output_fd());197out.print_raw("[error suppressed at ");198out.print_raw(base_name);199char buf[16];200jio_snprintf(buf, sizeof(buf), ":%d]", line_no);201out.print_raw_cr(buf);202} else {203// update 1-element cache for fast silent matches204last_file_name = file_name;205last_line_no = line_no;206}207return true;208}209210if (!VMError::is_error_reported() && !SuppressFatalErrorMessage) {211// print a friendly hint:212fdStream out(defaultStream::output_fd());213out.print_raw_cr("# To suppress the following error report, specify this argument");214out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt=");215out.print_raw (base_name);216char buf[16];217jio_snprintf(buf, sizeof(buf), ":%d", line_no);218out.print_raw_cr(buf);219}220return false;221}222223#undef is_token_break224225#else226227// Place-holder for non-existent suppression check:228#define error_is_suppressed(file_name, line_no) (false)229230#endif // !PRODUCT231232void report_vm_error(const char* file, int line, const char* error_msg)233{234report_vm_error(file, line, error_msg, "%s", "");235}236237238static void print_error_for_unit_test(const char* message, const char* detail_fmt, va_list detail_args) {239#ifdef ASSERT240if (ExecutingUnitTests) {241char detail_msg[256];242if (detail_fmt != NULL) {243// Special handling for the sake of gtest death tests which expect the assert244// message to be printed in one short line to stderr (see TEST_VM_ASSERT_MSG) and245// cannot be tweaked to accept our normal assert message.246va_list detail_args_copy;247va_copy(detail_args_copy, detail_args);248jio_vsnprintf(detail_msg, sizeof(detail_msg), detail_fmt, detail_args_copy);249250// the VM assert tests look for "assert failed: "251if (message == NULL) {252fprintf(stderr, "assert failed: %s", detail_msg);253} else {254if (strlen(detail_msg) > 0) {255fprintf(stderr, "assert failed: %s: %s", message, detail_msg);256} else {257fprintf(stderr, "assert failed: Error: %s", message);258}259}260::fflush(stderr);261va_end(detail_args_copy);262}263}264#endif // ASSERT265}266267void report_vm_error(const char* file, int line, const char* error_msg, const char* detail_fmt, ...)268{269if (Debugging || error_is_suppressed(file, line)) return;270va_list detail_args;271va_start(detail_args, detail_fmt);272void* context = NULL;273#ifdef CAN_SHOW_REGISTERS_ON_ASSERT274if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {275context = g_assertion_context;276}277#endif // CAN_SHOW_REGISTERS_ON_ASSERT278279print_error_for_unit_test(error_msg, detail_fmt, detail_args);280281VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args);282va_end(detail_args);283}284285void report_vm_status_error(const char* file, int line, const char* error_msg,286int status, const char* detail) {287report_vm_error(file, line, error_msg, "error %s(%d), %s", os::errno_name(status), status, detail);288}289290void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...) {291if (Debugging || error_is_suppressed(file, line)) return;292va_list detail_args;293va_start(detail_args, detail_fmt);294void* context = NULL;295#ifdef CAN_SHOW_REGISTERS_ON_ASSERT296if (g_assertion_context != NULL && os::current_thread_id() == g_asserting_thread) {297context = g_assertion_context;298}299#endif // CAN_SHOW_REGISTERS_ON_ASSERT300301print_error_for_unit_test("fatal error", detail_fmt, detail_args);302303VMError::report_and_die(error_type, "fatal error", detail_fmt, detail_args,304Thread::current_or_null(), NULL, NULL, context,305file, line, 0);306va_end(detail_args);307}308309void report_vm_out_of_memory(const char* file, int line, size_t size,310VMErrorType vm_err_type, const char* detail_fmt, ...) {311if (Debugging) return;312va_list detail_args;313va_start(detail_args, detail_fmt);314315print_error_for_unit_test(NULL, detail_fmt, detail_args);316317VMError::report_and_die(Thread::current_or_null(), file, line, size, vm_err_type, detail_fmt, detail_args);318va_end(detail_args);319320// The UseOSErrorReporting option in report_and_die() may allow a return321// to here. If so then we'll have to figure out how to handle it.322guarantee(false, "report_and_die() should not return here");323}324325void report_should_not_call(const char* file, int line) {326report_vm_error(file, line, "ShouldNotCall()");327}328329void report_should_not_reach_here(const char* file, int line) {330report_vm_error(file, line, "ShouldNotReachHere()");331}332333void report_unimplemented(const char* file, int line) {334report_vm_error(file, line, "Unimplemented()");335}336337void report_untested(const char* file, int line, const char* message) {338#ifndef PRODUCT339warning("Untested: %s in %s: %d\n", message, file, line);340#endif // !PRODUCT341}342343void report_java_out_of_memory(const char* message) {344static int out_of_memory_reported = 0;345346// A number of threads may attempt to report OutOfMemoryError at around the347// same time. To avoid dumping the heap or executing the data collection348// commands multiple times we just do it once when the first threads reports349// the error.350if (Atomic::cmpxchg(&out_of_memory_reported, 0, 1) == 0) {351// create heap dump before OnOutOfMemoryError commands are executed352if (HeapDumpOnOutOfMemoryError) {353tty->print_cr("java.lang.OutOfMemoryError: %s", message);354HeapDumper::dump_heap_from_oome();355}356357if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {358VMError::report_java_out_of_memory(message);359}360361if (CrashOnOutOfMemoryError) {362tty->print_cr("Aborting due to java.lang.OutOfMemoryError: %s", message);363report_fatal(OOM_JAVA_HEAP_FATAL, __FILE__, __LINE__, "OutOfMemory encountered: %s", message);364}365366if (ExitOnOutOfMemoryError) {367tty->print_cr("Terminating due to java.lang.OutOfMemoryError: %s", message);368os::exit(3);369}370}371}372373// ------ helper functions for debugging go here ------------374375// All debug entries should be wrapped with a stack allocated376// Command object. It makes sure a resource mark is set and377// flushes the logfile to prevent file sharing problems.378379class Command : public StackObj {380private:381ResourceMark rm;382bool debug_save;383public:384static int level;385Command(const char* str) {386debug_save = Debugging;387Debugging = true;388if (level++ > 0) return;389tty->cr();390tty->print_cr("\"Executing %s\"", str);391}392393~Command() {394tty->flush();395Debugging = debug_save;396level--;397}398};399400int Command::level = 0;401402extern "C" JNIEXPORT void blob(CodeBlob* cb) {403Command c("blob");404cb->print();405}406407408extern "C" JNIEXPORT void dump_vtable(address p) {409Command c("dump_vtable");410Klass* k = (Klass*)p;411k->vtable().print();412}413414415extern "C" JNIEXPORT void nm(intptr_t p) {416// Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)417Command c("nm");418CodeBlob* cb = CodeCache::find_blob((address)p);419if (cb == NULL) {420tty->print_cr("NULL");421} else {422cb->print();423}424}425426427extern "C" JNIEXPORT void disnm(intptr_t p) {428Command c("disnm");429CodeBlob* cb = CodeCache::find_blob((address) p);430if (cb != NULL) {431nmethod* nm = cb->as_nmethod_or_null();432if (nm != NULL) {433nm->print();434} else {435cb->print();436}437Disassembler::decode(cb);438}439}440441442extern "C" JNIEXPORT void printnm(intptr_t p) {443char buffer[256];444sprintf(buffer, "printnm: " INTPTR_FORMAT, p);445Command c(buffer);446CodeBlob* cb = CodeCache::find_blob((address) p);447if (cb->is_nmethod()) {448nmethod* nm = (nmethod*)cb;449nm->print_nmethod(true);450}451}452453454extern "C" JNIEXPORT void universe() {455Command c("universe");456Universe::print_on(tty);457}458459460extern "C" JNIEXPORT void verify() {461// try to run a verify on the entire system462// note: this may not be safe if we're not at a safepoint; for debugging,463// this manipulates the safepoint settings to avoid assertion failures464Command c("universe verify");465bool safe = SafepointSynchronize::is_at_safepoint();466if (!safe) {467tty->print_cr("warning: not at safepoint -- verify may fail");468SafepointSynchronize::set_is_at_safepoint();469}470// Ensure Eden top is correct before verification471Universe::heap()->prepare_for_verify();472Universe::verify();473if (!safe) SafepointSynchronize::set_is_not_at_safepoint();474}475476477extern "C" JNIEXPORT void pp(void* p) {478Command c("pp");479FlagSetting fl(DisplayVMOutput, true);480if (Universe::heap()->is_in(p)) {481oop obj = cast_to_oop(p);482obj->print();483} else {484tty->print(PTR_FORMAT, p2i(p));485}486}487488489extern "C" JNIEXPORT void findpc(intptr_t x);490491extern "C" JNIEXPORT void ps() { // print stack492if (Thread::current_or_null() == NULL) return;493Command c("ps");494495// Prints the stack of the current Java thread496JavaThread* p = JavaThread::active();497tty->print(" for thread: ");498p->print();499tty->cr();500501if (p->has_last_Java_frame()) {502// If the last_Java_fp is set we are in C land and503// can call the standard stack_trace function.504p->print_stack();505#ifndef PRODUCT506if (Verbose) p->trace_stack();507} else {508frame f = os::current_frame();509RegisterMap reg_map(p);510f = f.sender(®_map);511tty->print("(guessing starting frame id=" PTR_FORMAT " based on current fp)\n", p2i(f.id()));512p->trace_stack_from(vframe::new_vframe(&f, ®_map, p));513f.pd_ps();514#endif515}516}517518extern "C" JNIEXPORT void pfl() {519// print frame layout520Command c("pfl");521JavaThread* p = JavaThread::active();522tty->print(" for thread: ");523p->print();524tty->cr();525if (p->has_last_Java_frame()) {526p->print_frame_layout();527}528}529530extern "C" JNIEXPORT void psf() { // print stack frames531{532Command c("psf");533JavaThread* p = JavaThread::active();534tty->print(" for thread: ");535p->print();536tty->cr();537if (p->has_last_Java_frame()) {538p->trace_frames();539}540}541}542543544extern "C" JNIEXPORT void threads() {545Command c("threads");546Threads::print(false, true);547}548549550extern "C" JNIEXPORT void psd() {551Command c("psd");552SystemDictionary::print();553}554555556extern "C" JNIEXPORT void pss() { // print all stacks557if (Thread::current_or_null() == NULL) return;558Command c("pss");559Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));560}561562// #ifndef PRODUCT563564extern "C" JNIEXPORT void debug() { // to set things up for compiler debugging565Command c("debug");566NOT_PRODUCT(WizardMode = true;)567PrintCompilation = true;568PrintInlining = PrintAssembly = true;569tty->flush();570}571572573extern "C" JNIEXPORT void ndebug() { // undo debug()574Command c("ndebug");575PrintCompilation = false;576PrintInlining = PrintAssembly = false;577tty->flush();578}579580581extern "C" JNIEXPORT void flush() {582Command c("flush");583tty->flush();584}585586extern "C" JNIEXPORT void events() {587Command c("events");588Events::print();589}590591extern "C" JNIEXPORT Method* findm(intptr_t pc) {592Command c("findm");593nmethod* nm = CodeCache::find_nmethod((address)pc);594return (nm == NULL) ? (Method*)NULL : nm->method();595}596597598extern "C" JNIEXPORT nmethod* findnm(intptr_t addr) {599Command c("findnm");600return CodeCache::find_nmethod((address)addr);601}602603extern "C" JNIEXPORT void find(intptr_t x) {604Command c("find");605os::print_location(tty, x, false);606}607608609extern "C" JNIEXPORT void findpc(intptr_t x) {610Command c("findpc");611os::print_location(tty, x, true);612}613614615// Need method pointer to find bcp, when not in permgen.616extern "C" JNIEXPORT void findbcp(intptr_t method, intptr_t bcp) {617Command c("findbcp");618Method* mh = (Method*)method;619if (!mh->is_native()) {620tty->print_cr("bci_from(%p) = %d; print_codes():",621mh, mh->bci_from(address(bcp)));622mh->print_codes_on(tty);623}624}625626// int versions of all methods to avoid having to type type casts in the debugger627628void pp(intptr_t p) { pp((void*)p); }629void pp(oop p) { pp((void*)p); }630631void help() {632Command c("help");633tty->print_cr("basic");634tty->print_cr(" pp(void* p) - try to make sense of p");635tty->print_cr(" ps() - print current thread stack");636tty->print_cr(" pss() - print all thread stacks");637tty->print_cr(" pm(int pc) - print Method* given compiled PC");638tty->print_cr(" findm(intptr_t pc) - finds Method*");639tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");640tty->print_cr(" pns(void* sp, void* fp, void* pc) - print native (i.e. mixed) stack trace. E.g.");641tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 or");642tty->print_cr(" pns($sp, $ebp, $pc) on Linux/x86 or");643tty->print_cr(" pns($sp, $fp, $pc) on Linux/AArch64 or");644tty->print_cr(" pns($sp, 0, $pc) on Linux/ppc64 or");645tty->print_cr(" pns($sp, $s8, $pc) on Linux/mips or");646tty->print_cr(" - in gdb do 'set overload-resolution off' before calling pns()");647tty->print_cr(" - in dbx do 'frame 1' before calling pns()");648649tty->print_cr("misc.");650tty->print_cr(" flush() - flushes the log file");651tty->print_cr(" events() - dump events from ring buffers");652653654tty->print_cr("compiler debugging");655tty->print_cr(" debug() - to set things up for compiler debugging");656tty->print_cr(" ndebug() - undo debug");657}658659#ifndef PRODUCT660extern "C" JNIEXPORT void pns(void* sp, void* fp, void* pc) { // print native stack661Command c("pns");662static char buf[O_BUFLEN];663Thread* t = Thread::current_or_null();664// Call generic frame constructor (certain arguments may be ignored)665frame fr(sp, fp, pc);666VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));667}668669//670// This version of pns() will not work when called from the debugger, but is671// 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 to675// pns2() in committed source (product or debug).676//677extern "C" JNIEXPORT void pns2() { // print native stack678Command c("pns2");679static char buf[O_BUFLEN];680if (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 {684Thread* t = Thread::current_or_null();685frame fr = os::current_frame();686VMError::print_native_stack(tty, fr, t, buf, sizeof(buf));687}688}689#endif690691692//////////////////////////////////////////////////////////////////////////////693// Test multiple STATIC_ASSERT forms in various scopes.694695#ifndef PRODUCT696697// namespace scope698STATIC_ASSERT(true);699STATIC_ASSERT(true);700STATIC_ASSERT(1 == 1);701STATIC_ASSERT(0 == 0);702703void test_multiple_static_assert_forms_in_function_scope() {704STATIC_ASSERT(true);705STATIC_ASSERT(true);706STATIC_ASSERT(0 == 0);707STATIC_ASSERT(1 == 1);708}709710// class scope711struct TestMultipleStaticAssertFormsInClassScope {712STATIC_ASSERT(true);713STATIC_ASSERT(true);714STATIC_ASSERT(0 == 0);715STATIC_ASSERT(1 == 1);716};717718#endif // !PRODUCT719720// Support for showing register content on asserts/guarantees.721#ifdef CAN_SHOW_REGISTERS_ON_ASSERT722723static ucontext_t g_stored_assertion_context;724725void initialize_assert_poison() {726char* page = os::reserve_memory(os::vm_page_size());727if (page) {728MemTracker::record_virtual_memory_type(page, mtInternal);729if (os::commit_memory(page, os::vm_page_size(), false) &&730os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) {731g_assert_poison = page;732}733}734}735736void disarm_assert_poison() {737g_assert_poison = &g_dummy;738}739740static void store_context(const void* context) {741memcpy(&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 up744// 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#endif747}748749bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) {750if (faulting_address == g_assert_poison) {751// Disarm poison page.752if (os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX) == false) {753#ifdef ASSERT754fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)",755errno, os::strerror(errno));756fflush(stderr);757#endif758return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds.759}760// Store Context away.761if (ucVoid) {762const intx my_tid = os::current_thread_id();763if (Atomic::cmpxchg(&g_asserting_thread, (intx)0, my_tid) == 0) {764store_context(ucVoid);765g_assertion_context = &g_stored_assertion_context;766}767}768return true;769}770return false;771}772#endif // CAN_SHOW_REGISTERS_ON_ASSERT773774775