javafxports / openjdk-jfx

The openjfx repo has moved to:
https://github.com/openjdk/jfx
GNU General Public License v2.0
1.01k stars 145 forks source link

Java 10 + Monocle = JVM Crash (TestFX test suite) #66

Closed brcolow closed 5 years ago

brcolow commented 6 years ago

After adding a Java 10 build to our (TestFX) appveyor configuration, I am seeing a crash (every time at the same place):

https://ci.appveyor.com/project/testfx/testfx/build/master%201046/job/3pl22fioi0ut9juc#L492

It is triggered by this test.

I believe it is crashing in modules/javafx.graphics/src/main/native-font/directwrite.cpp in the JNIEXPORT jlong JNICALL OS_NATIVE(CreateBitmap) method. This is somewhat strange because that file hasn't been modified since the javafx-font and javafx-font-native modules were open sourced (as RT-31139) so figuring out why this would precipitate a crash now in Java 10 is probably non-trivial.

Here is the crash dump:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007fffe2c74e80, pid=3000, tid=600
#
# JRE version: Java(TM) SE Runtime Environment (10.0+46) (build 10+46)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10+46, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [javafx_font.dll+0x4e80]
#
# Core dump will be written. Default location: C:\projects\testfx\subprojects\testfx-core\hs_err_pid3000.mdmp
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
---------------  S U M M A R Y ------------
Command Line: -Dorg.gradle.native=false -Dfile.encoding=windows-1252 -Duser.country=US -Duser.language=en -Duser.variant -ea -Djava.awt.headless=true -Dtestfx.robot=glass -Dtestfx.headless=true -Dprism.order=sw -Dprism.text=t2k worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 1'
Host: Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz, 2 cores, 2G,  Windows Server 2012 R2 , 64 bit Build 9600 (6.3.9600.17415)
Time: Fri Apr 13 02:07:48 2018 Coordinated Universal Time elapsed time: 5 seconds (0d 0h 0m 5s)
---------------  T H R E A D  ---------------
Current thread (0x000000405f666800):  JavaThread "QuantumRenderer-0" daemon [_thread_in_native, id=600, stack(0x0000004061600000,0x0000004061700000)]
Stack: [0x0000004061600000,0x0000004061700000],  sp=0x00000040616fc9c0,  free space=1010k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [javafx_font.dll+0x4e80]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  com.sun.javafx.font.directwrite.OS.CreateBitmap(JIIII)J+0 javafx.graphics@10
j  com.sun.javafx.font.directwrite.IWICImagingFactory.CreateBitmap(IIII)Lcom/sun/javafx/font/directwrite/IWICBitmap;+9 javafx.graphics@10
j  com.sun.javafx.font.directwrite.DWGlyph.createBitmap(II)Lcom/sun/javafx/font/directwrite/IWICBitmap;+10 javafx.graphics@10
j  com.sun.javafx.font.directwrite.DWGlyph.getCachedBitmap()Lcom/sun/javafx/font/directwrite/IWICBitmap;+13 javafx.graphics@10
j  com.sun.javafx.font.directwrite.DWGlyph.getD2DMask(FFZ)[B+117 javafx.graphics@10
j  com.sun.javafx.font.directwrite.DWGlyph.getPixelData(I)[B+94 javafx.graphics@10
j  com.sun.prism.sw.SWGraphics.drawGlyph(Lcom/sun/javafx/font/FontStrike;Lcom/sun/javafx/scene/text/GlyphList;ILcom/sun/javafx/geom/transform/BaseTransform;ZFF)V+85 javafx.graphics@10
j  com.sun.prism.sw.SWGraphics.drawString(Lcom/sun/javafx/scene/text/GlyphList;Lcom/sun/javafx/font/FontStrike;FFLcom/sun/prism/paint/Color;II)V+352 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGText.renderText(Lcom/sun/prism/Graphics;Lcom/sun/javafx/font/FontStrike;Lcom/sun/javafx/geom/BaseBounds;Lcom/sun/prism/paint/Color;I)V+198 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGText.renderContent2D(Lcom/sun/prism/Graphics;Z)V+238 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGShape.renderContent(Lcom/sun/prism/Graphics;)V+454 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+330 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGGroup.renderContent(Lcom/sun/prism/Graphics;)V+151 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGRegion.renderContent(Lcom/sun/prism/Graphics;)V+111 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+330 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGGroup.renderContent(Lcom/sun/prism/Graphics;)V+151 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+330 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGGroup.renderContent(Lcom/sun/prism/Graphics;)V+151 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGRegion.renderContent(Lcom/sun/prism/Graphics;)V+111 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.renderForClip(Lcom/sun/prism/Graphics;)V+17 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.renderRectClip(Lcom/sun/prism/Graphics;Lcom/sun/javafx/sg/prism/NGRectangle;)V+106 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.renderClip(Lcom/sun/prism/Graphics;)V+83 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+285 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGGroup.renderContent(Lcom/sun/prism/Graphics;)V+151 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGRegion.renderContent(Lcom/sun/prism/Graphics;)V+111 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+330 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGGroup.renderContent(Lcom/sun/prism/Graphics;)V+151 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGRegion.renderContent(Lcom/sun/prism/Graphics;)V+111 javafx.graphics@10
j  com.sun.javafx.sg.prism.NodeEffectInput.getImageDataForBoundedNode(Lcom/sun/scenario/effect/FilterContext;Lcom/sun/javafx/sg/prism/NGNode;Lcom/sun/javafx/sg/prism/NodeEffectInput$RenderType;Lcom/sun/javafx/geom/transform/BaseTransform;Lcom/sun/javafx/geom/Rectangle;)Lcom/sun/scenario/effect/ImageData;+103 javafx.graphics@10
j  com.sun.javafx.sg.prism.NodeEffectInput.filter(Lcom/sun/scenario/effect/FilterContext;Lcom/sun/javafx/geom/transform/BaseTransform;Lcom/sun/javafx/geom/Rectangle;Ljava/lang/Object;Lcom/sun/scenario/effect/Effect;)Lcom/sun/scenario/effect/ImageData;+163 javafx.graphics@10
j  com.sun.scenario.effect.FilterEffect.filter(Lcom/sun/scenario/effect/FilterContext;Lcom/sun/javafx/geom/transform/BaseTransform;Lcom/sun/javafx/geom/Rectangle;Ljava/lang/Object;Lcom/sun/scenario/effect/Effect;)Lcom/sun/scenario/effect/ImageData;+111 javafx.graphics@10
j  com.sun.scenario.effect.Offset.filter(Lcom/sun/scenario/effect/FilterContext;Lcom/sun/javafx/geom/transform/BaseTransform;Lcom/sun/javafx/geom/Rectangle;Ljava/lang/Object;Lcom/sun/scenario/effect/Effect;)Lcom/sun/scenario/effect/ImageData;+35 javafx.graphics@10
j  com.sun.scenario.effect.Merge.filter(Lcom/sun/scenario/effect/FilterContext;Lcom/sun/javafx/geom/transform/BaseTransform;Lcom/sun/javafx/geom/Rectangle;Ljava/lang/Object;Lcom/sun/scenario/effect/Effect;)Lcom/sun/scenario/effect/ImageData;+27 javafx.graphics@10
j  com.sun.scenario.effect.DelegateEffect.filter(Lcom/sun/scenario/effect/FilterContext;Lcom/sun/javafx/geom/transform/BaseTransform;Lcom/sun/javafx/geom/Rectangle;Ljava/lang/Object;Lcom/sun/scenario/effect/Effect;)Lcom/sun/scenario/effect/ImageData;+11 javafx.graphics@10
j  com.sun.scenario.effect.impl.prism.PrEffectHelper.render(Lcom/sun/scenario/effect/Effect;Lcom/sun/prism/Graphics;FFLcom/sun/scenario/effect/Effect;)V+511 javafx.graphics@10
j  com.sun.javafx.sg.prism.EffectFilter.render(Lcom/sun/prism/Graphics;)V+13 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.renderEffect(Lcom/sun/prism/Graphics;)V+5 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+319 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGGroup.renderContent(Lcom/sun/prism/Graphics;)V+151 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGRegion.renderContent(Lcom/sun/prism/Graphics;)V+111 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+330 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGGroup.renderContent(Lcom/sun/prism/Graphics;)V+151 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGRegion.renderContent(Lcom/sun/prism/Graphics;)V+111 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.doRender(Lcom/sun/prism/Graphics;)V+330 javafx.graphics@10
j  com.sun.javafx.sg.prism.NGNode.render(Lcom/sun/prism/Graphics;)V+34 javafx.graphics@10
j  com.sun.javafx.tk.quantum.ViewPainter.doPaint(Lcom/sun/prism/Graphics;Lcom/sun/javafx/sg/prism/NodePath;)V+201 javafx.graphics@10
j  com.sun.javafx.tk.quantum.ViewPainter.paintImpl(Lcom/sun/prism/Graphics;)V+961 javafx.graphics@10
j  com.sun.javafx.tk.quantum.UploadingPainter.run()V+741 javafx.graphics@10
j  java.util.concurrent.Executors$RunnableAdapter.call()Ljava/lang/Object;+4 java.base@10
j  java.util.concurrent.FutureTask.runAndReset()Z+44 java.base@10
j  com.sun.javafx.tk.RenderJob.run()V+1 javafx.graphics@10
j  java.util.concurrent.ThreadPoolExecutor.runWorker(Ljava/util/concurrent/ThreadPoolExecutor$Worker;)V+92 java.base@10
j  java.util.concurrent.ThreadPoolExecutor$Worker.run()V+5 java.base@10
j  com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run()V+8 javafx.graphics@10
j  java.lang.Thread.run()V+11 java.base@10
v  ~StubRoutines::call_stub
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x00007ffff6ca6878
Register to memory mapping:
RIP=0x00007fffe2c74e80 javafx_font.dll
RAX=0x0000000000000001 is an unknown value
RBX=0x0000000000000000 is an unknown value
RCX=0x000000405ec5a2f0 is an unknown value
RDX=0x0000000000000100 is an unknown value
RSP=0x00000040616fc9c0 is pointing into the stack for thread: 0x000000405f666800
RBP=0x00000040616fca10 is pointing into the stack for thread: 0x000000405f666800
RSI=0x0000000000000000 is an unknown value
RDI=0x0000000000000100 is an unknown value
R8 =0x0000000000000100 is an unknown value
R9 =0x00000040616fc9f8 is pointing into the stack for thread: 0x000000405f666800
R10=0x00007ffff6ca67f0 is an unknown value
R11=0x000000405ec5a2f0 is an unknown value
R12=0x0000000000000000 is an unknown value
R13={method} {0x0000004061c9bab8} 'CreateBitmap' '(JIIII)J' in 'com/sun/javafx/font/directwrite/OS'
R14=0x00000040616fcb00 is pointing into the stack for thread: 0x000000405f666800
R15=0x000000405f666800 is a thread
Registers:
RAX=0x0000000000000001, RBX=0x0000000000000000, RCX=0x000000405ec5a2f0, RDX=0x0000000000000100
RSP=0x00000040616fc9c0, RBP=0x00000040616fca10, RSI=0x0000000000000000, RDI=0x0000000000000100
R8 =0x0000000000000100, R9 =0x00000040616fc9f8, R10=0x00007ffff6ca67f0, R11=0x000000405ec5a2f0
R12=0x0000000000000000, R13=0x0000004061c9bab0, R14=0x00000040616fcb00, R15=0x000000405f666800
RIP=0x00007fffe2c74e80, EFLAGS=0x0000000000010206
Top of Stack: (sp=0x00000040616fc9c0)
0x00000040616fc9c0:   000000405e7e6d20 00000000000003d8
0x00000040616fc9d0:   0000004061c9bab0 000000405f666800
0x00000040616fc9e0:   0000004000000001 00000040616fc9f0
0x00000040616fc9f0:   0000000000000000 4bfe4e036fddc324
0x00000040616fca00:   10c98d76773d85b1 00005ea8b322f10a
0x00000040616fca10:   00000040616fcab8 000000404a33f317
0x00000040616fca20:   0000004061c9bab0 000000404a339c10
0x00000040616fca30:   000000404a339c10 000000404a33effc
0x00000040616fca40:   0000004000000100 0000004000000008
0x00000040616fca50:   0000000000000001 0000000000000000
0x00000040616fca60:   000000404a339c10 000000404a33efb6
0x00000040616fca70:   00000040616fca70 0000004061c9bab0
0x00000040616fca80:   00000040616fcb00 0000004061c9c370
0x00000040616fca90:   0000000000000000 00000000decf15a0
0x00000040616fcaa0:   0000004061c9bab0 0000000000000000
0x00000040616fcab0:   00000040616fcad8 00000040616fcb50 
Instructions: (pc=0x00007fffe2c74e80)
0x00007fffe2c74e60:   4d 8b 10 48 8d 45 e0 44 8b 45 30 4c 8d 4d e8 48
0x00007fffe2c74e70:   89 44 24 28 8b d7 8b 45 40 49 8b cb 89 44 24 20
0x00007fffe2c74e80:   41 ff 92 88 00 00 00 85 c0 48 0f 49 5d e0 48 8b
0x00007fffe2c74e90:   c3 48 8b 4d f8 48 33 cc e8 13 3f 00 00 48 8b 5c 
---------------  P R O C E S S  ---------------
Threads class SMR info:
_java_thread_list=0x00000040607b5a00, length=21, elements={
0x000000403ef83800, 0x000000403f070000, 0x000000403f074800, 0x000000405dd72000,
0x000000405ddb9000, 0x000000405ddbb000, 0x000000405de17000, 0x000000405de18800,
0x000000405e764800, 0x000000405e76d000, 0x000000405f134000, 0x000000405f14b000,
0x000000405f14d800, 0x000000405f19f800, 0x000000405f16f800, 0x000000405f666800,
0x000000405f64e800, 0x000000405f650800, 0x00000040607c1000, 0x00000040607be000,
0x00000040607c2000
}
Java Threads: ( => current thread )
  0x000000403ef83800 JavaThread "main" [_thread_blocked, id=1604, stack(0x000000403ee80000,0x000000403ef80000)]
  0x000000403f070000 JavaThread "Reference Handler" daemon [_thread_blocked, id=2896, stack(0x000000405df70000,0x000000405e070000)]
  0x000000403f074800 JavaThread "Finalizer" daemon [_thread_blocked, id=2236, stack(0x000000405e070000,0x000000405e170000)]
  0x000000405dd72000 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=2244, stack(0x000000405e250000,0x000000405e350000)]
  0x000000405ddb9000 JavaThread "Attach Listener" daemon [_thread_blocked, id=2400, stack(0x000000405e350000,0x000000405e450000)]
  0x000000405ddbb000 JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=2888, stack(0x000000405e450000,0x000000405e550000)]
  0x000000405de17000 JavaThread "C1 CompilerThread1" daemon [_thread_blocked, id=2460, stack(0x000000405e550000,0x000000405e650000)]
  0x000000405de18800 JavaThread "Sweeper thread" daemon [_thread_blocked, id=684, stack(0x000000405e650000,0x000000405e750000)]
  0x000000405e764800 JavaThread "Service Thread" daemon [_thread_blocked, id=1912, stack(0x000000405eb50000,0x000000405ec50000)]
  0x000000405e76d000 JavaThread "Common-Cleaner" daemon [_thread_blocked, id=1304, stack(0x000000405ed50000,0x000000405ee50000)]
  0x000000405f134000 JavaThread "Test worker" [_thread_blocked, id=1300, stack(0x000000405fa50000,0x000000405fb50000)]
  0x000000405f14b000 JavaThread "/127.0.0.1:1119 to /127.0.0.1:1118 workers Thread 2" [_thread_blocked, id=1980, stack(0x000000405fe30000,0x000000405ff30000)]
  0x000000405f14d800 JavaThread "/127.0.0.1:1119 to /127.0.0.1:1118 workers Thread 3" [_thread_in_native, id=1452, stack(0x000000405ff30000,0x0000004060030000)]
  0x000000405f19f800 JavaThread "testfx-async-pool-thread-1" daemon [_thread_blocked, id=1872, stack(0x0000004060230000,0x0000004060330000)]
  0x000000405f16f800 JavaThread "JavaFX-Launcher" daemon [_thread_blocked, id=2008, stack(0x0000004060330000,0x0000004060430000)]
