Native Stack Printing on Windows AArch64
Another test failure I investigated last month was in the runtime/jni/nativeStack/TestNativeStack.java test. This is the setup I used to run the test in my MSYS environment.
export JDKARCH=aarch64
export DEBUGLEVEL=slowdebug
export JDKSRCPATH=/c/java/forks/openjdk/jdk
export JDKBUILDPATH="${JDKSRCPATH}/build/windows-${JDKARCH}-server-${DEBUGLEVEL}"
export JDKTOTEST="${JDKBUILDPATH}/images/jdk"
export JTREGNATIVEPATH1="${JDKBUILDPATH}/support/test/hotspot/jtreg/native/lib"
export JTREGNATIVEPATH2="${JDKBUILDPATH}/support/test/jdk/jtreg/native/lib"
export JTREGNATIVEPATH3="${JDKBUILDPATH}/support/test/lib/native/lib"
export GTESTPATH="${JDKBUILDPATH}/images/test/hotspot/gtest/server"
export JTREGBINPATH=/c/java/binaries/jtreg/jtreg-8+2
export TESTTORUN=test/hotspot/jtreg/runtime/jni/nativeStack/TestNativeStack.java
./run-jtreg-test.sh $JDKSRCPATH $JDKTOTEST $JTREGBINPATH/lib/jtreg.jar $TESTTORUN -nativepath:$JTREGNATIVEPATH1
The test fails with the output below. The key line is Native frames: <unavailable>.
STDOUT:
Command line: [C:\java\forks\openjdk\jdk\build\windows-aarch64-server-slowdebug\images\jdk\bin\java.exe -cp C:\java\forks\openjdk\jdk\JTwork\classes\runtime\jni\nativeStack\TestNativeStack.d;C:\java\forks\openjdk\jdk\test\hotspot\jtreg\runtime\jni\nativeStack;C:\java\forks\openjdk\jdk\JTwork\classes\test\lib;C:\java\binaries\jtreg\jtreg-7.5.2\lib\javatest.jar;C:\java\binaries\jtreg\jtreg-7.5.2\lib\jtreg.jar;C:\java\binaries\jtreg\jtreg-7.5.2\lib\junit-platform-console-standalone-1.11.0.jar;C:\java\binaries\jtreg\jtreg-7.5.2\lib\testng-7.3.0.jar;C:\java\binaries\jtreg\jtreg-7.5.2\lib\guice-5.1.0.jar;C:\java\binaries\jtreg\jtreg-7.5.2\lib\jcommander-1.82.jar -Xmx512m -Xcheck:jni -Djava.library.path=C:\java\forks\openjdk\jdk\build\windows-aarch64-server-slowdebug\support\test\hotspot\jtreg\native\lib TestNativeStack$Main ]
[2025-09-04T15:54:18.312130500Z] Gathering output for process 22380
[2025-09-04T15:54:18.753851700Z] Waiting for completion for process 22380
[2025-09-04T15:54:18.756861300Z] Waiting for completion finished for process 22380
Output and diagnostic info for process 22380 was saved into 'pid-22380-output.log'
STDERR:
stdout: [Triggering a JNI warning
WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod
Native frames: <unavailable>
];
stderr: [WARNING: A restricted method in java.lang.System has been called
WARNING: java.lang.System::loadLibrary has been called by TestNativeStack in an unnamed module (file:/C:/java/forks/openjdk/jdk/JTwork/classes/runtime/jni/nativeStack/TestNativeStack.d/)
WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module
WARNING: Restricted methods will be blocked in a future release unless native access is enabled
]
exitValue = -2147483645
java.lang.RuntimeException: Expected to get exit value of [0], exit value is: [-2147483645]
at jdk.test.lib.process.OutputAnalyzer.shouldHaveExitValue(OutputAnalyzer.java:522)
at TestNativeStack.main(TestNativeStack.java:57)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:565)
at com.sun.javatest.regtest.agent.MainActionHelper$AgentVMRunnable.run(MainActionHelper.java:335)
at java.base/java.lang.Thread.run(Thread.java:1474)
I added a DebugBreak call to the line outputing that message to see how we got there:
KernelBase.dll!...DebugBreak() Line 2582 C++
jvm.dll!NativeStackPrinter::print_stack_from_frame(outputStream * st, frame fr, char * buf, int buf_size, bool print_source_info, int max_frames) Line 80 C++
jvm.dll!NativeStackPrinter::print_stack_from_frame(outputStream * st, char * buf, int buf_size, bool print_source_info, int max_frames) Line 104 C++
jvm.dll!NativeStackPrinter::print_stack(outputStream * st, char * buf, int buf_size, unsigned char * & lastpc, bool print_source_info, int max_frames) Line 40 C++
jvm.dll!JavaThread::print_jni_stack() Line 1775 C++
jvm.dll!check_pending_exception(JavaThread * thr) Line 192 C++
jvm.dll!functionEnter(JavaThread * thr) Line 218 C++
jvm.dll!checked_jni_CallStaticObjectMethod(JNIEnv_ * env, _jclass * clazz, _jmethodID * methodID, ...) Line 1321 C++
nativeStack.dll!generateWarning(const JNINativeInterface_ * * env) Line 66 C
nativeStack.dll!thread_start(void * unused) Line 92 C
ucrtbase.dll!00007ffb0970b028() Unknown
kernel32.dll!00007ffb0bbd8740() Unknown
ntdll.dll!RtlUserThreadStart(long(*)(void *) StartAddress, void * Argument) Line 1184 C
The failure path is as follows. HAVE_PLATFORM_PRINT_NATIVE_STACK is not defined on Windows AArch64. Consequently, Windows AArch64 uses the implementation of os::platform_print_native_stack that simply returns false. This results in NativeStackPrinter::print_stack having to call NativeStackPrinter::print_stack_from_frame instead. However, the context is null. As a result, the frame used for printing the stack is obtained from os::current_frame(), which returns an empty frame. The frame’s pc() method returns nullptr and the “Native frames: <unavailable>” message is printed.
The fix for this issue is to define the os::platform_print_native_stack method for Windows AArch64 and share the implementation of the Windows x64 os::win32::platform_print_native_stack method with Windows AArch64. I opened [JDK-8369322] Implement native stack printing for Windows-AArch64 – Java Bug System and the associated PR 8369322: Implement native stack printing for Windows-AArch64 by swesonga · Pull Request #27680 · openjdk/jdk fixing this failure. With this change, the native frames are now printed as shown below:
Triggering a JNI warning WARNING: A restricted method in java.lang.System has been called WARNING: java.lang.System::loadLibrary has been called by TestNativeStack in an unnamed module (file:/C:/java/forks/openjdk/jdk/JTwork/classes/runtime/jni/nativeStack/TestNativeStack.d/) WARNING: Use --enable-native-access=ALL-UNNAMED to avoid a warning for callers in this module WARNING: Restricted methods will be blocked in a future release unless native access is enabled Native thread is running and attaching as daemon ... About to trigger JNI Warning WARNING in native method: JNI call made without checking exceptions when required to from CallStaticObjectMethod Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [jvm.dll+0x10e8aa8] os::win32::platform_print_native_stack+0x58 (os_windows_aarch64.cpp:143) V [jvm.dll+0x10598ac] os::platform_print_native_stack+0x34 (os_windows_aarch64.inline.hpp:38) V [jvm.dll+0x1059588] NativeStackPrinter::print_stack+0x48 (nativeStackPrinter.cpp:35) V [jvm.dll+0xba74a0] JavaThread::print_jni_stack+0x120 (javaThread.cpp:1775) V [jvm.dll+0xcb0e84] check_pending_exception+0x84 (jniCheck.cpp:192) V [jvm.dll+0xcb0f24] functionEnter+0x4c (jniCheck.cpp:218) V [jvm.dll+0xcbbb70] checked_jni_CallStaticObjectMethod+0xf0 (jniCheck.cpp:1321) C [nativeStack.dll+0x1264] generateWarning+0x13c (libnativeStack.c:66) C [nativeStack.dll+0x1364] thread_start+0xa4 (libnativeStack.c:92) C [ucrtbase.dll+0x2b028] (no source info available) C [KERNEL32.DLL+0x8740] (no source info available) C [ntdll.dll+0xd47a4] (no source info available) Native thread terminating C:\java\forks\openjdk\jdk\build\windows-aarch64-server-slowdebug\images\jdk\bin\java.exe (process 30308) exited with code 0 (0x0). To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops. Press any key to close this window . . .
Leave a Reply