JDK-6421149 : Application hangs creating fonts
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2006-05-03
  • Updated: 2011-05-18
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b03Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-beta2"
Java(TM) SE Runtime Environment (build 1.6.0-beta2-b80)
Java HotSpot(TM) Client VM (build 1.6.0-beta2-b80, mixed mode, sharing)

(also seen with various earlier 1.6.0 betas.)

ADDITIONAL OS VERSION INFORMATION :
Linux bertha 2.6.12-1-686-smp #1 SMP Tue Sep 27 13:10:31 JST 2005 i686 GNU/Linux

A DESCRIPTION OF THE PROBLEM :

i've seen crashes with different applications on different architectures
(x86 and amd64) on diffeerent physical machines using -- as best i can guess
from the contexts -- different fonts. i just saw b82 closed 6402537, and wonder if this could be a duplicate of
that?

sometimes an application will hang trying to get font metrics. i've seen this with a few applications, but here's an example chunk of stack trace (from jstack(1)):

"AWT-EventQueue-0" prio=10 tid=0x080e1c00 nid=0x3d90 runnable [0xb4aad000..0xb4aaeec0]
   java.lang.Thread.State: RUNNABLE
	at java.lang.Thread.isInterrupted(Native Method)
	at java.lang.Thread.isInterrupted(Thread.java:889)
	at java.nio.channels.spi.AbstractInterruptibleChannel.begin(AbstractInterruptibleChannel.java:153)
	at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:142)
	- locked <0x50120000> (a java.lang.Object)
	at sun.font.TrueTypeFont.readBlock(TrueTypeFont.java:305)
	- locked <0x54f7b4a8> (a sun.font.TrueTypeFont)
	at sun.font.TrueTypeFont.createScaler(Native Method)
	at sun.font.TrueTypeFont.getScaler(TrueTypeFont.java:1025)
	- locked <0x54f7b4a8> (a sun.font.TrueTypeFont)
	at sun.font.FileFontStrike.<init>(FileFontStrike.java:98)
	at sun.font.FileFont.createStrike(FileFont.java:74)
	at sun.font.Font2D.getStrike(Font2D.java:331)
	at sun.font.Font2D.getStrike(Font2D.java:262)
	at sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
	at sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)
	at sun.font.FontDesignMetrics.initMatrixAndMetrics(FontDesignMetrics.java:345)
	at sun.font.FontDesignMetrics.<init>(FontDesignMetrics.java:336)
	at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:284)
	at sun.swing.SwingUtilities2.getFontMetrics(SwingUtilities2.java:902)
	at javax.swing.JComponent.getFontMetrics(JComponent.java:1616)
	at javax.swing.plaf.synth.SynthGraphicsUtils.getPreferredSize(SynthGraphicsUtils.java:264)
	at javax.swing.plaf.synth.SynthGraphicsUtils.getMinimumSize(SynthGraphicsUtils.java:176)
	at javax.swing.plaf.synth.SynthLabelUI.getMinimumSize(SynthLabelUI.java:199)
	at javax.swing.JComponent.getMinimumSize(JComponent.java:1731)
	at javax.swing.BoxLayout.checkRequests(BoxLayout.java:436)
	at javax.swing.BoxLayout.preferredLayoutSize(BoxLayout.java:254)
	- locked <0x50120008> (a javax.swing.BoxLayout)
	at java.awt.Container.preferredSize(Container.java:1576)
	- locked <0x54f463a8> (a java.awt.Component$AWTTreeLock)
	at java.awt.Container.getPreferredSize(Container.java:1561)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1653)
	at javax.swing.JRootPane$RootLayout.preferredLayoutSize(JRootPane.java:860)
	at java.awt.Container.preferredSize(Container.java:1576)
	- locked <0x54f463a8> (a java.awt.Component$AWTTreeLock)
	at java.awt.Container.getPreferredSize(Container.java:1561)
	at javax.swing.JComponent.getPreferredSize(JComponent.java:1653)
	at java.awt.BorderLayout.preferredLayoutSize(BorderLayout.java:702)
	- locked <0x54f463a8> (a java.awt.Component$AWTTreeLock)
	at java.awt.Container.preferredSize(Container.java:1576)
	- locked <0x54f463a8> (a java.awt.Component$AWTTreeLock)
	at java.awt.Container.getPreferredSize(Container.java:1561)
	at java.awt.Window.pack(Window.java:558)
	at e.gui.AboutBox.makeUi(AboutBox.java:176)
	at e.gui.AboutBox.show(AboutBox.java:90)
	at e.gui.HelpMenu$AboutBoxAction.actionPerformed(HelpMenu.java:79)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1982)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2305)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:377)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:232)
	at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
	at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1137)
	at javax.swing.plaf.basic.BasicMenuItemUI$Handler.menuDragMouseReleased(BasicMenuItemUI.java:1241)
	at javax.swing.JMenuItem.fireMenuDragMouseReleased(JMenuItem.java:553)
	at javax.swing.JMenuItem.processMenuDragMouseEvent(JMenuItem.java:450)
	at javax.swing.JMenuItem.processMouseEvent(JMenuItem.java:396)
	at javax.swing.MenuSelectionManager.processMouseEvent(MenuSelectionManager.java:292)
	at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.eventDispatched(BasicPopupMenuUI.java:784)
	at java.awt.Toolkit$SelectiveAWTEventListener.eventDispatched(Toolkit.java:2358)
	at java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2250)
	at java.awt.Toolkit.notifyAWTEventListeners(Toolkit.java:2208)
	at java.awt.Component.dispatchEventImpl(Component.java:4285)
	at java.awt.Container.dispatchEventImpl(Container.java:2042)
	at java.awt.Component.dispatchEvent(Component.java:4217)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4246)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3910)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3840)
	at java.awt.Container.dispatchEventImpl(Container.java:2028)
	at java.awt.Window.dispatchEventImpl(Window.java:2297)
	at java.awt.Component.dispatchEvent(Component.java:4217)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at e.debug.EventDispatchThreadHangMonitor.dispatchEvent(EventDispatchThreadHangMonitor.java:192)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