=>0x000000405f666800 JavaThread "QuantumRenderer-0" daemon [_thread_in_native, id=600, stack(0x0000004061600000,0x0000004061700000)]
  0x000000405f64e800 JavaThread "JavaFX Application Thread" daemon [_thread_blocked, id=1468, stack(0x0000004061700000,0x0000004061800000)]
  0x000000405f650800 JavaThread "Timer-0" daemon [_thread_blocked, id=2496, stack(0x0000004061800000,0x0000004061900000)]
  0x00000040607c1000 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=1368, stack(0x0000004061b00000,0x0000004061c00000)]
  0x00000040607be000 JavaThread "Prism Font Disposer" daemon [_thread_blocked, id=2752, stack(0x0000004063190000,0x0000004063290000)]
  0x00000040607c2000 JavaThread "Cleaner-0" daemon [_thread_blocked, id=1240, stack(0x0000004063a90000,0x0000004063b90000)]
Other Threads:
  0x000000403f068800 VMThread "VM Thread" [stack: 0x000000405de70000,0x000000405df70000] [id=2172]
  0x000000405e76d800 WatcherThread [stack: 0x000000405ee50000,0x000000405ef50000] [id=1032]
  0x000000403ef9e000 GCTaskThread "GC Thread#0" [stack: 0x0000004059510000,0x0000004059610000] [id=1036]
  0x000000403ef9f800 GCTaskThread "GC Thread#1" [stack: 0x0000004059610000,0x0000004059710000] [id=1296]
  0x000000403efc1000 ConcurrentGCThread "G1 Main Marker" [stack: 0x000000405ad40000,0x000000405ae40000] [id=1088]
  0x000000403efc4800 ConcurrentGCThread "G1 Conc#0" [stack: 0x000000405ae40000,0x000000405af40000] [id=1632]
  0x000000403eff1800 ConcurrentGCThread "G1 Refine#0" [stack: 0x000000405d170000,0x000000405d270000] [id=3020]
  0x000000403eff5800 ConcurrentGCThread "G1 Refine#1" [stack: 0x000000405d270000,0x000000405d370000] [id=2284]
  0x000000403eff6800 ConcurrentGCThread "G1 Young RemSet Sampling" [stack: 0x000000405d370000,0x000000405d470000] [id=2560]
Threads with active compile tasks:
C2 CompilerThread02757       4       javafx.scene.CssStyleHelper::resolveRef (128 bytes)
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
Heap address: 0x00000000de400000, size: 540 MB, Compressed Oops mode: 32-bit
Narrow klass base: 0x0000000000000000, Narrow klass shift: 3
Compressed class space size: 1073741824 Address: 0x0000000100000000
Heap:
 garbage-first heap   total 41984K, used 24829K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 6 young (6144K), 2 survivors (2048K)
 Metaspace       used 26798K, capacity 27760K, committed 28032K, reserved 1073152K
  class space    used 3433K, capacity 3868K, committed 3968K, reserved 1048576K
Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, A=archive, TS=gc time stamp, AC=allocation context, TAMS=top-at-mark-start (previous, next)
|   0|0x00000000de400000, 0x00000000de500000, 0x00000000de500000|100%| O|  |TS  0|AC  0|TAMS 0x00000000de500000, 0x00000000de500000|
|   1|0x00000000de500000, 0x00000000de600000, 0x00000000de600000|100%| O|  |TS  0|AC  0|TAMS 0x00000000de600000, 0x00000000de600000|
|   2|0x00000000de600000, 0x00000000de700000, 0x00000000de700000|100%| O|  |TS  0|AC  0|TAMS 0x00000000de700000, 0x00000000de700000|
|   3|0x00000000de700000, 0x00000000de800000, 0x00000000de800000|100%| O|  |TS  0|AC  0|TAMS 0x00000000de800000, 0x00000000de800000|
|   4|0x00000000de800000, 0x00000000de900000, 0x00000000de900000|100%|HS|  |TS  0|AC  0|TAMS 0x00000000de900000, 0x00000000de900000|
|   5|0x00000000de900000, 0x00000000dea00000, 0x00000000dea00000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000dea00000, 0x00000000dea00000|
|   6|0x00000000dea00000, 0x00000000deb00000, 0x00000000deb00000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000deb00000, 0x00000000deb00000|
|   7|0x00000000deb00000, 0x00000000dec00000, 0x00000000dec00000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000dec00000, 0x00000000dec00000|
|   8|0x00000000dec00000, 0x00000000ded00000, 0x00000000ded00000|100%| O|  |TS  0|AC  0|TAMS 0x00000000ded00000, 0x00000000ded00000|
|   9|0x00000000ded00000, 0x00000000dee00000, 0x00000000dee00000|100%| O|  |TS  0|AC  0|TAMS 0x00000000dee00000, 0x00000000dee00000|
|  10|0x00000000dee00000, 0x00000000dee79800, 0x00000000def00000| 47%| O|  |TS  0|AC  0|TAMS 0x00000000dee79800, 0x00000000dee79800|
|  11|0x00000000def00000, 0x00000000df000000, 0x00000000df000000|100%|HS|  |TS  0|AC  0|TAMS 0x00000000df000000, 0x00000000df000000|
|  12|0x00000000df000000, 0x00000000df100000, 0x00000000df100000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df100000, 0x00000000df100000|
|  13|0x00000000df100000, 0x00000000df200000, 0x00000000df200000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df200000, 0x00000000df200000|
|  14|0x00000000df200000, 0x00000000df300000, 0x00000000df300000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df300000, 0x00000000df300000|
|  15|0x00000000df300000, 0x00000000df400000, 0x00000000df400000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df400000, 0x00000000df400000|
|  16|0x00000000df400000, 0x00000000df500000, 0x00000000df500000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df500000, 0x00000000df500000|
|  17|0x00000000df500000, 0x00000000df600000, 0x00000000df600000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df600000, 0x00000000df600000|
|  18|0x00000000df600000, 0x00000000df700000, 0x00000000df700000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df700000, 0x00000000df700000|
|  19|0x00000000df700000, 0x00000000df800000, 0x00000000df800000|100%|HC|  |TS  0|AC  0|TAMS 0x00000000df800000, 0x00000000df800000|
|  20|0x00000000df800000, 0x00000000df800000, 0x00000000df900000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000df800000, 0x00000000df800000|
|  21|0x00000000df900000, 0x00000000df900000, 0x00000000dfa00000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000df900000, 0x00000000df900000|
|  22|0x00000000dfa00000, 0x00000000dfa00000, 0x00000000dfb00000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000dfa00000, 0x00000000dfa00000|
|  23|0x00000000dfb00000, 0x00000000dfb00000, 0x00000000dfc00000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000dfb00000, 0x00000000dfb00000|
|  24|0x00000000dfc00000, 0x00000000dfc00000, 0x00000000dfd00000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000dfc00000, 0x00000000dfc00000|
|  25|0x00000000dfd00000, 0x00000000dfd00000, 0x00000000dfe00000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000dfd00000, 0x00000000dfd00000|
|  26|0x00000000dfe00000, 0x00000000dfe00000, 0x00000000dff00000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000dfe00000, 0x00000000dfe00000|
|  27|0x00000000dff00000, 0x00000000dff00000, 0x00000000e0000000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000dff00000, 0x00000000dff00000|
|  28|0x00000000e0000000, 0x00000000e0000000, 0x00000000e0100000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000e0000000, 0x00000000e0000000|
|  29|0x00000000e0100000, 0x00000000e0100000, 0x00000000e0200000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000e0100000, 0x00000000e0100000|
|  30|0x00000000e0200000, 0x00000000e0200000, 0x00000000e0300000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000e0200000, 0x00000000e0200000|
|  31|0x00000000e0300000, 0x00000000e03c5d10, 0x00000000e0400000| 77%| S|CS|TS  0|AC  0|TAMS 0x00000000e0300000, 0x00000000e0300000|
|  32|0x00000000e0400000, 0x00000000e0500000, 0x00000000e0500000|100%| S|CS|TS  0|AC  0|TAMS 0x00000000e0400000, 0x00000000e0400000|
|  33|0x00000000e0500000, 0x00000000e0500000, 0x00000000e0600000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000e0500000, 0x00000000e0500000|
|  34|0x00000000e0600000, 0x00000000e0600000, 0x00000000e0700000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000e0600000, 0x00000000e0600000|
|  35|0x00000000e0700000, 0x00000000e0700000, 0x00000000e0800000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000e0700000, 0x00000000e0700000|
|  36|0x00000000e0800000, 0x00000000e0800000, 0x00000000e0900000|  0%| F|  |TS  0|AC  0|TAMS 0x00000000e0800000, 0x00000000e0800000|
|  37|0x00000000e0900000, 0x00000000e09db4f0, 0x00000000e0a00000| 85%| E|  |TS  0|AC  0|TAMS 0x00000000e0900000, 0x00000000e0900000|
|  38|0x00000000e0a00000, 0x00000000e0b00000, 0x00000000e0b00000|100%| E|CS|TS  0|AC  0|TAMS 0x00000000e0a00000, 0x00000000e0a00000|
|  39|0x00000000e0b00000, 0x00000000e0c00000, 0x00000000e0c00000|100%| E|CS|TS  0|AC  0|TAMS 0x00000000e0b00000, 0x00000000e0b00000|
|  40|0x00000000e0c00000, 0x00000000e0d00000, 0x00000000e0d00000|100%| E|CS|TS  0|AC  0|TAMS 0x00000000e0c00000, 0x00000000e0c00000|
Card table byte_map: [0x0000004059a40000,0x0000004059b50000] byte_map_base: 0x000000405934e000
Marking Bits (Prev, Next): (CMBitMap*) 0x000000403efc0038, (CMBitMap*) 0x000000403efc0000
 Prev Bits: [0x000000405a4d0000, 0x000000405ad40000)
 Next Bits: [0x0000004059c60000, 0x000000405a4d0000)
Polling page: 0x000000403d550000
CodeHeap 'non-profiled nmethods': size=120064Kb used=1127Kb max_used=1127Kb free=118936Kb
 bounds [0x0000004051df0000, 0x0000004052060000, 0x0000004059330000]
CodeHeap 'profiled nmethods': size=120000Kb used=5448Kb max_used=5448Kb free=114551Kb
 bounds [0x000000404a8c0000, 0x000000404ae20000, 0x0000004051df0000]
CodeHeap 'non-nmethods': size=5696Kb used=1313Kb max_used=1332Kb free=4382Kb
 bounds [0x000000404a330000, 0x000000404a5a0000, 0x000000404a8c0000]
 total_blobs=4024 nmethods=2735 adapters=634
 compilation: enabled
Compilation events (10 events):
Event: 5.031 Thread 0x000000405de17000 2747       1       com.sun.javafx.css.StyleMap::getId (5 bytes)
Event: 5.031 Thread 0x000000405de17000 nmethod 2747 0x0000004051f09790 code [0x0000004051f09940, 0x0000004051f09a58]
Event: 5.031 Thread 0x000000405de17000 2783       1       java.util.Collections$SingletonList::size (2 bytes)
Event: 5.032 Thread 0x000000405de17000 nmethod 2783 0x0000004051f09b10 code [0x0000004051f09cc0, 0x0000004051f09dd8]
Event: 5.042 Thread 0x000000405de17000 2794       2       java.lang.invoke.DelegatingMethodHandle::whichKind (40 bytes)
Event: 5.042 Thread 0x000000405de17000 nmethod 2794 0x000000404ae12090 code [0x000000404ae12240, 0x000000404ae123b8]
Event: 5.048 Thread 0x000000405de17000 2797       2       com.sun.javafx.geom.RectBounds::setBounds (22 bytes)
Event: 5.048 Thread 0x000000405de17000 nmethod 2797 0x000000404ae12490 code [0x000000404ae12640, 0x000000404ae127b8]
Event: 5.048 Thread 0x000000405de17000 2796       2       com.sun.marlin.IntArrayCache$Reference::putArray (55 bytes)
Event: 5.048 Thread 0x000000405de17000 nmethod 2796 0x000000404ae12890 code [0x000000404ae12a80, 0x000000404ae12e30]
GC Heap History (10 events):
Event: 1.564 GC heap before
{Heap before GC invocations=2 (full 0):
 garbage-first heap   total 34816K, used 19332K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 12 young (12288K), 1 survivors (1024K)
 Metaspace       used 17761K, capacity 18252K, committed 18432K, reserved 1064960K
  class space    used 2013K, capacity 2210K, committed 2304K, reserved 1048576K
}
Event: 1.574 GC heap after
{Heap after GC invocations=3 (full 0):
 garbage-first heap   total 34816K, used 9367K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 2 young (2048K), 2 survivors (2048K)
 Metaspace       used 17761K, capacity 18252K, committed 18432K, reserved 1064960K
  class space    used 2013K, capacity 2210K, committed 2304K, reserved 1048576K
}
Event: 1.887 GC heap before
{Heap before GC invocations=3 (full 0):
 garbage-first heap   total 34816K, used 13463K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 7 young (7168K), 2 survivors (2048K)
 Metaspace       used 20561K, capacity 21075K, committed 21296K, reserved 1069056K
  class space    used 2446K, capacity 2688K, committed 2688K, reserved 1048576K
}
Event: 1.896 GC heap after
{Heap after GC invocations=4 (full 0):
 garbage-first heap   total 34816K, used 10685K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 2 young (2048K), 2 survivors (2048K)
 Metaspace       used 20561K, capacity 21075K, committed 21296K, reserved 1069056K
  class space    used 2446K, capacity 2688K, committed 2688K, reserved 1048576K
}
Event: 2.013 GC heap before
{Heap before GC invocations=5 (full 0):
 garbage-first heap   total 34816K, used 11709K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 4 young (4096K), 2 survivors (2048K)
 Metaspace       used 21544K, capacity 22172K, committed 22576K, reserved 1069056K
  class space    used 2615K, capacity 2871K, committed 2944K, reserved 1048576K
}
Event: 2.018 GC heap after
{Heap after GC invocations=6 (full 0):
 garbage-first heap   total 41984K, used 11021K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 1 young (1024K), 1 survivors (1024K)
 Metaspace       used 21544K, capacity 22172K, committed 22576K, reserved 1069056K
  class space    used 2615K, capacity 2871K, committed 2944K, reserved 1048576K
}
Event: 3.349 GC heap before
{Heap before GC invocations=7 (full 0):
 garbage-first heap   total 41984K, used 31501K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 12 young (12288K), 1 survivors (1024K)
 Metaspace       used 23765K, capacity 24476K, committed 24832K, reserved 1071104K
  class space    used 2948K, capacity 3281K, committed 3328K, reserved 1048576K
}
Event: 3.372 GC heap after
{Heap after GC invocations=8 (full 0):
 garbage-first heap   total 41984K, used 20966K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 1 young (1024K), 1 survivors (1024K)
 Metaspace       used 23765K, capacity 24476K, committed 24832K, reserved 1071104K
  class space    used 2948K, capacity 3281K, committed 3328K, reserved 1048576K
}
Event: 4.366 GC heap before
{Heap before GC invocations=8 (full 0):
 garbage-first heap   total 41984K, used 29158K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 9 young (9216K), 1 survivors (1024K)
 Metaspace       used 25964K, capacity 26861K, committed 27392K, reserved 1073152K
  class space    used 3312K, capacity 3713K, committed 3840K, reserved 1048576K
}
Event: 4.372 GC heap after
{Heap after GC invocations=9 (full 0):
 garbage-first heap   total 41984K, used 21757K [0x00000000de400000, 0x0000000100000000)
  region size 1024K, 2 young (2048K), 2 survivors (2048K)
 Metaspace       used 25964K, capacity 26861K, committed 27392K, reserved 1073152K
  class space    used 3312K, capacity 3713K, committed 3840K, reserved 1048576K
}
Deoptimization events (10 events):
Event: 4.962 Thread 0x000000405f64e800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000004051ee199c method=com.sun.javafx.css.StyleManager$CacheContainer.getStyleMap(I)Lcom/sun/javafx/css/StyleMap; @ 22 c2
Event: 4.970 Thread 0x000000405f64e800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x0000004051ed7144 method=javafx.scene.Node.getScene()Ljavafx/scene/Scene; @ 7 c2
Event: 4.971 Thread 0x000000405f64e800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x0000004051ed7144 method=javafx.scene.Node.getScene()Ljavafx/scene/Scene; @ 7 c2
Event: 4.971 Thread 0x000000405f64e800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x0000004051ed7144 method=javafx.scene.Node.getScene()Ljavafx/scene/Scene; @ 7 c2
Event: 4.971 Thread 0x000000405f64e800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x0000004051ed7144 method=javafx.scene.Node.getScene()Ljavafx/scene/Scene; @ 7 c2
Event: 4.971 Thread 0x000000405f64e800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x0000004051ee716c method=javafx.scene.Node.getScene()Ljavafx/scene/Scene; @ 7 c2
Event: 4.982 Thread 0x000000405f64e800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000004051ec8744 method=com.sun.javafx.css.BitSet.addAll(Ljava/util/Collection;)Z @ 1 c2
Event: 5.000 Thread 0x000000405f64e800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000004051e3ec2c method=jdk.internal.org.objectweb.asm.Type.getArgumentsAndReturnSizes(Ljava/lang/String;)I @ 47 c2
Event: 5.000 Thread 0x000000405f64e800 Uncommon trap: reason=unstable_if action=reinterpret pc=0x0000004051e5d11c method=jdk.internal.org.objectweb.asm.Frame.push(Ljdk/internal/org/objectweb/asm/ClassWriter;Ljava/lang/String;)V @ 18 c2
Event: 5.047 Thread 0x000000405f666800 Uncommon trap: reason=class_check action=maybe_recompile pc=0x0000004051e4b618 method=java.util.concurrent.ConcurrentHashMap.putVal(Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object; @ 242 c2
Classes redefined (0 events):
No events
Internal exceptions (10 events):
Event: 4.752 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e0b41098}: method resolution failed> (0x00000000e0b41098) thrown at [t:/workspace/open/src/hotspot/share/prims/methodHandles.cpp, line 1226]
Event: 4.752 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e0b454c0}: method resolution failed> (0x00000000e0b454c0) thrown at [t:/workspace/open/src/hotspot/share/prims/methodHandles.cpp, line 1226]
Event: 4.939 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e0bc37e0}: java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(Ljava/lang/Object;I)V> (0x00000000e0bc37e0) thrown at [t:/workspace/open/src/hotspot/share/interpreter/linkResolver.cpp, line 741]
Event: 4.982 Thread 0x000000405f64e800 Implicit null exception at 0x0000004051ec80f1 to 0x0000004051ec872e
Event: 5.000 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e09200b0}: method resolution failed> (0x00000000e09200b0) thrown at [t:/workspace/open/src/hotspot/share/prims/methodHandles.cpp, line 1226]
Event: 5.000 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e09231f8}: java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)J> (0x00000000e09231f8) thrown at [t:/workspace/open/src/hotspot/share/inter
Event: 5.002 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e0936300}: method resolution failed> (0x00000000e0936300) thrown at [t:/workspace/open/src/hotspot/share/prims/methodHandles.cpp, line 1226]
Event: 5.002 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e093c1b0}: java.lang.invoke.DirectMethodHandle$Holder.invokeStatic(Ljava/lang/Object;Ljava/lang/Object;J)Ljava/lang/Object;> (0x00000000e093c1b0) thrown at [t:/workspace/open/src/hotspot/share/interpret
Event: 5.002 Thread 0x000000405f64e800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e093f8a0}: method resolution failed> (0x00000000e093f8a0) thrown at [t:/workspace/open/src/hotspot/share/prims/methodHandles.cpp, line 1226]
Event: 5.033 Thread 0x000000405f666800 Exception <a 'java/lang/NoSuchMethodError'{0x00000000e0c72628}: java.lang.invoke.DirectMethodHandle$Holder.invokeStaticInit(Ljava/lang/Object;I)Ljava/lang/Object;> (0x00000000e0c72628) thrown at [t:/workspace/open/src/hotspot/share/interpreter/linkResolve
Events (10 events):
Event: 5.034 loading class java/lang/FdLibm done
Event: 5.036 loading class com/sun/scenario/effect/FilterContext
Event: 5.036 loading class com/sun/scenario/effect/FilterContext done
Event: 5.036 loading class com/sun/scenario/effect/impl/Renderer
Event: 5.036 loading class com/sun/scenario/effect/impl/Renderer done
Event: 5.036 loading class com/sun/scenario/effect/FilterContext
Event: 5.036 loading class com/sun/scenario/effect/FilterContext done
Event: 5.047 Thread 0x000000405f666800 Uncommon trap: trap_request=0xffffffde fr.pc=0x0000004051e4b618 relative=0x00000000000011d8
Event: 5.047 Thread 0x000000405f666800 DEOPT PACKING pc=0x0000004051e4b618 sp=0x00000040616fcb80
Event: 5.047 Thread 0x000000405f666800 DEOPT UNPACKING pc=0x000000404a358a2f sp=0x00000040616fcb00 mode 2
Dynamic libraries:
0x00007ff78d530000 - 0x00007ff78d56e000     C:\jdk10\bin\java.exe
0x00007ffffb920000 - 0x00007ffffbacd000     C:\windows\SYSTEM32\ntdll.dll
0x00007ffffb030000 - 0x00007ffffb16e000     C:\windows\system32\KERNEL32.DLL
0x00007ffff8e90000 - 0x00007ffff8fa5000     C:\windows\system32\KERNELBASE.dll
0x00007ffffb7c0000 - 0x00007ffffb86a000     C:\windows\system32\ADVAPI32.dll
0x00007ffffb640000 - 0x00007ffffb7b7000     C:\windows\system32\USER32.dll
0x00007fffefdb0000 - 0x00007ffff002b000     C:\windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9600.18006_none_623f33d3ecbe86e8\COMCTL32.dll
0x00007ffff29c0000 - 0x00007ffff29ca000     C:\windows\SYSTEM32\VERSION.dll
0x00007ffffb870000 - 0x00007ffffb91a000     C:\windows\system32\msvcrt.dll
0x00007ffffab20000 - 0x00007ffffab79000     C:\windows\SYSTEM32\sechost.dll
0x00007ffffa980000 - 0x00007ffffaac0000     C:\windows\system32\RPCRT4.dll
0x00007ffffaee0000 - 0x00007ffffb02b000     C:\windows\system32\GDI32.dll
0x00007ffff8b20000 - 0x00007ffff8b4e000     C:\windows\system32\SspiCli.dll
0x00007ffffa790000 - 0x00007ffffa7c6000     C:\windows\system32\IMM32.DLL
0x00007ffff90e0000 - 0x00007ffff9231000     C:\windows\system32\MSCTF.dll
0x00007fffee3a0000 - 0x00007fffee48f000     C:\jdk10\bin\msvcr120.dll
0x00007fffe3ab0000 - 0x00007fffe3b56000     C:\jdk10\bin\msvcp120.dll
0x0000000077590000 - 0x0000000077fff000     C:\jdk10\bin\server\jvm.dll
0x00007ffff0b60000 - 0x00007ffff0b69000     C:\windows\SYSTEM32\WSOCK32.dll
0x00007ffff1d30000 - 0x00007ffff1d52000     C:\windows\SYSTEM32\WINMM.dll
0x00007ffffa770000 - 0x00007ffffa777000     C:\windows\system32\PSAPI.DLL
0x00007ffffab80000 - 0x00007ffffabda000     C:\windows\system32\WS2_32.dll
0x00007ffff1d00000 - 0x00007ffff1d2a000     C:\windows\SYSTEM32\WINMMBASE.dll
0x00007ffffa780000 - 0x00007ffffa789000     C:\windows\system32\NSI.dll
0x00007ffff8c00000 - 0x00007ffff8c4f000     C:\windows\SYSTEM32\cfgmgr32.dll
0x00007ffff78f0000 - 0x00007ffff7918000     C:\windows\SYSTEM32\DEVOBJ.dll
0x00007fffeebc0000 - 0x00007fffeebcf000     C:\jdk10\bin\verify.dll
0x00007fffe3920000 - 0x00007fffe3aa9000     C:\windows\SYSTEM32\DBGHELP.DLL
0x00007fffee370000 - 0x00007fffee397000     C:\jdk10\bin\java.dll
0x00007fffeeba0000 - 0x00007fffeebb6000     C:\jdk10\bin\zip.dll
0x00007fffee360000 - 0x00007fffee36a000     C:\jdk10\bin\jimage.dll
0x00007ffff9240000 - 0x00007ffffa76c000     C:\windows\system32\SHELL32.dll
0x00007ffffabe0000 - 0x00007ffffadf2000     C:\windows\SYSTEM32\combase.dll
0x00007ffffaac0000 - 0x00007ffffab14000     C:\windows\system32\SHLWAPI.dll
0x00007ffff55d0000 - 0x00007ffff5682000     C:\windows\SYSTEM32\SHCORE.dll
0x00007ffff8a50000 - 0x00007ffff8a65000     C:\windows\SYSTEM32\profapi.dll
0x00007fffea0f0000 - 0x00007fffea10a000     C:\jdk10\bin\net.dll
0x00007ffff4820000 - 0x00007ffff48e7000     C:\windows\SYSTEM32\WINHTTP.dll
0x00007ffff8320000 - 0x00007ffff8379000     C:\windows\system32\mswsock.dll
0x00007fffea0d0000 - 0x00007fffea0e1000     C:\jdk10\bin\nio.dll
0x00007ffff83f0000 - 0x00007ffff8410000     C:\windows\SYSTEM32\CRYPTSP.dll
0x00007ffff7d80000 - 0x00007ffff7db6000     C:\windows\system32\rsaenh.dll
0x00007ffff8530000 - 0x00007ffff8556000     C:\windows\SYSTEM32\bcrypt.dll
0x00007ffff8380000 - 0x00007ffff83a1000     C:\windows\SYSTEM32\USERENV.dll
0x00007ffff8850000 - 0x00007ffff88b3000     C:\windows\system32\bcryptprimitives.dll
0x00007ffff88c0000 - 0x00007ffff88cb000     C:\windows\SYSTEM32\CRYPTBASE.dll
0x00007ffff6630000 - 0x00007ffff665a000     C:\windows\SYSTEM32\IPHLPAPI.DLL
0x00007ffff6680000 - 0x00007ffff668a000     C:\windows\SYSTEM32\WINNSI.DLL
0x00007ffff6110000 - 0x00007ffff6126000     C:\windows\SYSTEM32\dhcpcsvc6.DLL
0x00007ffff5c10000 - 0x00007ffff5c2a000     C:\windows\SYSTEM32\dhcpcsvc.DLL
0x00007ffff2d40000 - 0x00007ffff2d43000     C:\jdk10\bin\api-ms-win-core-console-l1-1-0.dll
0x00007ffff2d30000 - 0x00007ffff2d33000     C:\jdk10\bin\api-ms-win-core-datetime-l1-1-0.dll
0x00007ffff2d20000 - 0x00007ffff2d23000     C:\jdk10\bin\api-ms-win-core-debug-l1-1-0.dll
0x00007ffff28e0000 - 0x00007ffff28e3000     C:\jdk10\bin\api-ms-win-core-errorhandling-l1-1-0.dll
0x00007ffff1930000 - 0x00007ffff1934000     C:\jdk10\bin\api-ms-win-core-file-l1-1-0.dll
0x00007ffff1920000 - 0x00007ffff1923000     C:\jdk10\bin\api-ms-win-core-file-l1-2-0.dll
0x00007ffff1910000 - 0x00007ffff1913000     C:\jdk10\bin\api-ms-win-core-file-l2-1-0.dll
0x00007ffff1900000 - 0x00007ffff1903000     C:\jdk10\bin\api-ms-win-core-handle-l1-1-0.dll
0x00007ffff18f0000 - 0x00007ffff18f3000     C:\jdk10\bin\api-ms-win-core-heap-l1-1-0.dll
0x00007ffff18e0000 - 0x00007ffff18e3000     C:\jdk10\bin\api-ms-win-core-interlocked-l1-1-0.dll
0x00007ffff18d0000 - 0x00007ffff18d3000     C:\jdk10\bin\api-ms-win-core-libraryloader-l1-1-0.dll
0x00007ffff18c0000 - 0x00007ffff18c3000     C:\jdk10\bin\api-ms-win-core-localization-l1-2-0.dll
0x00007ffff18b0000 - 0x00007ffff18b3000     C:\jdk10\bin\api-ms-win-core-memory-l1-1-0.dll
0x00007ffff18a0000 - 0x00007ffff18a3000     C:\jdk10\bin\api-ms-win-core-namedpipe-l1-1-0.dll
0x00007ffff1890000 - 0x00007ffff1893000     C:\jdk10\bin\api-ms-win-core-processenvironment-l1-1-0.dll
0x00007ffff1880000 - 0x00007ffff1883000     C:\jdk10\bin\api-ms-win-core-processthreads-l1-1-0.dll
0x00007ffff1870000 - 0x00007ffff1873000     C:\jdk10\bin\api-ms-win-core-processthreads-l1-1-1.dll
0x00007ffff1860000 - 0x00007ffff1863000     C:\jdk10\bin\api-ms-win-core-profile-l1-1-0.dll
0x00007ffff1850000 - 0x00007ffff1853000     C:\jdk10\bin\api-ms-win-core-rtlsupport-l1-1-0.dll
0x00007ffff1840000 - 0x00007ffff1843000     C:\jdk10\bin\api-ms-win-core-string-l1-1-0.dll
0x00007ffff1830000 - 0x00007ffff1833000     C:\jdk10\bin\api-ms-win-core-synch-l1-1-0.dll
0x00007ffff1820000 - 0x00007ffff1823000     C:\jdk10\bin\api-ms-win-core-synch-l1-2-0.dll
0x00007ffff1810000 - 0x00007ffff1813000     C:\jdk10\bin\api-ms-win-core-sysinfo-l1-1-0.dll
0x00007ffff1800000 - 0x00007ffff1803000     C:\jdk10\bin\api-ms-win-core-timezone-l1-1-0.dll
0x00007ffff17f0000 - 0x00007ffff17f3000     C:\jdk10\bin\api-ms-win-core-util-l1-1-0.dll
0x00007ffff17e0000 - 0x00007ffff17e3000     C:\jdk10\bin\api-ms-win-crt-conio-l1-1-0.dll
0x00007ffff17d0000 - 0x00007ffff17d4000     C:\jdk10\bin\api-ms-win-crt-convert-l1-1-0.dll
0x00007ffff17c0000 - 0x00007ffff17c3000     C:\jdk10\bin\api-ms-win-crt-environment-l1-1-0.dll
0x00007ffff17b0000 - 0x00007ffff17b3000     C:\jdk10\bin\api-ms-win-crt-filesystem-l1-1-0.dll
0x00007ffff17a0000 - 0x00007ffff17a3000     C:\jdk10\bin\api-ms-win-crt-heap-l1-1-0.dll
0x00007ffff1790000 - 0x00007ffff1793000     C:\jdk10\bin\api-ms-win-crt-locale-l1-1-0.dll
0x00007ffff1780000 - 0x00007ffff1785000     C:\jdk10\bin\api-ms-win-crt-math-l1-1-0.dll
0x00007ffff1770000 - 0x00007ffff1775000     C:\jdk10\bin\api-ms-win-crt-multibyte-l1-1-0.dll
0x00007ffff1120000 - 0x00007ffff1130000     C:\jdk10\bin\api-ms-win-crt-private-l1-1-0.dll
0x00007ffff1110000 - 0x00007ffff1113000     C:\jdk10\bin\api-ms-win-crt-process-l1-1-0.dll
0x00007ffff1100000 - 0x00007ffff1104000     C:\jdk10\bin\api-ms-win-crt-runtime-l1-1-0.dll
0x00007ffff0bb0000 - 0x00007ffff0bb4000     C:\jdk10\bin\api-ms-win-crt-stdio-l1-1-0.dll
0x00007ffff0ba0000 - 0x00007ffff0ba4000     C:\jdk10\bin\api-ms-win-crt-string-l1-1-0.dll
0x00007ffff0b90000 - 0x00007ffff0b93000     C:\jdk10\bin\api-ms-win-crt-time-l1-1-0.dll
0x00007ffff0b80000 - 0x00007ffff0b83000     C:\jdk10\bin\api-ms-win-crt-utility-l1-1-0.dll
0x00007fffe2cd0000 - 0x00007fffe2dc6000     C:\jdk10\bin\ucrtbase.dll
0x00007fffe2cb0000 - 0x00007fffe2cc6000     C:\jdk10\bin\vcruntime140.dll
0x00007fffe2aa0000 - 0x00007fffe2b3c000     C:\jdk10\bin\msvcp140.dll
0x00007fffe2a40000 - 0x00007fffe2a91000     C:\jdk10\bin\concrt140.dll
0x00007fffe2c90000 - 0x00007fffe2cac000     C:\jdk10\bin\prism_sw.dll
0x00007fffe2c70000 - 0x00007fffe2c84000     C:\jdk10\bin\javafx_font.dll
0x00007ffffb370000 - 0x00007ffffb504000     C:\windows\system32\ole32.dll
0x00007fffe26d0000 - 0x00007fffe286b000     C:\jdk10\bin\awt.dll
0x00007ffffae00000 - 0x00007ffffaec6000     C:\windows\system32\OLEAUT32.dll
0x00007ffff5c80000 - 0x00007ffff6101000     C:\windows\SYSTEM32\d2d1.dll
0x00007ffff75c0000 - 0x00007ffff764e000     C:\windows\system32\apphelp.dll
0x00007fffe29d0000 - 0x00007fffe2a35000     C:\jdk10\bin\fontmanager.dll
0x00007ffff7750000 - 0x00007ffff7879000     C:\windows\system32\uxtheme.dll
0x00007fffee660000 - 0x00007fffee84a000     C:\windows\SYSTEM32\dwrite.dll
0x00007ffff1b70000 - 0x00007ffff1b87000     C:\jdk10\bin\decora_sse.dll
0x00007ffff7710000 - 0x00007ffff771b000     C:\windows\SYSTEM32\kernel.appcore.dll
0x00007ffffb580000 - 0x00007ffffb636000     C:\windows\SYSTEM32\clbcatq.dll
dbghelp: loaded successfully - version: 4.0.5 - missing functions: none
symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;C:\jdk10\bin;C:\windows\SYSTEM32;C:\windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9600.18006_none_623f33d3ecbe86e8;C:\jdk10\bin\server
VM Arguments:
jvm_args: -Dorg.gradle.native=false -Dfile.encoding=windows-1252 -Duser.country=US -Duser.language=en -Duser.variant -ea -Djava.awt.headless=true -Dtestfx.robot=glass -Dtestfx.headless=true -Dprism.order=sw -Dprism.text=t2k 
java_command: worker.org.gradle.process.internal.worker.GradleWorkerMain 'Gradle Test Executor 1'
java_class_path (initial): C:\\Users\\appveyor\\.gradle\\caches\\4.6\\workerMain\\gradle-worker.jar;C:\\projects\\testfx\\subprojects\\testfx-core\\build\\classes\\java\\test;C:\\projects\\testfx\\subprojects\\testfx-core\\build\\resources\\test;C:\\projects\\testfx\\subprojects\\testfx-core\\build\\classes\\java\\main;C:\\projects\\testfx\\subprojects\\testfx-core\\build\\resources\\main;C:\\projects\\testfx\\subprojects\\testfx-junit\\build\\libs\\testfx-junit-4.0.13-alpha.jar;C:\\projects\\testfx\\subprojects\\testfx-core\\build\\libs\\testfx-core-4.0.13-alpha.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\junit\\junit\\4.12\\2973d150c0dc1fefe998f834810d68f278ea58ec\\junit-4.12.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\org.hamcrest\\hamcrest-core\\1.3\\42a25dc3219429f0e5d060061f71acb49bf010a0\\hamcrest-core-1.3.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\org.assertj\\assertj-core\\3.9.1\\c5ce126b15f28d56cd8f960c1a6a058b9c9aea87\\assertj-core-3.9.1.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\org.mockito\\mockito-core\\2.18.0\\d3e839acfc4b862bbcfe9165c316f1567db24cb6\\mockito-core-2.18.0.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\org.testfx\\openjfx-monocle\\jdk-9+181\\c412deb11898e532c46e4d6c2808e4227f120445\\openjfx-monocle-jdk-9+181.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\net.bytebuddy\\byte-buddy\\1.8.3\\c7625191ad0f190bd719f0aef54ece5fdf0e4a77\\byte-buddy-1.8.3.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\net.bytebuddy\\byte-buddy-agent\\1.8.3\\897127e8724cbf38f72b4c85fe8e39e7ae00d688\\byte-buddy-agent-1.8.3.jar;C:\\Users\\appveyor\\.gradle\\caches\\modules-2\\files-2.1\\org.objenesis\\objenesis\\2.6\\639033469776fd37c08358c6b92a4761feb2af4b\\objenesis-2.6.jar
Launcher Type: SUN_STANDARD
Logging:
Log output configuration:
#0: stdout all=warning uptime,level,tags
#1: stderr all=off uptime,level,tags
Environment Variables:
JAVA_HOME=C:\jdk10
_JAVA_OPTIONS=-Djava.awt.headless=true -Dtestfx.robot=glass -Dtestfx.headless=true -Dprism.order=sw -Dprism.text=t2k
CLASSPATH=C:\projects\testfx\\gradle\wrapper\gradle-wrapper.jar
PATH=C:\Perl\site\bin;C:\Perl\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\7-Zip;C:\Program Files\Microsoft\Web Platform Installer\;C:\Tools\GitVersion;C:\Tools\PsTools;C:\Program Files\Git LFS;C:\Program Files (x86)\Subversion\bin;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\Tools\Binn\ManagementStudio\;C:\Tools\WebDriver;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.4\;C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\PrivateAssemblies\;C:\Program Files (x86)\Microsoft SDKs\Azure\CLI\wbin;C:\Ruby193\bin;C:\Tools\NUnit\bin;C:\Tools\xUnit;C:\Tools\MSpec;C:\Tools\Coverity\bin;C:\Program Files (x86)\CMake\bin;C:\go\bin;C:\Program Files\Java\jdk1.8.0\bin;C:\Python27;C:\Program Files\nodejs;C:\Program Files (x86)\iojs;C:\Program Files\iojs;C:\Users\appveyor\AppData\Roaming\npm;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files (x86)\MSBuild\14.0\Bin;C:\Tools\NuGet;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files\Microsoft DNX\Dnvm;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn\;C:\Program Files\Microsoft SQL Server\130\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;C:\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\;C:\Program Files (x86)\Apache\Maven\bin;C:\Python27\Scripts;C:\Tools\NUnit3;C:\Program Files\Mercurial\;C:\Program Files\LLVM\bin;C:\Program Files\dotnet\;C:\Tools\curl\bin;C:\Program Files\Amazon\AWSCLI\;C:\Program Files (x86)\Microsoft SQL Server\140\DTS\Binn\;C:\Program Files (x
USERNAME=appveyor
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 63 Stepping 2, GenuineIntel
---------------  S Y S T E M  ---------------
OS: Windows Server 2012 R2 , 64 bit Build 9600 (6.3.9600.17415)
CPU:total 2 (initial active 2) (2 cores per cpu, 1 threads per core) family 6 model 63 stepping 2, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, lzcnt, tsc, bmi1, bmi2, fma
Memory: 4k page, physical 2204696k(540100k free), swap 2700512k(618992k free)
vm_info: Java HotSpot(TM) 64-Bit Server VM (10+46) for windows-amd64 JRE (10+46), built on Mar  8 2018 02:11:18 by "mach5one" with MS VC++ 12.0 (VS2013)
END.
kevinrushforth commented 6 years ago

Is it possible that you were somehow falling back to T2K when running with JDK 9? The native font implementation, which calls DirectWrite on Windows platforms, has been the default since JDK 8, but we would fall back to T2K on Windows platforms without the necessary support (or via java -Dprism.text=t2k). The T2K code was removed in JDK 10, so there is no longer a fallback path. The fallback should have only ever happened on Windows Vista, though.

kevinrushforth commented 6 years ago

Answering my own question, I see this in your log:

    -Dprism.text=t2k

which means you were running T2K with JDK 9 and earlier. That flag is now ignored, so you are running the native font code with JDK 10. So that at least explains why the upgrade to JDK 10 has triggered this bug.

kevinrushforth commented 6 years ago

I filed JDK-8201539 in JBS.

brcolow commented 6 years ago

That makes a lot of sense, thanks so much for tracking that down. I always wondered why we used that argument... 😆

brcolow commented 6 years ago

If we trust the native back-trace, it says the access violation occurs at javafx_font!cacheDWRITE_GLYPH_METRICSFields+0x280: which corresponds to void cacheDWRITE_GLYPH_METRICSFields(JNIEnv *env) in directwrite.cpp.

brcolow commented 6 years ago

@ararunprasad You were very helpful with the MathML bug (https://github.com/javafxports/openjdk-jfx/issues/71), do you think you could provide a little guidance on this one?

arajkumar commented 6 years ago

@brcolow , let me take a look.

kevinrushforth commented 6 years ago

@brcolow @ararunprasad We roughly know what the problem is: Some initialization that is done by either the D3D pipeline or Glass (either is sufficient) is needed to allow the DirectWrite calls used by the native font code to work.

brcolow commented 6 years ago

To get started on this issue, I took a look at the source code to figure out where the crash is happening, and that is here:

/* IWICImagingFactory*/
JNIEXPORT jlong JNICALL OS_NATIVE(CreateBitmap)
    (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2, jint arg3, jint arg4)
{
    IWICBitmap* result = NULL;
    GUID pixelFormat;
    switch (arg3) {
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat8bppGray:pixelFormat = GUID_WICPixelFormat8bppGray; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat8bppAlpha:pixelFormat = GUID_WICPixelFormat8bppAlpha; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat16bppGray: pixelFormat = GUID_WICPixelFormat16bppGray; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat24bppRGB: pixelFormat = GUID_WICPixelFormat24bppRGB; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat24bppBGR: pixelFormat = GUID_WICPixelFormat24bppBGR; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppBGR: pixelFormat = GUID_WICPixelFormat32bppBGR; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppBGRA: pixelFormat = GUID_WICPixelFormat32bppBGRA; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppPBGRA: pixelFormat = GUID_WICPixelFormat32bppPBGRA; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppGrayFloat: pixelFormat = GUID_WICPixelFormat32bppGrayFloat; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppRGBA: pixelFormat = GUID_WICPixelFormat32bppRGBA; break;
    case com_sun_javafx_font_directwrite_OS_GUID_WICPixelFormat32bppPRGBA: pixelFormat = GUID_WICPixelFormat32bppPRGBA; break;
    }

    HRESULT hr = ((IWICImagingFactory *)arg0)->CreateBitmap(arg1, arg2, (REFWICPixelFormatGUID)pixelFormat, (WICBitmapCreateCacheOption)arg4, &result);
    return SUCCEEDED(hr) ? (jlong)result : NULL;
}

It seems that arg0 is the likely cantidate for being null, and that is a pointer to the IWICImagingFactory instance, which should be set by the following method:

private static final native long _WICCreateImagingFactory();

which is implemented as native code in directwrite.cpp thusly:

JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
    (JNIEnv *env, jclass that)
{
    /* This routine initialize COM in order to create an WICImagingFactory.
     * It runs on the prism thread and expects no other codes in this thread
     * to interface with COM.
     * Note: This method is called by DWFactory a single time.
     */
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    /* This means COM has been initialize with a different concurrency model.
     * This should never happen. */
    if (hr == RPC_E_CHANGED_MODE) return NULL;

    IWICImagingFactory* result = NULL;
    hr = CoCreateInstance(
            CLSID_WICImagingFactory,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_PPV_ARGS(&result)
            );

    /* Unload COM as no other COM objects will be create directly */
    CoUninitialize();
    return SUCCEEDED(hr) ? (jlong)result : NULL;

I will try and investigate further.

Edit: I found something kind of interesting with regards to CLSID_WICImagingFactory https://github.com/google/skia/blob/master/src/ports/SkImageGeneratorWIC.cpp#L12 - but I have no idea if that would apply in our case or not.

Also, is it reliable to trust the java backtrace in the crash report, or is the native backtrace more reliable?

Piggy-backing off your comment @kevinrushforth - is there any chance you could be more specific? Is it that Monocle needs to initialize something with respect to DirectWrite that is only being initialized by Glass?

Edit 2: I don't think CLSID_WICImagingFactory has anything to do with it, because we explicitly set WIN32_WINNT=0x0601 which targets Windows 7 APIs, not 8+.

I'm working on compiling OpenJFX locally on my Windows development machine, but for some reason the first build is taking hours upon hours (seems to be stalling at :graphics:buildModuleWin). I am at least creating a simple build script that can be used when working locally on Windows to build without setting any environment variables, etc. Are there any such scripts that you guys at Oracle use internally when working on OpenJFX that are not in this repository, or is the configuration of the machines that you run builds on somehow standardized?

Edit 3: Got a first successful local build of OpenJFX. I don't have cygwin installed, so I think the docs are incorrect in requiring Cygwin. It may only be working because I have WSL installed, though. Anyways, to compile locally I had to make some very small tweaks to the gradle build file, and I also created a powershell script that may be useful for others, I will open a PR for that soon-ish.

brcolow commented 6 years ago

Alright, I was able to debug using a locally built JavaFX and Visual Studio 2017 Community:

javafx_font.dll!Java_com_sun_javafx_font_directwrite_OSCreateBitmap(JNIEnv env=0x000001f2e1ec3a70, _jclass that=0x0000003f492fd0e8, __int64 arg0=2142694496368, long arg1=256, long arg2=256, long arg3=8, long arg4=1) Line 2359 at c:\users\brcolow\dev\openjdk-jfx\modules\javafx.graphics\src\main\native-font\directwrite.cpp(2359)

The crash happens on this line:

HRESULT hr = ((IWICImagingFactory *)arg0)->CreateBitmap(arg1, arg2, (REFWICPixelFormatGUID)pixelFormat, (WICBitmapCreateCacheOption)arg4, &result);

Dissasembly:

call qword ptr [rax+88] <--- I believe this is calling the function CreateBitmap on arg0

result is highlighted red in the local variables table, though (meaning it's null - hence the illegal access exception I believe):

  Name Value Type
result 0x0000000000000000 IWICBitmap *

The docs for CreateBitmap are https://docs.microsoft.com/en-us/windows/desktop/api/wincodec/nf-wincodec-iwicimagingfactory-createbitmap

It seems it is normal to call CreateBitmap in this way, so perhaps it is that the CreateBitmap call itself is returning null? Perhaps that is the missing initialization that you referred to, Kevin. I'm not sure how to tell the difference between result being null and the method returning a null pointer. I will dig in deeper with the debugger and try and get to the bottom of what exactly is the problem. I have never debugged native code before, so it's a learning process for me.

Just wanted to post my progress, will update as I get more information.

Debugger screenshot:

javafx native crash

brcolow commented 6 years ago

The changes in this commit seem to stop the crash for me (unless for some bewitching reason logging statements are having some effect or maybe after a couple tries without restarting it works?):

https://github.com/brcolow/openjdk-jfx/commit/29c01b9b1852c5a4beaaae13ebbcec990ac7d78d

but I can't easily tell because compilation takes so long. If someone could test it with the changes (@kevinrushforth @ararunprasad ) and LMK if I'm seeing an apparition or not, that would be much appreciated. Then we could narrow down which change it is.

brcolow commented 6 years ago

I was able to prevent the crash with only the following change to directwrite.cpp:

JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
    (JNIEnv *env, jclass that)
{
    /* This routine initialize COM in order to create an WICImagingFactory.
     * It runs on the prism thread and expects no other codes in this thread
     * to interface with COM.
     * Note: This method is called by DWFactory a single time.
     */
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    /* This means COM has been initialize with a different concurrency model.
     * This should never happen. */
    if (hr == RPC_E_CHANGED_MODE) return NULL;

    IWICImagingFactory* result = NULL;
    hr = CoCreateInstance(
-           CLSID_WICImagingFactory
+           CLSID_WICImagingFactory1,
             NULL,
             CLSCTX_INPROC_SERVER,
             IID_PPV_ARGS(&result)
             );
+   if (hr == REGDB_E_CLASSNOTREG) {
+       hr = CoCreateInstance(
+               CLSID_WICImagingFactory,
+               NULL,
+               CLSCTX_INPROC_SERVER,
+               IID_PPV_ARGS(&result)
+               );
+    }

    /* Unload COM as no other COM objects will be create directly */
    CoUninitialize();
    return SUCCEEDED(hr) ? (jlong)result : NULL;
}

As soon as someone can re-produce the fix I'm seeing, I'll open a PR (I have a hard time believing it was this easy...).

kevinrushforth commented 6 years ago

@brcolow I can take a look early next week. As this is a P2 bug, we can still get a fix into openjfx 11 if a safe fix can be found.

brcolow commented 6 years ago

I'm not sure if https://ci.appveyor.com/project/brcolow/openjdk-jfx/build/master%20267?fullLog=true proves that it fixes the crash or not, because I'm not sure if text is ever rendered to the screen without -PUSE_ROBOT=true and -PFULL_TEST=true (both of which make the time be exceeded on Appveyor). So, I can only reproduce the fix locally.

brcolow commented 6 years ago

@kevinrushforth Do you think you will have time to take a look by tomorrow (Wednesday)? I know you are busy.

Or anyone else that can build OpenJFX locally on Windows - let me know (and save Kevin the work!).

kevinrushforth commented 6 years ago

I hope so... I'll put it on my list of reviews for tomorrow.

kevinrushforth commented 6 years ago

I ran a quick test, and it still crashes for me.

brcolow commented 6 years ago

Huh...interesting. Okay, thanks. I will look more deeply into this.

brcolow commented 6 years ago

@kevinrushforth

Check out this build which crashes (which only has the small changeset I mentioned above):

https://ci.appveyor.com/project/brcolow/openjdk-jfx/build/monocle-sw-font-crash%20268?fullLog=true#L22477

Now compare that to this build, with the same test (no crash there, and indeed no where on any other tests):

https://ci.appveyor.com/project/brcolow/openjdk-jfx/build/monocle-sw-font-crash%20272?fullLog=true#L22977

So it seems that the full changes (those in this PR):

https://github.com/brcolow/openjdk-jfx/pull/7

Are enough to stop the crash, probably at the expense of a memory leak as I mentioned earlier. Can you confirm? Thanks.

Edit: I messed up the PR I linked to, there are too many changes, let me fix that. Edit 2: Fixed.

kevinrushforth commented 6 years ago

I can confirm that with the patched referenced above, it does not crash. The only difference between that and the patch I tried last night was the following:

     /* Unload COM as no other COM objects will be create directly */
-    CoUninitialize();
+    //CoUninitialize();
     return SUCCEEDED(hr) ? (jlong)result : NULL;

This is an interesting observation that may lead to a solution, but is not something we would want to use directly.

brcolow commented 6 years ago

Yes, indeed. I was hoping it would provide the insight needed for someone who knows the Windows native code to arrive at a solution. If no such person exists, I will have to try and forge ahead with this but I am very much in the dark about DirectWrite/Windows Imaging Component/COM initialization/un-initialization and how that has anything to do with the SW renderer and Monocle.

How would we move the CoUninitialize method call into the JavaFX shutdown/cleanup code?

brcolow commented 6 years ago

Something that bugs me about this issue, that I am trying to find the answer to but the documentation on COM + Windows Imaging Component is pretty scarce is:

If COM is un-initialized (via CoUninitialize) is it expected that the IWICImagingFactory COM object that we created is going to go stale? In other words, is it the Monocle + SW renderer case that's working as intended (i.e. it should crash trying to access the IWICImagingFactory after COM un-initialization) and the D3D renderer + WinApplication is doing something different to somehow keep COM initialized and therefore access to IWICImagingFactory succeeds?

kevinrushforth commented 6 years ago

That's a good question, and seems worth exploring.

brcolow commented 6 years ago

Found something interesting by looking at the file history of directwrite.cpp (tracking it through various renames):

http://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/932cecc14e49#l9.1

CoUninitialize was once commented thusly:

CoUninitialize(); /* NOT COOL BUT SEEMS TO WORK */

This was changed and expounded upon by Felipe Heidrich, is he still at Oracle? Does anyone know how to get in touch?

I was trying to find the RT-32255 issue mentioned in the commit, but am having trouble finding it since the old bug system was merged with the JDK Jira.

brcolow commented 6 years ago

I think I have figured this out, or at least made progress towards that goal. When Monocle is not used the native WinApplication is created. The native _runLoop implementation in GlassApplication.cpp creates an OLEHolder:

/*
 * Class:     com_sun_glass_ui_win_WinApplication
 * Method:    _runLoop
 * Signature: (Ljava/lang/Runnable;)V
 */
JNIEXPORT void JNICALL Java_com_sun_glass_ui_win_WinApplication__1runLoop
  (JNIEnv * env, jobject self, jobject jLaunchable)
{
    OLEHolder _ole_

    // ...
    MSG msg;
    while (GlassApplication::GetInstance() && ::GetMessage(&msg, NULL, 0, 0) > 0) {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
    // ...

}

This OLE holder will be visible for the entire time the JavaFX application is running. The OLEHolder is defined as a struct in OleUtils.h thusly:

struct OLEHolder
{
    OLEHolder()
    : m_hr(::OleInitialize(NULL))
    {
        if (SUCCEEDED(m_hr)) {
            STRACE(_T("{OLE"));
        }
    }

    ~OLEHolder(){
        if (SUCCEEDED(m_hr)) {
            ::OleUninitialize();
            STRACE(_T("}OLE"));
        }
    }
    operator bool() const { return TRUE==SUCCEEDED(m_hr); }
    HRESULT m_hr;
};

What does this have to do with anything? Well, according to the docs OleInitialize calls CoInitializeEx, which is the COM initialization. Therefore, when using the native glass Windows application, COM remains initialized the whole time the application is running. Which explains why :

CoUninitialize(); /* NOT COOL BUT SEEMS TO WORK */ was indeed true, given that the person who wrote that was most likely testing using the native glass Windows "toolkit".

When WinApplication is not created, and instead MonocleApplication is used, there is no extra OLE/COM initialization and so when directwrite.cpp calls CoUninitialize(); the IWICImagingFactory pointer starts pointing to garbage. COM should not be uninitialized until we are sure that no objects instantiated by COM are going to be called. The safest thing would perhaps be to initialize COM on demand (as we are doing), and just call into native Windows code (perhaps by creating a windows directory in native-glass/monocle/) at the end of MonocleApplication.runLoop which un-initializes COM. What are your thoughts on that approach?

brcolow commented 6 years ago

Here is a very rough proof of concept of the idea I outlined briefly in my last comment. Basically, introduce a native windows library for monocle and use it to shut-down COM when the application is exiting. I can't think of any way to be able to check on the Monocle side of things if the DirectWrite factory has initialized the WIC factory (given that getWICFactory has default visibility, and I doubt we want to change that) so, on Windows at least, an unnecessary call (if in fact the WIC factory was never initialized, which could happen depending on an application's usage of fonts) on shutdown to un-initialize COM should be harmless enough.

The current approach is to add a check to HeadlessPlatform (the only possible monocle platform on Windows) to see if we are on Windows and if so, call a native _shutdown method. It may make more sense to make a new class, HeadlessWindowsPlatform, that extends from HeadlessPlatform and implements the COM un-initialize on shutdown. Then we could have HeadlessPlatformFactory return an instance of it if PlatformUtils.isWindows is true. Not sure how else to do it, really.

Currently the code will not compile, I just want to get the idea of my approach more concrete, and you can let me know what you think.

The most direct way to fix this, in my opinion, is to have monocle shut down COM when the application is shutting down. Currently we don't have any native libraries on Windows for monocle, so that complicates the fix.

The changes to appveyor.yml are only temporary to ensure that the approach actually works, and will be reverted. The change to include monocle by default on Windows (WIN.includeMonocle = true;) is something that would be really nice to have for TestFX purposes at least (and including it by default on Windows should make no difference to JavaFX users because actually having JavaFX use Monocle requires glass.platform=Monocle to be set). Additionally, Monocle to be included on Linux and macOS as well, so that eventually we can stop packaging a separate library for this purpose. But, we can discuss the default inclusion of Monocle separately from this issue, if you prefer.

brcolow commented 6 years ago

I realized that it isn't feasible to use the variants gradle feature because only one can be used at a time (either glass or glass_monocle), so I think I would have to either:

1.) Add a new nativeTarget for Windows builds for a new native library (maybe called monocle_win.dll or something) 2.) Add the CoUninitialize function to an already existing native library, but then how to access it from Monocle?

I think I have the problem debugged, just unclear about the approach to take.

kevinrushforth commented 6 years ago

If it turns out that you really do need a native utility method that is called by Monocle (I'm not yet sure about that), then adding a native method to call CoUninitialize should be pretty straight-forward.

I do not like the first approach. It seems overkill to create a native library for Monocle just for this. We faced a similar issue for the javafx.swing module and ended up using an existing library in javafx.graphics. Presuming that you put your native method in glass.dll, which is the obvious choice if using an existing library, the only thing you would need to enable accessing it from Monocle is this one statement in the initialization code, from within a doPrivileged:

NativeLibLoader.loadLibrary("glass");

You can look here for the pattern used by javafx.swing. Note that in the case of javafx.swing, the load method was added to a utility class in javafx.graphics. Since Monocle is already in the javafx.graphics module, your utility method can be co-located in the class that has the native method.

My bigger concern in all of this isn't what happens in the Monocle case. We don't ship the Monocle classes, so only developers who explicitly build and enable it will ever run in this mode. I'm more worried about any changes that could effect the normal Glass / D3D pipeline mode of operation. In that normal case, we need to ensure that removing the call to CoUninitialize will not have any negative effects.

brcolow commented 6 years ago

The theory I am operating under is that CoUninitialize should never have been called that early. The IWICImagingFactory was still used by the time it was called. The only reason that it ever worked was that COM stayed initialized on that thread because of the COM life-cycle in WinApplication runLoop. In order to make this movie from a theory to an assertion, we really need someone who knows about COM to chime in. Do you know of anyone that could give us a sanity check on this assumption?

I agree with the approach you mention. I will work on that.

brcolow commented 6 years ago

One thing that would be useful, in case we can't find someone who has COM expertise, would be to look at the private changelog (before JavaFX was open-sourced) and see when the CoUninitialize() method call was added. Was it at the same time as CoInitializeEx? Was it always commented with the NOT COOL comment? I would love to dig deeper on my end, but the history only goes back so far.

brcolow commented 6 years ago

I came up with a new approach that doesn't make any changes to Monocle. Instead, we use a disposer mechanism with IWICImagingFactory and we have it's dispose method call the native method that un-initializes COM. Here is that approach.

brcolow commented 6 years ago

I believe my assumption about COM staying initialized because of WinApplication's OLEInitialize was wrong because the initializations happen on different threads and the threading mode is set to single, apartment based threading. Unless Windows is doing something tricky like keeping COM objects alive because the parent (which is our case, I believe, as OLEInitialize is called from the main application thread provided by Windows) thread still has COM initialized, this was probably a false assumption.

brcolow commented 6 years ago

Quick sanity check: does it even make sense that with prism.order=sw and glass.platform=Monocle that SWGraphics creates DWGlyphs (that is, DirectWrite glyphs)? I mean, why should DirectWrite be used at all when using the SW renderer in headless mode? Shouldn't it instead use some sort of "software-only" (that is, not GL or D2D,D3D) font renderer?

kevinrushforth commented 6 years ago

The Windows native font rendering relies on DirectWrite, so yes, DWGlyphs are needed even in SW headless mode.

pyokagan commented 5 years ago

Hi @brcolow , I've been taking a look at this issue as well.

The theory I am operating under is that CoUninitialize should never have been called that early. The IWICImagingFactory was still used by the time it was called.

I'm no expert in COM either, but I do suspect that this is correct reason.

The crash occurs at:

000007FED842448F  call        qword ptr [rax+88h] 

with an access violation from reading the memory location rax + 88h. rax contains the vtable location (The value of ((IWICImagingFactory *)arg0)->__vfptr), so my hypothesis is that the location where the vtable resided became unmapped.

To confirm my hypothesis, I stepped through _1WICCreateImagingFactory in the debugger:

    IWICImagingFactory* result = NULL;
    hr = CoCreateInstance(
            CLSID_WICImagingFactory,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_PPV_ARGS(&result)
            );

capture

At this point, result pointer to a valid instance of IWICImagingFactory, and its vtable was located at WindowsCodecs.dll!0x000007fefa037020, which leads me to guess that WindowsCodecs.dll was somehow unloaded, perhaps by CoUninitialize().

Comparing the list of loaded DLLs before and after the CoUninitialize() call confirms my suspicion:

$ diff before.txt  after.txt
89d88
< WindowsCodecs.dll     WindowsCodecs.dll       C:\Windows\System32\WindowsCodecs.dll   N/A     No      Cannot find or open the PDB file.               95   6.2.9200.21830 (win8_ldr.160407-0600)    8/4/2016 1:57 AM        000007FEFA010000-000007FEFA171000       [8416] java.exe

Which means that the DLL WindowsCodecs.dll was unloaded by the CoUninitialize() call.

I believe my assumption about COM staying initialized because of WinApplication's OLEInitialize was wrong because the initializations happen on different threads and the threading mode is set to single, apartment based threading.

I don't think this disproves the hypothesis. The COM initialization on the other thread may cause it to hold a reference to WindowsCodecs.dll, and since DLL reference counts are process-wide, WindowsCodecs.dll is thus not unloaded when CoUninitialize() is called.

brcolow commented 5 years ago

@pyokagan Really glad to get someone else involved in this. So is it the case that with Monocle WinApplication's OLEInitialize is never called and therefore, when COM is uninitialized in directwrite.cpp, the DLL reference count for WindowsCodecs.dll goes to 0 and thus IWICImagingFactory becomes garbage and the only reason that the early un-initialization of COM worked before was because WinApplication's OLEInitialize kept the reference count non-zero and thus IWICImagingFactory was never invalidated?

Do you have any ideas about the best fix for this issue? That is, what would be the best way to un-initialize COM at the right time? I tried using a disposer mechanism but it didn't seem to work. We could un-initialize COM at application shutdown, but that seems a bit heavy-handed.

pyokagan commented 5 years ago

@brcolow

Really glad to get someone else involved in this. So is it the case that with Monocle WinApplication's OLEInitialize is never called and therefore, when COM is uninitialized in directwrite.cpp, the DLL reference count for WindowsCodecs.dll goes to 0 and thus IWICImagingFactory becomes garbage and the only reason that the early un-initialization of COM worked before was because WinApplication's OLEInitialize kept the reference count non-zero and thus IWICImagingFactory was never invalidated?

Yes, that's the gist of it. In fact, we can actually confirm this by attaching windbg to the process to look at the load counts of loaded DLLs.

At the point just before CoUninitialize() is called, when we are not using monocle, the load count of WindowsCodecs.dll is 2:

capture3

Whereas when we are using monocle, the load count of WindowsCodecs.dll is 1:

capture4

So this is very likely what is happening. Indeed, CoUninitialize() should not have been called that early, and the only reason the non-monocle case doesn't crash is just a happy accident.

Do you have any ideas about the best fix for this issue? That is, what would be the best way to un-initialize COM at the right time? I tried using a disposer mechanism but it didn't seem to work.

Are you referring to https://github.com/brcolow/openjdk-jfx/pull/10/files ? I don't quite understand what's going on in the diff unfortunately :confused: I can't really see where the disposer mechanism is being used.

We could un-initialize COM at application shutdown, but that seems a bit heavy-handed.

I'm not familiar enough with the codebase to be able to make a confident suggestion, but from what I can tell the lifetime of IWICImagingFactory is tied to the lifetime of the QuantumRenderer thread? In that case I suppose the correct thing to do would be to call CoUninitialize() when the QuantumRenderer thread is shutting down, if IWICImagingFactory was previously initialized. Something like this?

diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/FontFactory.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/FontFactory.java
index 46100cd..05271e6 100644
--- a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/FontFactory.java
+++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/FontFactory.java
@@ -132,4 +132,6 @@ public interface FontFactory {
                                      float size, boolean register, boolean all);

     public boolean isPlatformFont(String name);
+
+    public void dispose();
 }
diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java
index 3717d74..e68f0b9 100644
--- a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java
+++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java
@@ -2002,4 +2002,7 @@ public abstract class PrismFontFactory implements FontFactory {

     /* Called from PrismFontFile which caches the return value */
     static native short getSystemLCID();
+
+    @Override
+    public void dispose() {}
 }
diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWFactory.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWFactory.java
index 431eb58..2e3f7a0 100644
--- a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWFactory.java
+++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWFactory.java
@@ -133,4 +133,14 @@ public class DWFactory extends PrismFontFactory {
         }
         return D2D_FACTORY;
     }
+
+    @Override
+    public synchronized void dispose() {
+        checkThread();
+        if (WIC_FACTORY != null) {
+            OS.WICDestroyImagingFactory();
+            WIC_FACTORY = null;
+        }
+        super.dispose();
+    }
 }
diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/OS.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/OS.java
index d49149e..d84119d 100644
--- a/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/OS.java
+++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/OS.java
@@ -175,6 +175,11 @@ class OS {
         return ptr != 0 ? new IWICImagingFactory(ptr) : null;
     }

+    private static final native void _WICDestroyImagingFactory();
+    static final void WICDestroyImagingFactory() {
+        _WICDestroyImagingFactory();
+    }
+
     private static final native long _NewJFXTextAnalysisSink(char[] text,
                                                              int start,
                                                              int length,
diff --git a/modules/javafx.graphics/src/main/java/com/sun/prism/GraphicsPipeline.java b/modules/javafx.graphics/src/main/java/com/sun/prism/GraphicsPipeline.java
index f10d819..31991a8 100644
--- a/modules/javafx.graphics/src/main/java/com/sun/prism/GraphicsPipeline.java
+++ b/modules/javafx.graphics/src/main/java/com/sun/prism/GraphicsPipeline.java
@@ -59,6 +59,10 @@ public abstract class GraphicsPipeline {

     public abstract boolean init();
     public void dispose() {
+        if (fontFactory != null) {
+            fontFactory.dispose();
+            fontFactory = null;
+        }
         installedPipeline = null;
     }

diff --git a/modules/javafx.graphics/src/main/java/com/sun/prism/j2d/J2DFontFactory.java b/modules/javafx.graphics/src/main/java/com/sun/prism/j2d/J2DFontFactory.java
index 21a1647..6e1c9fc 100644
--- a/modules/javafx.graphics/src/main/java/com/sun/prism/j2d/J2DFontFactory.java
+++ b/modules/javafx.graphics/src/main/java/com/sun/prism/j2d/J2DFontFactory.java
@@ -237,4 +237,7 @@ final class J2DFontFactory implements FontFactory {

         return srcFont;
     }
+
+    @Override
+    public void dispose() {}
 }
diff --git a/modules/javafx.graphics/src/main/native-font/directwrite.cpp b/modules/javafx.graphics/src/main/native-font/directwrite.cpp
index 96e751c..8507109 100644
--- a/modules/javafx.graphics/src/main/native-font/directwrite.cpp
+++ b/modules/javafx.graphics/src/main/native-font/directwrite.cpp
@@ -867,11 +867,14 @@ JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
             IID_PPV_ARGS(&result)
             );

-    /* Unload COM as no other COM objects will be create directly */
-    CoUninitialize();
     return SUCCEEDED(hr) ? (jlong)result : NULL;
 }

