Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8292674

ReportJNIFatalError should print all java frames

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P3 P3
    • 21
    • 19
    • hotspot
    • b02

      Peter Hofer reported the following output with -Xcheck:jni when using a JVM TI agent:

      FATAL ERROR in native method: Wrong object class or methodID passed to JNI call
              at jdk.internal.vm.Continuation.run(java.base/Continuation.java:260)
              at java.lang.VirtualThread.runContinuation(java.base/VirtualThread.java:213)
              at java.lang.VirtualThread$$Lambda$44/0x00000008000a2490.run(java.base/Unknown Source)
              at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(java.base/ForkJoinTask.java:1423)
              at java.util.concurrent.ForkJoinTask.doExec(java.base/ForkJoinTask.java:387)
              at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(java.base/ForkJoinPool.java:1311)
              at java.util.concurrent.ForkJoinPool.scan(java.base/ForkJoinPool.java:1840)
              at java.util.concurrent.ForkJoinPool.runWorker(java.base/ForkJoinPool.java:1806)
              at java.util.concurrent.ForkJoinWorkerThread.run(java.base/ForkJoinWorkerThread.java:177)


      The issue here is not the crash or the reasons for it, but that the stack trace printed by ReportJNIFatalError is not very useful when there are virtual thread frames on the stack and the thread identity has temporarily switched to the carrier thread. The thread stack printing supports just the carrier stack frames or just the virtual thread stack frames but the scenario where the thread identity has to temporarily switch to the carrier is complicated and we should except a stack trace like this:

      at java.lang.Class.isArray()
      at java.lang.invoke.MethodHandles$Lookup.isClassAccessible
      at java.lang.invoke.MethodHandles$Lookup.checkSymbolicClass
      at java.lang.invoke.MethodHandles$Lookup.resolveOrFail
      at java.lang.invoke.MethodHandles$Lookup.findVarHandle
      at java.lang.invoke.MethodHandles$Lookup.findVarHandle
      at java.util.concurrent.FutureTask.<clinit>
      at java.util.concurrent.ScheduledThreadPoolExecutor.schedule
      at java.lang.VirtualThread.scheduleUnpark. <=== thread identity changes to the carrier thread here
      at java.lang.VirtualThread.parkNanos
      at java.lang.VirtualThread.doSleepNanos
      at java.lang.VirtualThread.sleepNanos
      at java.lang.Thread.sleep
      at gameoflife.GameOfLife.sleep
      at gameoflife.GameOfLife.run
      at jdk.internal.vm.Continuation.enterSpecial
      at jdk.internal.vm.Continuation.run(java.base/Continuation.java:260)
      at java.lang.VirtualThread.runContinuation(java.base/VirtualThread.java:213)
      at java.lang.VirtualThread$$Lambda$44/0x00000008000a2490.run(java.base/Unknown Source)
      at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(java.base/ForkJoinTask.java:1423)
      at java.util.concurrent.ForkJoinTask.doExec(java.base/ForkJoinTask.java:387)
      at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(java.base/ForkJoinPool.java:1311)
      at java.util.concurrent.ForkJoinPool.scan(java.base/ForkJoinPool.java:1840)
      at java.util.concurrent.ForkJoinPool.runWorker(java.base/ForkJoinPool.java:1806)
      at java.util.concurrent.ForkJoinWorkerThread.run(java.base/ForkJoinWorkerThread.java:177)

      For JNI fatal errors then I think the simplest is to print all stack frames (there are flags for that).

            dholmes David Holmes
            alanb Alan Bateman
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: