Categories: OpenJDK

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 . . .

Article info



Leave a Reply

Your email address will not be published. Required fields are marked *