+JNIEXPORT void JNICALL OS_NATIVE(_1WICDestroyImagingFactory) (JNIEnv *env, jclass that)
+{
+    CoUninitialize();
+}
+
 JNIEXPORT jlong JNICALL OS_NATIVE(_1D2D1CreateFactory)
     (JNIEnv *env, jclass that, jint arg0)
 {
brcolow commented 5 years ago

@pyokagan LGTM. You want to open a PR for that?

pyokagan commented 5 years ago

@brcolow On second thought, I'm not so confident in that solution, since it is fairly intrusive by adding a new dispose() method to the FontFactory interface, which all implementing classes would then need to implement. It's also hard to do right, there are some instances in the codebase where the FontFactory is retrieved and then saved in an instance field:

https://github.com/javafxports/openjdk-jfx/blob/5b7bd51b3f41ae7fb12ee931f45839502e26256d/modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontLoader.java#L262-L277

I do get the feeling that FontFactory is meant to outlive the QuantumRenderer thread, and so it's perhaps best not to violate this design.


I have an alternate solution, which is much less intrusive. Fibre local storages allow us to call callbacks on thread exit, so perhaps we could use it to call CoUninitialize() when the QuantumRender thread exits?

diff --git a/modules/javafx.graphics/src/main/native-font/directwrite.cpp b/modules/javafx.graphics/src/main/native-font/directwrite.cpp
index 96e751c75d..cfbfca558a 100644
--- a/modules/javafx.graphics/src/main/native-font/directwrite.cpp
+++ b/modules/javafx.graphics/src/main/native-font/directwrite.cpp
@@ -845,6 +845,11 @@ jobject newD2D1_MATRIX_3X2_F(JNIEnv *env, D2D1_MATRIX_3X2_F *lpStruct)
 /*                                                                        */
 /**************************************************************************/

+static void coUninitializeCallback(void *data)
+{
+    CoUninitialize();
+}
+
 JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
     (JNIEnv *env, jclass that)
 {
@@ -859,6 +864,12 @@ JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
      * This should never happen. */
     if (hr == RPC_E_CHANGED_MODE) return NULL;

+    /* Setup a fibre local storage slot to call coUninitializeCallback() on thread exit. */
+    DWORD flsindex = FlsAlloc(coUninitializeCallback);
+    if (flsindex == FLS_OUT_OF_INDEXES) return NULL;
+    /* A non-NULL value must be set so that the callback will be called on thread exit. */
+    FlsSetValue(flsindex, (void*)1);
+
     IWICImagingFactory* result = NULL;
     hr = CoCreateInstance(
             CLSID_WICImagingFactory,
@@ -867,8 +878,6 @@ JNIEXPORT jlong JNICALL OS_NATIVE(_1WICCreateImagingFactory)
             IID_PPV_ARGS(&result)
             );

-    /* Unload COM as no other COM objects will be create directly */
-    CoUninitialize();
     return SUCCEEDED(hr) ? (jlong)result : NULL;
 }

The advantage of this approach is that the changes are very small and entirely localized within directwrite.cpp. FlsAlloc is a pretty exotic API though (and only available on Windows Vista and up), I'm not sure if this would cause any trouble.


Alternatively, perhaps we could just remove the CoUninitialize() call? Since IWICImagingFactory is only created once in the entire lifetime of the process, any leaks should not be that bad...

Any thoughts?

brcolow commented 5 years ago

I really like the all-native solution - I think that's really clever. I was looking for something like that in the Windows API but didn't find it. IIRC JavaFX only supports Windows Vista and up so that shouldn't be a problem. Removing the call to CoUninitialize would indeed only introduce a really small leak (if the OS didn't automatically take care of it when the process is wholly terminated) but I think Kevin would be hesitant to approve a leaky solution.