strace(1) doesn't show any activity:

bertha:~$ strace -c -p 15746
Process 15746 attached - interrupt to quit
Process 15746 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                     0           total

and it looks like we're stuck:

bertha:~$ strace -p 15746
Process 15746 attached - interrupt to quit
futex(0xb7d95bf8, FUTEX_WAIT, 15747, NULL <unfinished ...>

jconsole(1) says no deadlock detected.

it usually happens when the application has already been running for a while. in this instance, the application had been running for over 4 hours.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
i don't have guaranteed steps to reproduce. i've been using Java 6 all day every day for a few weeks, and i've seen this four or five times.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
no hang
ACTUAL -
hang; quite a lot of CPU usage. attaching ltrace(1) to see what it was up to produced the following output and brought the CPU usage down to zero:

bertha:~$ ltrace -p 15746
--- SIGSTOP (Stopped (signal)) ---
--- SIGSTOP (Stopped (signal)) ---

jstack(1) now hangs, so i guess i've come to the end of my poking about here!

killing the process then dumped a lot of log output suggesting that it may have been making some very slow progress (or just giving a better idea of exactly where it's spinning):

2006-04-14T17:48:19.490-0700 Terminator: (hang #664) event dispatch thread stuck processing event for 108910 ms:
    sun.nio.ch.FileChannelImpl.position0(Native Method)
    sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:290)
    sun.font.TrueTypeFont.readBlock(TrueTypeFont.java:304)
    sun.font.TrueTypeFont.createScaler(Native Method)
    sun.font.TrueTypeFont.getScaler(TrueTypeFont.java:1025)
    sun.font.FileFontStrike.<init>(FileFontStrike.java:98)
    sun.font.FileFont.createStrike(FileFont.java:74)
    sun.font.Font2D.getStrike(Font2D.java:331)
    sun.font.Font2D.getStrike(Font2D.java:262)
    sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
    sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)
.
.
.
2006-04-14T17:48:19.591-0700 Terminator: (hang #665) event dispatch thread stuck processing event for 109011 ms:
    java.lang.Thread.isInterrupted(Native Method)
    java.lang.Thread.isInterrupted(Thread.java:889)
    java.nio.channels.spi.AbstractInterruptibleChannel.begin(AbstractInterruptibleChannel.java:153)
    sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:142)
    sun.font.TrueTypeFont.readBlock(TrueTypeFont.java:305)
    sun.font.TrueTypeFont.createScaler(Native Method)
    sun.font.TrueTypeFont.getScaler(TrueTypeFont.java:1025)
    sun.font.FileFontStrike.<init>(FileFontStrike.java:98)
    sun.font.FileFont.createStrike(FileFont.java:74)
    sun.font.Font2D.getStrike(Font2D.java:331)
    sun.font.Font2D.getStrike(Font2D.java:262)
    sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
    sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)
