Projects
openEuler:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:8219584-Try-to-dump-error-file...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:8219584-Try-to-dump-error-file-by-thread-which-cause.patch of Package openjdk-1.8.0
From b61cd484f501a1fe7d49c336878a4b8398e727d9 Mon Sep 17 00:00:00 2001 From: eapen <zhangyipeng7@huawei.com> Date: Thu, 15 Dec 2022 14:28:05 +0800 Subject: [PATCH 20/33] I68TO2: 8219584: Try to dump error file by thread which causes safepoint timeout --- hotspot/src/os/posix/vm/os_posix.cpp | 31 ++++++- hotspot/src/os/windows/vm/os_windows.cpp | 9 ++ hotspot/src/share/vm/runtime/globals.hpp | 2 +- hotspot/src/share/vm/runtime/os.hpp | 4 + hotspot/src/share/vm/runtime/safepoint.cpp | 21 +++-- hotspot/src/share/vm/runtime/vmThread.cpp | 36 +++++--- hotspot/src/share/vm/runtime/vmThread.hpp | 10 ++- hotspot/src/share/vm/utilities/vmError.cpp | 3 + .../Safepoint/TestAbortVMOnSafepointTimeout.java | 97 ++++++++++++++++++++++ 9 files changed, 195 insertions(+), 18 deletions(-) create mode 100644 hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp index e7f1fdd..d2663bd 100644 --- a/hotspot/src/os/posix/vm/os_posix.cpp +++ b/hotspot/src/os/posix/vm/os_posix.cpp @@ -26,6 +26,7 @@ #include "prims/jvm.h" #include "runtime/frame.inline.hpp" #include "runtime/os.hpp" +#include "utilities/events.hpp" #include "utilities/vmError.hpp" #include <signal.h> @@ -814,6 +815,15 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t return true; } +bool os::signal_sent_by_kill(const void* siginfo) { + const siginfo_t* const si = (const siginfo_t*)siginfo; + return si->si_code == SI_USER || si->si_code == SI_QUEUE +#ifdef SI_TKILL + || si->si_code == SI_TKILL +#endif + ; +} + // A POSIX conform, platform-independend siginfo print routine. // Short print out on one line. void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) { @@ -844,7 +854,7 @@ void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) { const int me = (int) ::getpid(); const int pid = (int) si->si_pid; - if (si->si_code == SI_USER || si->si_code == SI_QUEUE) { + if (signal_sent_by_kill(si)) { if (IS_VALID_PID(pid) && pid != me) { os->print(", sent from pid: %d (uid: %d)", pid, (int) si->si_uid); } @@ -860,6 +870,25 @@ void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) { } } +bool os::signal_thread(Thread* thread, int sig, const char* reason) { + OSThread* osthread = thread->osthread(); + if (osthread) { +#if defined (SOLARIS) + // Note: we cannot use pthread_kill on Solaris - not because + // its missing, but because we do not have the pthread_t id. + int status = thr_kill(osthread->thread_id(), sig); +#else + int status = pthread_kill(osthread->pthread_id(), sig); +#endif + if (status == 0) { + Events::log(Thread::current(), "sent signal %d to Thread " INTPTR_FORMAT " because %s.", + sig, p2i(thread), reason); + return true; + } + } + return false; +} + bool os::Posix::is_root(uid_t uid){ return ROOT_UID == uid; } diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index cc31126..cf1036c 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -1877,6 +1877,11 @@ void os::print_memory_info(outputStream* st) { st->cr(); } +bool os::signal_sent_by_kill(const void* siginfo) { + // TODO: Is this possible? + return false; +} + void os::print_siginfo(outputStream *st, void *siginfo) { EXCEPTION_RECORD* er = (EXCEPTION_RECORD*)siginfo; st->print("siginfo:"); @@ -1911,6 +1916,10 @@ void os::print_siginfo(outputStream *st, void *siginfo) { st->cr(); } +bool os::signal_thread(Thread* thread, int sig, const char* reason) { + // TODO: Can we kill thread? + return false; +} int os::vsnprintf(char* buf, size_t len, const char* fmt, va_list args) { #if _MSC_VER >= 1900 diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 10e4e7f..64d40e0 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -650,7 +650,7 @@ class CommandLineFlags { "Print out every time compilation is longer than " \ "a given threshold") \ \ - develop(bool, SafepointALot, false, \ + diagnostic(bool, SafepointALot, false, \ "Generate a lot of safepoints. This works with " \ "GuaranteedSafepointInterval") \ \ diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index 5f41e96..092459c 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -492,6 +492,9 @@ class os: AllStatic { static void pd_start_thread(Thread* thread); static void start_thread(Thread* thread); + // Returns true if successful. + static bool signal_thread(Thread* thread, int sig, const char* reason); + static void initialize_thread(Thread* thr); static void free_thread(OSThread* osthread); @@ -653,6 +656,7 @@ class os: AllStatic { static void print_environment_variables(outputStream* st, const char** env_list, char* buffer, int len); static void print_context(outputStream* st, void* context); static void print_register_info(outputStream* st, void* context); + static bool signal_sent_by_kill(const void* siginfo); static void print_siginfo(outputStream* st, void* siginfo); static void print_signal_handlers(outputStream* st, char* buf, size_t buflen); static void print_date_and_time(outputStream* st, char* buf, size_t buflen); diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp index 440617c..8408bed 100644 --- a/hotspot/src/share/vm/runtime/safepoint.cpp +++ b/hotspot/src/share/vm/runtime/safepoint.cpp @@ -476,8 +476,7 @@ void SafepointSynchronize::begin() { GC_locker::set_jni_lock_count(_current_jni_active_count); if (TraceSafepoint) { - VM_Operation *op = VMThread::vm_operation(); - tty->print_cr("Entering safepoint region: %s", (op != NULL) ? op->name() : "no vm operation"); + tty->print_cr("Entering safepoint region: %s", VMThread::vm_safepoint_description()); } RuntimeService::record_safepoint_synchronized(); @@ -929,11 +928,23 @@ void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason // To debug the long safepoint, specify both AbortVMOnSafepointTimeout & // ShowMessageBoxOnError. if (AbortVMOnSafepointTimeout) { + // Send the blocking thread a signal to terminate and write an error file. + for (JavaThread *cur_thread = Threads::first(); cur_thread; + cur_thread = cur_thread->next()) { + ThreadSafepointState *cur_state = cur_thread->safepoint_state(); + if (cur_thread->thread_state() != _thread_blocked && + ((reason == _spinning_timeout && cur_state->is_running()) || + (reason == _blocking_timeout && !cur_state->has_called_back()))) { + if (!os::signal_thread(cur_thread, SIGILL, "blocking a safepoint")) { + break; // Could not send signal. Report fatal error. + } + // Give cur_thread a chance to report the error and terminate the VM. + os::sleep(Thread::current(), 3000, false); + } + } char msg[1024]; - VM_Operation *op = VMThread::vm_operation(); sprintf(msg, "Safepoint sync time longer than " INTX_FORMAT "ms detected when executing %s.", - SafepointTimeoutDelay, - op != NULL ? op->name() : "no vm operation"); + SafepointTimeoutDelay, VMThread::vm_safepoint_description()); fatal(msg); } } diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp index b27c287..4f1695e 100644 --- a/hotspot/src/share/vm/runtime/vmThread.cpp +++ b/hotspot/src/share/vm/runtime/vmThread.cpp @@ -217,6 +217,7 @@ VMThread* VMThread::_vm_thread = NULL; VM_Operation* VMThread::_cur_vm_operation = NULL; VMOperationQueue* VMThread::_vm_queue = NULL; PerfCounter* VMThread::_perf_accumulated_vm_operation_time = NULL; +const char* VMThread::_no_op_reason = NULL; void VMThread::create() { @@ -290,6 +291,7 @@ void VMThread::run() { } // 4526887 let VM thread exit at Safepoint + _no_op_reason = "Halt"; SafepointSynchronize::begin(); if (VerifyBeforeExit) { @@ -422,6 +424,25 @@ void VMThread::evaluate_operation(VM_Operation* op) { } } +bool VMThread::no_op_safepoint_needed(bool check_time) { + if (SafepointALot) { + _no_op_reason = "SafepointALot"; + return true; + } + if (!SafepointSynchronize::is_cleanup_needed()) { + return false; + } + if (check_time) { + long interval = SafepointSynchronize::last_non_safepoint_interval(); + bool max_time_exceeded = GuaranteedSafepointInterval != 0 && + (interval > GuaranteedSafepointInterval); + if (!max_time_exceeded) { + return false; + } + } + _no_op_reason = "Cleanup"; + return true; +} void VMThread::loop() { assert(_cur_vm_operation == NULL, "no current one should be executing"); @@ -460,8 +481,7 @@ void VMThread::loop() { exit(-1); } - if (timedout && (SafepointALot || - SafepointSynchronize::is_cleanup_needed())) { + if (timedout && VMThread::no_op_safepoint_needed(false)) { MutexUnlockerEx mul(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag); // Force a safepoint since we have not had one for at least @@ -585,14 +605,10 @@ void VMThread::loop() { // // We want to make sure that we get to a safepoint regularly. // - if (SafepointALot || SafepointSynchronize::is_cleanup_needed()) { - long interval = SafepointSynchronize::last_non_safepoint_interval(); - bool max_time_exceeded = GuaranteedSafepointInterval != 0 && (interval > GuaranteedSafepointInterval); - if (SafepointALot || max_time_exceeded) { - HandleMark hm(VMThread::vm_thread()); - SafepointSynchronize::begin(); - SafepointSynchronize::end(); - } + if (VMThread::no_op_safepoint_needed(true)) { + HandleMark hm(VMThread::vm_thread()); + SafepointSynchronize::begin(); + SafepointSynchronize::end(); } } } diff --git a/hotspot/src/share/vm/runtime/vmThread.hpp b/hotspot/src/share/vm/runtime/vmThread.hpp index a6d1ad3..d8af0d9 100644 --- a/hotspot/src/share/vm/runtime/vmThread.hpp +++ b/hotspot/src/share/vm/runtime/vmThread.hpp @@ -100,7 +100,12 @@ class VMThread: public NamedThread { static Monitor * _terminate_lock; static PerfCounter* _perf_accumulated_vm_operation_time; + static const char* _no_op_reason; + + static bool no_op_safepoint_needed(bool check_time); + void evaluate_operation(VM_Operation* op); + public: // Constructor VMThread(); @@ -123,7 +128,10 @@ class VMThread: public NamedThread { static void execute(VM_Operation* op); // Returns the current vm operation if any. - static VM_Operation* vm_operation() { return _cur_vm_operation; } + static VM_Operation* vm_operation() { return _cur_vm_operation; } + + // Returns the current vm operation name or set reason + static const char* vm_safepoint_description() { return _cur_vm_operation != NULL ? _cur_vm_operation->name() : _no_op_reason; }; // Returns the single instance of VMThread. static VMThread* vm_thread() { return _vm_thread; } diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp index 9b40a34..261591d 100644 --- a/hotspot/src/share/vm/utilities/vmError.cpp +++ b/hotspot/src/share/vm/utilities/vmError.cpp @@ -460,6 +460,9 @@ void VMError::report(outputStream* st) { st->print("%s", buf); st->print(" (0x%x)", _id); // signal number st->print(" at pc=" PTR_FORMAT, _pc); + if (_siginfo != NULL && os::signal_sent_by_kill(_siginfo)) { + st->print(" (sent by kill)"); + } } else { if (should_report_bug(_id)) { st->print("Internal Error"); diff --git a/hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java b/hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java new file mode 100644 index 0000000..a097bdc --- /dev/null +++ b/hotspot/test/runtime/Safepoint/TestAbortVMOnSafepointTimeout.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019, SAP SE. All rights reserved. + * Copyright (c) 2021, Huawei Technologies Co., Ltd. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.*; + +/* + * @test TestAbortVMOnSafepointTimeout + * @summary Check if VM can kill thread which doesn't reach safepoint. + * @bug 8219584 8227528 + * @library /testlibrary + * + */ + +public class TestAbortVMOnSafepointTimeout { + + public static void main(String[] args) throws Exception { + if (args.length > 0) { + int result = test_loop(3); + System.out.println("This message would occur after some time with result " + result); + return; + } + + testWith(500, 500); + } + + static int test_loop(int x) { + int sum = 0; + if (x != 0) { + // Long running loop without safepoint. + for (int y = 1; y < Integer.MAX_VALUE; ++y) { + if (y % x == 0) ++sum; + } + } + return sum; + } + + public static void testWith(int sfpt_interval, int timeout_delay) throws Exception { + // -XX:-UseCountedLoopSafepoints - is used to prevent the loop + // in test_loop() to poll for safepoints. + // -XX:LoopStripMiningIter=0 and -XX:LoopUnrollLimit=0 - are + // used to prevent optimizations over the loop in test_loop() + // since we actually want it to provoke a safepoint timeout. + // -XX:-UseBiasedLocking - is used to prevent biased locking + // handshakes from changing the timing of this test. + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:-UseBiasedLocking", + "-XX:+SafepointTimeout", + "-XX:+SafepointALot", + "-XX:+AbortVMOnSafepointTimeout", + "-XX:SafepointTimeoutDelay=" + timeout_delay, + "-XX:GuaranteedSafepointInterval=" + sfpt_interval, + "-XX:-TieredCompilation", + "-XX:-UseCountedLoopSafepoints", + "-XX:LoopUnrollLimit=0", + "-XX:CompileCommand=compileonly,TestAbortVMOnSafepointTimeout::test_loop", + "-Xcomp", + "-XX:-CreateMinidumpOnCrash", + "-Xms64m", + "TestAbortVMOnSafepointTimeout", + "runTestLoop" + ); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + if (Platform.isWindows()) { + output.shouldMatch("Safepoint sync time longer than"); + } else { + output.shouldMatch("SIGILL"); + if (Platform.isLinux()) { + output.shouldMatch("(sent by kill)"); + } + output.shouldMatch("TestAbortVMOnSafepointTimeout.test_loop"); + } + output.shouldNotHaveExitValue(0); + } +} -- 1.8.3.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2