brcolow commented 5 years ago

Would you have time to open a PR for the solution? It will require filling out the Oracle Contributor Agreement (OCA). It is your solution so you should get credit 👍. After doing a little more research the Fiber-Local Storage API is a really good choice. I think it is only being used in it's thread-local storage capacity because no fibers are created. Because the thread-local storage API is older and harder to work with (not so easy to set a callback on thread exit), and because on newer versions TLS functions are in-lined to FLS functions, I think it's a wise choice and not too exotic.

pyokagan commented 5 years ago

@brcolow

Would you have time to open a PR for the solution?

OK I'll work on it.

pyokagan commented 5 years ago

Just to complete the picture, this is the stacktrace of the other callsite that loads WindowsCodecs.dll the second time in the non-monocle case:

ModLoad: 00007ffa`ca180000 00007ffa`ca32e000   C:\Windows\SYSTEM32\WindowsCodecs.dll
 # Child-SP          RetAddr           Call Site
00 00000003`955f9148 00007ffa`d1a2bea5 ntdll!NtMapViewOfSection+0x14
01 00000003`955f9150 00007ffa`d1a2bbf0 ntdll!LdrpMinimalMapModule+0xed
02 00000003`955f91d0 00007ffa`d1a432ce ntdll!LdrpMapDllWithSectionHandle+0x14
03 00000003`955f9230 00007ffa`d1a4231a ntdll!LdrpMapDllNtFileName+0x18a
04 00000003`955f9300 00007ffa`d1a4276b ntdll!LdrpMapDllSearchPath+0x1de
05 00000003`955f9560 00007ffa`d1a383da ntdll!LdrpProcessWork+0x83
06 00000003`955f95d0 00007ffa`d1a41a3d ntdll!LdrpLoadDllInternal+0x13e
07 00000003`955f9650 00007ffa`d1a418b6 ntdll!LdrpLoadForwardedDll+0x129
08 00000003`955f9960 00007ffa`d1a0f387 ntdll!LdrpGetDelayloadExportDll+0xa2
09 00000003`955f9a70 00007ffa`d1a22d96 ntdll!LdrpHandleProtectedDelayload+0x87
0a 00000003`955fa030 00007ffa`c7845871 ntdll!LdrResolveDelayLoadedAPI+0xc6
0b 00000003`955fa0c0 00007ffa`c784d24f COMCTL32!_delayLoadHelper2+0x31
0c 00000003`955fa100 00007ffa`c781e853 COMCTL32!_tailMerge_windowscodecs_dll+0x3f
0d 00000003`955fa170 00007ffa`c7820315 COMCTL32!CImageList::Initialize+0x253
0e 00000003`955fa220 00007ffa`d02b0525 COMCTL32!CSparseImageList::Initialize+0x55
0f 00000003`955fa270 00007ffa`d02b155a SHELL32!_InitSysImageLists+0xd5
10 00000003`955fa330 00007ffa`d04079e9 SHELL32!FileIconInitInternal+0x2ba
11 00000003`955fa3e0 00007ffa`d0408a85 SHELL32!_InitDragHelper+0x19
12 00000003`955fa410 00007ffa`cfc4a6d1 SHELL32!CDragDropHelper_CreateInstance+0x15
13 00000003`955fa440 00007ffa`cfc5844f combase!CServerContextActivator::CreateInstance+0x201 [onecore\com\combase\objact\actvator.cxx @ 878] 
14 00000003`955fa5c0 00007ffa`cfc481c1 combase!ActivationPropertiesIn::DelegateCreateInstance+0xef [onecore\com\combase\actprops\actprops.cxx @ 1906] 
15 00000003`955fa650 00007ffa`cfc4af22 combase!CApartmentActivator::CreateInstance+0xc1 [onecore\com\combase\objact\actvator.cxx @ 2169] 
16 00000003`955fa700 00007ffa`cfc4ac80 combase!CProcessActivator::CCICallback+0x72 [onecore\com\combase\objact\actvator.cxx @ 1637] 
17 00000003`955fa740 00007ffa`cfc4ad3e combase!CProcessActivator::AttemptActivation+0x40 [onecore\com\combase\objact\actvator.cxx @ 1524] 
18 00000003`955fa790 00007ffa`cfc4b26b combase!CProcessActivator::ActivateByContext+0xae [onecore\com\combase\objact\actvator.cxx @ 1368] 
19 00000003`955fa820 00007ffa`cfc5840d combase!CProcessActivator::CreateInstance+0x8b [onecore\com\combase\objact\actvator.cxx @ 1268] 
1a 00000003`955fa870 00007ffa`cfc55dda combase!ActivationPropertiesIn::DelegateCreateInstance+0xad [onecore\com\combase\actprops\actprops.cxx @ 1906] 
1b 00000003`955fa900 00007ffa`cfc58417 combase!CClientContextActivator::CreateInstance+0x14a [onecore\com\combase\objact\actvator.cxx @ 567] 
1c 00000003`955fabb0 00007ffa`cfc5fa28 combase!ActivationPropertiesIn::DelegateCreateInstance+0xb7 [onecore\com\combase\actprops\actprops.cxx @ 1958] 
1d 00000003`955fac40 00007ffa`cfc5ee79 combase!ICoCreateInstanceEx+0xa38 [onecore\com\combase\objact\objact.cxx @ 1959] 
1e 00000003`955fbac0 00007ffa`cfc5ec83 combase!CComActivator::DoCreateInstance+0x169 [onecore\com\combase\objact\immact.hxx @ 385] 
*** WARNING: Unable to verify checksum for \openjdk-jfx\build\sdk\bin\glass.dll
1f (Inline Function) --------`-------- combase!CoCreateInstanceEx+0x88 [onecore\com\combase\objact\actapi.cxx @ 177] 
20 00000003`955fbbe0 00007ffa`ae2d655e combase!CoCreateInstance+0xc3 [onecore\com\combase\objact\actapi.cxx @ 121] 
21 00000003`955fbc80 00007ffa`ae2eb2cf glass!GlassDropTarget::GlassDropTarget+0x9e [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\glassdnd.cpp @ 44] 
22 00000003`955fbce0 00007ffa`ae2dee16 glass!ViewContainer::InitDropTarget+0x4f [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\viewcontainer.cpp @ 109] 
23 00000003`955fbd50 00007ffa`ae2e4e7a glass!GlassWindow::Create+0x126 [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\glasswindow.cpp @ 154] 
24 00000003`955fbde0 00007ffa`ae2e3cb3 glass!`Java_com_sun_glass_ui_win_WinWindow__1createWindow'::`2'::_MyAction::_UserDo+0x26a [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\glasswindow.cpp @ 1270] 
25 00000003`955fbea0 00007ffa`ae2bf17b glass!`Java_com_sun_glass_ui_win_WinWindow__1createWindow'::`2'::_MyAction::Do+0x13 [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\glasswindow.cpp @ 1220] 
26 00000003`955fbed0 00007ffa`ae2b1814 glass!GlassApplication::WindowProc+0xcb [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\glassapplication.cpp @ 150] 
27 00000003`955fbf40 00007ffa`d1726d41 glass!BaseWnd::StaticWindowProc+0xa4 [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\basewnd.cpp @ 162] 
28 00000003`955fbfa0 00007ffa`d172634e USER32!UserCallWinProcCheckWow+0x2c1
29 00000003`955fc130 00007ffa`d17260d8 USER32!SendMessageWorker+0x21e
2a 00000003`955fc1c0 00007ffa`ae2bea87 USER32!SendMessageW+0xf8
2b 00000003`955fc220 00007ffa`ae2e2280 glass!GlassApplication::ExecAction+0x37 [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\glassapplication.cpp @ 288] 
2c 00000003`955fc250 000001ee`e13ef0b7 glass!Java_com_sun_glass_ui_win_WinWindow__1createWindow+0x60 [\openjdk-jfx\modules\javafx.graphics\src\main\native-glass\win\glasswindow.cpp @ 1297] 
2d 00000003`955fc2c0 000001ee`fdadeb40 0x000001ee`e13ef0b7
2e 00000003`955fc2c8 00000003`955fc3a0 0x000001ee`fdadeb40
2f 00000003`955fc2d0 00000000`00000000 0x00000003`955fc3a0
DagmarS commented 5 years ago

Hi! I have the same problem with headless TestFX Unit Tests and open jdk 11 on a Windows 10 System

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffa1cb74879, pid=3804, tid=12072
#
# JRE version: OpenJDK Runtime Environment (11.0.1+13) (build 11.0.1+13)
# Java VM: OpenJDK 64-Bit Server VM (11.0.1+13, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C  [javafx_font.dll+0x4879]

Just for my understanding:

Will this be fixed in OpenJFX? Or is this an open jdk issue?

brcolow commented 5 years ago

This is the same bug - @pyokagan is currently working on a PR. He has already posted a fix above so hopefully the PR will be opened, reviewed, and merged soon. It won't get in till OpenJFX 13, but that's the way the cookie crumbles. Also there should be no major obstacles to upgrading JavaFX versions like there was from 9 -> 10 so it should be quite painless.

kevinrushforth commented 5 years ago

It won't get in till OpenJFX 13

There is still a little over 3 weeks to get bug fixes into OpenJFX 12, although it will likely take some time to review this.

Speaking of which, my first thought is that an explicit dispose method that hooks into the existing FontDisposer mechanism might be a better way to go, but I haven't looked in detail.

kevinrushforth commented 5 years ago

I took a closer look and the Disposer mechanism won't work, since the cleanup would be on a singleton factory object that is kept in a static field.

Presuming that the change to avoid calling CoUninitialize too early is the right fix (which seems likely), then I see three approaches:

  1. Add an explicit dispose method to FontFactory as @brcolow suggested above, and call it "at the right time", possibly by adding a Toolkit shutdown hook when the font factory is created. This will be called when the JavaFX runtime exits.

  2. Use a native-only solution as @pyokagan suggested (which is effectively a native shutdown hook).

  3. Remove the call to CoUninitalize altogether (this doesn't seem like a good idea).

I think I prefer option 1, even though it is a little more intrusive.

pyokagan commented 5 years ago

@kevinrushforth

Add an explicit dispose method to FontFactory as @brcolow suggested above, and call it "at the right time", possibly by adding a Toolkit shutdown hook when the font factory is created. This will be called when the JavaFX runtime exits.

If I'm reading the source code correctly, shutdown hooks (notifyShutdownHooks()) would only be called in the application thread.

https://github.com/javafxports/openjdk-jfx/blob/3ad2d3a0f767992f1b0d516caf864c7a6164c7fe/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java#L813-L837

CoUninitialize() needs to be called on the thread which called CoInitializeEx(), which in this case is the QuantumRenderer thread. This makes things significantly trickier. I guess the calling of the dispose method would need to be called by QuantumRenderer or GraphicsPipeline.

I have a patch in https://github.com/javafxports/openjdk-jfx/issues/66#issuecomment-450498291 which makes GraphicsPipeline call FontFactory#dispose(). I wan't so confident about the patch though, for the following reasons:

https://github.com/javafxports/openjdk-jfx/blob/3ad2d3a0f767992f1b0d516caf864c7a6164c7fe/modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontLoader.java#L262-L277

pyokagan commented 5 years ago

It also didn't seem right to me for FontFactory to have a dispose method, and GraphicsPipeline to call it, and it only having an effect for DTFactory and not for any of the other FontFactory implementations (CTFactory and FTFactory). (Should it dispose resources used by FontFiles as well, for example? thinking )

Scratch that, it doesn't need to be a full disposal method. It could be a simple notifyRelease() method which just notifies the FontFactory that the GraphicsPipeline is shutting down, and it is up to the FontFactory to perform whatever internal cleanup it deems necessary.

pyokagan commented 5 years ago

I think I prefer option 1, even though it is a little more intrusive.

Generally speaking I do think that option 1 would be more ideal as well, since it makes the cleanup more explicit (and not using an exotic Win32 API is a nice bonus).