8292054: Test runtime/posixSig/TestPosixSig.java fails with 'Test failed, bad output.'

Reviewed-by: coleenp, stuefe
This commit is contained in:
Harold Seigel 2022-08-17 19:56:14 +00:00
parent e8bc87956a
commit 0d96546ab9
8 changed files with 87 additions and 139 deletions

View File

@ -874,7 +874,7 @@ BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm
ifeq ($(call isTargetOs, windows), true)
BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT
BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libTestPsig.c
BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c
BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib
BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exedaemonDestroy := jvm.lib
else

View File

@ -890,7 +890,7 @@ int os::sigexitnum_pd() {
// This method is a periodic task to check for misbehaving JNI applications
// under CheckJNI, we can add any periodic checks here
void os::run_periodic_checks() {
void os::run_periodic_checks(outputStream* st) {
if (check_signals == false) return;
@ -924,8 +924,8 @@ void os::run_periodic_checks() {
// - print all signal handlers. As part of that printout, details will be printed
// about any modified handlers.
char buf[O_BUFLEN];
os::print_signal_handlers(tty, buf, O_BUFLEN);
tty->print_cr("Consider using jsig library.");
os::print_signal_handlers(st, buf, O_BUFLEN);
st->print_cr("Consider using jsig library.");
}
}

View File

@ -269,10 +269,10 @@ bool os::have_special_privileges() {
}
// This method is a periodic task to check for misbehaving JNI applications
// This method is a periodic task to check for misbehaving JNI applications
// under CheckJNI, we can add any periodic checks here.
// For Windows at the moment does nothing
void os::run_periodic_checks() {
void os::run_periodic_checks(outputStream* st) {
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. 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
@ -33,7 +33,7 @@
class JniPeriodicCheckerTask : public PeriodicTask {
public:
JniPeriodicCheckerTask(int interval_time) : PeriodicTask(interval_time) {}
void task() { os::run_periodic_checks(); }
void task() { os::run_periodic_checks(tty); }
static void engage();
static void disengage();
};

View File

@ -257,7 +257,7 @@ class os: AllStatic {
static jlong javaTimeNanos();
static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
static void javaTimeSystemUTC(jlong &seconds, jlong &nanos);
static void run_periodic_checks();
static void run_periodic_checks(outputStream* st);
// Returns the elapsed time in seconds since the vm started.
static double elapsedTime();

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. 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.
*/
#include "precompiled.hpp"
#ifndef _WIN32
#include "runtime/os.hpp"
#include "utilities/ostream.hpp"
#include "unittest.hpp"
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <sys/ucontext.h>
#include <string.h>
extern "C" {
static void sig_handler(int sig, siginfo_t *info, ucontext_t *context) {
printf( " HANDLER (1) " );
}
}
class PosixSignalTest : public ::testing::Test {
public:
static void check_handlers() {
struct sigaction act, old_SIGFPE_act, old_SIGILL_act;
act.sa_handler = (void (*)(int))sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
ASSERT_NE(sigaction(SIGFPE, &act, &old_SIGFPE_act), -1) << "Setting SIGFPE handler failed: " << os::strerror(errno) << " (" << errno << ")";
ASSERT_NE(sigaction(SIGILL, &act, &old_SIGILL_act), -1) << "Setting SIGILL handler failed: " << os::strerror(errno) << " (" << errno << ")";
// Use local stringStream to capture output from run_periodic_checks() calls to
// print_signal_handlers().
stringStream st;
os::run_periodic_checks(&st);
char* res = (char *)st.base(); // res can't be const because some strstr()'s have non-const first args.
// Restore signal handlers.
ASSERT_NE(sigaction(SIGFPE, &act, &old_SIGFPE_act), -1) << "Restoring SIGFPE handler failed: " << os::strerror(errno) << " (" << errno << ")";
ASSERT_NE(sigaction(SIGILL, &act, &old_SIGILL_act), -1) << "Restoring SIGILL handler failed: " << os::strerror(errno) << " (" << errno << ")";
// Check that "Handler was modified" occurs exactly twice in the tty output.
char* modified = strstr(res, "Handler was modified!");
ASSERT_NE(modified, nullptr) << "No message found";
modified = strstr(modified + 1, "Handler was modified!");
ASSERT_NE(modified, nullptr) << "Only one message found";
ASSERT_EQ(strstr(modified + 1, "Handler was modified!"), nullptr) << "Too many messages found";
}
};
// This tests the fix for JDK-8285792.
TEST_OTHER_VM(PosixSignalTest, check_handlers) {
PosixSignalTest::check_handlers();
}
#endif

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. 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.
*/
/*
* @test TestPosixSig.java
* @bug 8285792
* @summary fix issues with signal handler modification checks
* @requires os.family != "windows"
* @library /test/lib
* @run driver TestPosixSig
*/
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
public class TestPosixSig {
// Check that a substring occurs exactly once.
public static boolean occursOnce(String source, String substring) {
int index = source.indexOf(substring);
if (index == -1) return false;
return (source.indexOf(substring, index + 1) == -1);
}
private static native void changeSigActionFor(int val);
public static void main(String[] args) throws Throwable {
// Get the library path property.
String libpath = System.getProperty("java.library.path");
if (args.length == 0) {
// Create a new java process for the TestPsig Java/JNI test
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
"-XX:+CheckJNICalls",
"-Djava.library.path=" + libpath + ":.",
"TestPosixSig", "dummy");
// Start the process and check the output
OutputAnalyzer output = new OutputAnalyzer(pb.start());
String outputString = output.getOutput();
if (!occursOnce(outputString, "SIGFPE: sig_handler in ") ||
!occursOnce(outputString, "SIGILL: sig_handler in ")) {
System.out.println("output: " + outputString);
throw new RuntimeException("Test failed, bad output.");
}
output.shouldHaveExitValue(0);
} else {
System.loadLibrary("TestPsig");
TestPosixSig.changeSigActionFor(8); // SIGFPE
TestPosixSig.changeSigActionFor(4); // SIGILL
Thread.sleep(600);
}
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. 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.
*/
#include <stdio.h>
#include <jni.h>
#include <signal.h>
#include <sys/ucontext.h>
#include <errno.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
void sig_handler(int sig, siginfo_t *info, ucontext_t *context) {
printf( " HANDLER (1) " );
}
JNIEXPORT void JNICALL Java_TestPosixSig_changeSigActionFor(JNIEnv *env, jclass klass, jint val) {
struct sigaction act;
act.sa_handler = (void (*)())sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
int retval = sigaction(val, &act, 0);
if (retval != 0) {
printf("ERROR: failed to set %d signal handler error=%s\n", val, strerror(errno));
}
}
#ifdef __cplusplus
}
#endif