# HG changeset patch # User gthornbr # Date 1447867972 28800 # Node ID 2cf348387c442a4dad5719fb3c025850ce630b48 # Parent 892795cc82fe63dacb16be9d43b566d269c82013 8141445: Use of Solaris/SPARC M7 libadimalloc.so can generate unknown signal in hs_err file Summary: Add libadimalloc.so SIGSEGV defines and a test to validate the correct message is printed in the hs_err file Reviewed-by: dcubed, dholmes diff -r 892795cc82fe -r 2cf348387c44 hotspot/make/test/JtregNative.gmk --- a/hotspot/make/test/JtregNative.gmk Tue Nov 17 15:14:29 2015 -0800 +++ b/hotspot/make/test/JtregNative.gmk Wed Nov 18 09:32:52 2015 -0800 @@ -48,6 +48,16 @@ $(HOTSPOT_TOPDIR)/test/runtime/SameObject \ # +# Add conditional directories here when needed. +ifeq ($(OPENJDK_TARGET_OS)-$(OPENJDK_TARGET_CPU_ARCH), solaris-sparc) +BUILD_HOTSPOT_JTREG_NATIVE_SRC += \ + $(HOTSPOT_TOPDIR)/test/runtime/libadimalloc.solaris.sparc +endif + +ifeq ($(TOOLCHAIN_TYPE), solstudio) + BUILD_HOTSPOT_JTREG_LIBRARIES_LDFLAGS_liboverflow := -lc +endif + BUILD_HOTSPOT_JTREG_OUTPUT_DIR := $(BUILD_OUTPUT)/support/test/hotspot/jtreg/native BUILD_HOTSPOT_JTREG_IMAGE_DIR := $(TEST_IMAGE_DIR)/hotspot/jtreg diff -r 892795cc82fe -r 2cf348387c44 hotspot/src/os/posix/vm/os_posix.cpp --- a/hotspot/src/os/posix/vm/os_posix.cpp Tue Nov 17 15:14:29 2015 -0800 +++ b/hotspot/src/os/posix/vm/os_posix.cpp Wed Nov 18 09:32:52 2015 -0800 @@ -837,6 +837,21 @@ #if defined(IA64) && !defined(AIX) { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" }, #endif +#if defined(__sparc) && defined(SOLARIS) +// define Solaris Sparc M7 ADI SEGV signals +#if !defined(SEGV_ACCADI) +#define SEGV_ACCADI 3 +#endif + { SIGSEGV, SEGV_ACCADI, "SEGV_ACCADI", "ADI not enabled for mapped object." }, +#if !defined(SEGV_ACCDERR) +#define SEGV_ACCDERR 4 +#endif + { SIGSEGV, SEGV_ACCDERR, "SEGV_ACCDERR", "ADI disrupting exception." }, +#if !defined(SEGV_ACCPERR) +#define SEGV_ACCPERR 5 +#endif + { SIGSEGV, SEGV_ACCPERR, "SEGV_ACCPERR", "ADI precise exception." }, +#endif // defined(__sparc) && defined(SOLARIS) { SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." }, { SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." }, { SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." }, diff -r 892795cc82fe -r 2cf348387c44 hotspot/test/runtime/libadimalloc.solaris.sparc/SEGVOverflow.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/libadimalloc.solaris.sparc/SEGVOverflow.java Wed Nov 18 09:32:52 2015 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2015, 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. + */ +public class SEGVOverflow { + + static { + System.loadLibrary("overflow"); + } + + native static String nativesegv(); + + public static void main(String[] args) { + String str = nativesegv(); + if (str == null) { + System.out.println("FAILED: malloc returned null"); + } else { + System.out.println(str); + } + } +} diff -r 892795cc82fe -r 2cf348387c44 hotspot/test/runtime/libadimalloc.solaris.sparc/Testlibadimalloc.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/libadimalloc.solaris.sparc/Testlibadimalloc.java Wed Nov 18 09:32:52 2015 -0800 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015, 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 Testlibadimalloc.java + * @bug 8141445 + * @summary make sure the Solaris Sparc M7 libadimalloc.so library generates SIGSEGV's on buffer overflow + * @requires (os.family == "solaris" & os.arch == "sparcv9") + * @library /testlibrary + * @build jdk.test.lib.* + * @compile SEGVOverflow.java + * @run driver Testlibadimalloc + */ + +import java.io.*; +import java.nio.file.*; +import java.util.*; +import jdk.test.lib.ProcessTools; + +public class Testlibadimalloc { + + // Expected return value when java program cores + static final int EXPECTED_RET_VAL = 6; + + public static void main(String[] args) throws Throwable { + + // See if the libadimalloc.so library exists + Path path = Paths.get("/usr/lib/64/libadimalloc.so"); + + // If the libadimalloc.so file does not exist, pass the test + if (!(Files.isRegularFile(path) || Files.isSymbolicLink(path))) { + System.out.println("Test skipped; libadimalloc.so does not exist"); + return; + } + + // Get the JDK, library and class path properties + String libpath = System.getProperty("java.library.path"); + + // Create a new java process for the SEGVOverflow Java/JNI test + ProcessBuilder builder = ProcessTools.createJavaProcessBuilder( + "-Djava.library.path=" + libpath + ":.", "SEGVOverflow"); + + // Add the LD_PRELOAD_64 value to the environment + Map env = builder.environment(); + env.put("LD_PRELOAD_64", "libadimalloc.so"); + + // Start the process, get the pid and then wait for the test to finish + Process process = builder.start(); + long pid = process.getPid(); + int retval = process.waitFor(); + + // make sure the SEGVOverflow test crashed + boolean found = false; + if (retval == EXPECTED_RET_VAL) { + String filename = "hs_err_pid" + pid + ".log"; + Path filepath = Paths.get(filename); + // check to see if hs_err_file exists + if (Files.isRegularFile(filepath)) { + // see if the crash was due to a SEGV_ACCPERR signal + File hs_err_file = new File(filename); + Scanner scanner = new Scanner(hs_err_file); + while (!found && scanner.hasNextLine()) { + String nextline = scanner.nextLine(); + if (nextline.contains("SEGV_ACCPERR")) { + found = true; + } + } + } else { + System.out.println("Test failed; hs_err_file does not exist: " + + filepath); + } + } else { + System.out.println("Test failed; java test program did not " + + "return expected error: expected = " + + EXPECTED_RET_VAL + ", retval = " + retval); + } + // If SEGV_ACCPERR was not found in the hs_err file fail the test + if (!found) { + System.out.println("FAIL: SEGV_ACCPERR not found"); + throw new RuntimeException("FAIL: SEGV_ACCPERR not found"); + } + } +} diff -r 892795cc82fe -r 2cf348387c44 hotspot/test/runtime/libadimalloc.solaris.sparc/liboverflow.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/libadimalloc.solaris.sparc/liboverflow.c Wed Nov 18 09:32:52 2015 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015, 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 +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT jstring JNICALL Java_SEGVOverflow_nativesegv(JNIEnv *env, jobject obj) { + char *buffer1; + char *buffer2; + char *buffer3; + char ch; + + jstring ret = NULL; + + // sleep for a bit to let the libadimalloc library initialize + sleep(5); + + // allocate three buffers + buffer1 = (char *)malloc(64); + buffer2 = (char *)malloc(64); + buffer3 = (char *)malloc(64); + if ((buffer1 == NULL) || (buffer2 == NULL) || (buffer3 == NULL)) { + // this return will result in a test failure + return ret; + } + + // Read past the end of each buffer multiple times to increase the probability + // that an ADI version mismatch occurs so an ADI fault is triggered. + ch = buffer1[70]; + ch = buffer2[70]; + ch = buffer3[70]; + ch = buffer1[140]; + ch = buffer2[140]; + ch = buffer3[140]; + + // create a failed test return value because this test should have cored + buffer1 = "TEST FAILED, a read past the end of a buffer succeeded."; + ret = (*env)->NewStringUTF(env, buffer1); + + return ret; +} + +#ifdef __cplusplus +} +#endif