.
.
.
2006-04-14T17:48:19.692-0700 Terminator: (hang #666) event dispatch thread stuck processing event for 109112 ms:
    sun.nio.ch.FileChannelImpl.position0(Native Method)
    sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:290)
    sun.font.TrueTypeFont.readBlock(TrueTypeFont.java:304)
    sun.font.TrueTypeFont.createScaler(Native Method)
    sun.font.TrueTypeFont.getScaler(TrueTypeFont.java:1025)
    sun.font.FileFontStrike.<init>(FileFontStrike.java:98)
    sun.font.FileFont.createStrike(FileFont.java:74)
    sun.font.Font2D.getStrike(Font2D.java:331)
    sun.font.Font2D.getStrike(Font2D.java:262)
    sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
    sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)
    sun.font.FontDesignMetrics.initMatrixAndMetrics(FontDesignMetrics.java:345)
    sun.font.FontDesignMetrics.<init>(FontDesignMetrics.java:336)
    sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:284)
    sun.swing.SwingUtilities2.getFontMetrics(SwingUtilities2.java:902)
    javax.swing.JComponent.getFontMetrics(JComponent.java:1616)
.
.
.
2006-04-14T17:48:19.995-0700 Terminator: (hang #667) event dispatch thread stuck processing event for 109415 ms:
    java.lang.Thread.isInterrupted(Native Method)
    java.lang.Thread.isInterrupted(Thread.java:889)
    java.nio.channels.spi.AbstractInterruptibleChannel.begin(AbstractInterruptibleChannel.java:153)
    sun.nio.ch.FileChannelImpl.position(FileChannelImpl.java:285)
    sun.font.TrueTypeFont.readBlock(TrueTypeFont.java:304)
    sun.font.TrueTypeFont.createScaler(Native Method)
    sun.font.TrueTypeFont.getScaler(TrueTypeFont.java:1025)
    sun.font.FileFontStrike.<init>(FileFontStrike.java:98)
    sun.font.FileFont.createStrike(FileFont.java:74)
    sun.font.Font2D.getStrike(Font2D.java:331)
    sun.font.Font2D.getStrike(Font2D.java:262)
    sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
    sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)

et cetera.

REPRODUCIBILITY :
This bug can be reproduced occasionally.

Comments
EVALUATION Although the failure was not reproduced we have added code which resolves the most likely cause of the hang This was fixed in conjunction with the fix for 6359722 which added the code necessary to be able to return from a bad read safely. Code was also added to prevent the possible recursion in NativeFont.java
25-09-2006

EVALUATION There was an analysis to try to identify problems here. None were found. The original submitter was solicted for help. He could not reprodce the problem. Debugging classes supplied to him revealed nothing. At this point he was using a lightly later build of JDK 6 (Please note this was reported on an interim build of JDK 6 not any FCS/final build). There was some specculation that sme underlying VM build and perhaps OS updates whilt running where related. Nothing was proven. At this point this remains open only because even though the circumstances which might cause this seem impossible in normal operation we may ttry to add some recovery or at least diagnostic code. There was a note by a different user of a problem which may appear superficially similar : *************** I see a problem in 1.5 on debian sarge: .. Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at sun.font.NativeFont.createStrike(NativeFont.java:241) *************** But that appears not to be a bug but because the JDK has been corrupted and the entire jre/lib.fonts directory is missing. even then this would not be a problem except because the JRE was running on an unrecognised release it looks as if some (at least) fonts were found only via X11 such that the default font ended up being an X11 font. Ordinarily the default font is one in the jre/lib/fonts directory. So I note this here mainly because this bug was annotated with this symptom however it is not related to the main subject of this bug nor is it really a bug - corrupted JRE's cannot be expected to function normally.
04-08-2006

EVALUATION Here's the code from TrueTypeFont.readBlock() : while (bread != length) { disposerRecord.channel.position(offset+bread); // line 304 int cnt = disposerRecord.channel.read(buffer); // line 305 if (cnt == -1) { buffer.flip(); throw new IOException("unexpected EOF" + this); } bread += cnt; } The size of the ByteBuffer in use here is fixed so it doesn't seem likely we are asking for a huge amount of data that would take a long time to complete. The jstack traces make it look this loop is being repeated because we aren't getting any bytes read. I suspect that read() is either returning 1 byte at a time, or perhaps returning 0 (essentially blocking). So far as I can tell from FileChannel.read() docs 0 being returned just means it read no bytes into the buffer. If there were an error we'd expect an exception. I don't know what else the code should do to recover except to try again as it seems possible that returning 0 is occasionally possible but the circumstances aren't documented. This code hasn't changed since before 1.5 FCS - Oct 2003 was the last update here, so a problem that "started occuring" in 1.6 may point to a problem elsewhere in the runtime although 6402537 doesn't appear related to NIO or this bug.
03-05-2006