1 Star 0 Fork 81

fuowang/openjdk-1.8.0

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
8219584-Try-to-dump-error-file-by-thread-which-cause.patch 16.40 KB
一键复制 编辑 原始数据 按行查看 历史
eapen 提交于 2023-01-11 10:00 . I69W1Y: Add feature and bug fix for 8u352
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
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/fuowang/openjdk-1.8.0.git
git@gitee.com:fuowang/openjdk-1.8.0.git
fuowang
openjdk-1.8.0
openjdk-1.8.0
master

搜索帮助