diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk index a08210fb211..d4006d0e24f 100644 --- a/make/test/JtregNativeHotspot.gmk +++ b/make/test/JtregNativeHotspot.gmk @@ -860,8 +860,10 @@ 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 libnativeStack.c exeGetCreatedJavaVMs.c + BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libTestPsig.c exeGetCreatedJavaVMs.c BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libatExit := jvm.lib + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack := jvm.lib + BUILD_HOTSPOT_JTREG_LIBRARIES_COPY_DEBUG_SYMBOLS_libnativeStack := true BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exedaemonDestroy := jvm.lib else BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exedaemonDestroy := -ljvm diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp index b469c1a6790..0597d06d58c 100644 --- a/src/hotspot/share/runtime/javaThread.cpp +++ b/src/hotspot/share/runtime/javaThread.cpp @@ -1710,9 +1710,15 @@ void JavaThread::print_jni_stack() { tty->print_cr("Unable to print native stack - out of memory"); return; } - frame f = os::current_frame(); - VMError::print_native_stack(tty, f, this, true /*print_source_info */, - -1 /* max stack */, buf, O_BUFLEN); + address lastpc = nullptr; + if (os::platform_print_native_stack(tty, nullptr, buf, O_BUFLEN, lastpc)) { + // We have printed the native stack in platform-specific code, + // so nothing else to do in this case. + } else { + frame f = os::current_frame(); + VMError::print_native_stack(tty, f, this, true /*print_source_info */, + -1 /* max stack */, buf, O_BUFLEN); + } } else { print_active_stack_on(tty); } diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 3b9cf59b954..7f9809dabd9 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -474,6 +474,8 @@ void VMError::print_native_stack(outputStream* st, frame fr, Thread* t, bool pri st->print_cr("......"); } + } else { + st->print_cr("Native frames: "); } } diff --git a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java index 81ce1da7846..a7b8d945eec 100644 --- a/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java +++ b/test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java @@ -24,11 +24,10 @@ /* * @test * @bug 8295974 - * @requires os.family != "windows" & os.arch != "arm" + * @requires os.arch != "arm" * @library /test/lib * @summary Generate a JNI Fatal error, or a warning, in a launched VM and check * the native stack is present as expected. - * @comment The native code only supports POSIX so no windows testing * @run driver TestNativeStack */ diff --git a/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c b/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c index 1da49f586d3..2b75f29aa83 100644 --- a/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c +++ b/test/hotspot/jtreg/runtime/jni/nativeStack/libnativeStack.c @@ -24,7 +24,15 @@ #include #include +#ifdef _WIN32 +#include +#include +typedef unsigned int THREAD_ID; +#else #include +typedef pthread_t THREAD_ID; +#endif + #include #include "jni.h" @@ -63,7 +71,12 @@ void generateError(JNIEnv *env) { (*env)->FatalError(env, "Fatal error generated in test code"); } -static void * thread_start(void* unused) { +#ifdef _WIN32 +unsigned __stdcall +#else +void * +#endif +thread_start(void* unused) { JNIEnv *env; int res; @@ -94,13 +107,17 @@ static void * thread_start(void* unused) { printf("Native thread terminating\n"); +#ifndef _WIN32 return NULL; +#else + return 0; +#endif } JNIEXPORT void JNICALL Java_TestNativeStack_triggerJNIStackTrace (JNIEnv *env, jclass cls, jboolean warn) { - pthread_t thread; + THREAD_ID thread; int res = (*env)->GetJavaVM(env, &jvm); if (res != JNI_OK) { fprintf(stderr, "Test ERROR. Can't extract JavaVM: %d\n", res); @@ -109,6 +126,21 @@ Java_TestNativeStack_triggerJNIStackTrace warning = warn; +#ifdef _WIN32 + HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, thread_start, + NULL, 0, &thread); + if (hThread == 0) { + fprintf(stderr, "TEST ERROR: _beginthreadex failed: %s\n", strerror(errno)); + exit(1); + } + if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0) { + fprintf(stderr, "TEST ERROR: WaitForSingleObject failed: %d\n", GetLastError()); + exit(1); + } + CloseHandle(hThread); + +#else + pthread_attr_t attr; pthread_attr_init(&attr); size_t stack_size = 0x100000; @@ -125,4 +157,5 @@ Java_TestNativeStack_triggerJNIStackTrace fprintf(stderr, "TEST ERROR: pthread_join failed: %s (%d)\n", strerror(res), res); exit(1); } +#endif }