Bug on Font/FontMetrics (with a patch)

Maurizio De Cecco maurizio at mandrakesoft.com
Mon Apr 17 06:50:56 PDT 2000

I found the following problem (on kaffe 1.0.5, but apparently it applies also
to the current snap shot); the effect is quite catastrophic, random size
of text objects, memory corruption, potentially core dump ?

The bug is quite subtle, so forgive me if the explication is not 
as simple as i would like and feel free to ask me better explications :->


1) The Font class get a pointer to a native data representing the font,
thru the Toolkit native method fntInitFont; in the X implementation,
it will be a pointer a XFontStruct structure.

2) The Font finalize method call the fntFreeFont method, that in the X
implementation call XFreeFont, that actually free the XFontStruct

3) The FontMetrics class also have a pointer to native data describing
the font metrics, obtained thru the Toolkit method fntInitFontMetrics
called on the font native data; in the case of X windows, the font metric
information is *the same* XFontStruct object used in the Font.

4) The FontMetrics instances are stored in a cache; this cache use as key
the Font encoding string; as a result, the lifetime of a FontMetrics
instance in the cache is not related to the lifetime of a Font object,
and two Font instances referring to the same font name share the same FontMetrics

Given these fact, if the following happens:

a) A new Font instance is created, referring to a yet unused font.

b) The FontMetrics of this font is obtained with FontMetrics.getFontMetrics(Font f)

c) The Font instance is not used anymore, garbage collected, and the finalize method
   is actually called.

d) a new Font instance is created, with the same font as in a)

e) Then the FontMetrics of this new instance is obtained with FontMetrics.getFontMetrics(Font f).

Then: the fontmetrics object obtained in e) is the same instance obtained in b),
pointing to a XFontStruct structure that has been Freed in c).

As a result, all the font metrics operations will give inconsistent results 
(like -224532 points for a 4 character strings), and potentially can core
dump the virtual machine.

The patch is more a workaround than a solution; i am afraid the solution
must be more architectural and consistent with non-X Windows implementation
of the AWT; anyway, the following is a simple workaround that should
work just fine on X windows: i simply added a reference from a FontMetrics
instance to the Font instance used to build it; so the Font instance will
not be freed unless the FontMetrics is freed (that will not, because kept
in the static cache).


-- snip ------------------------------------------------------------------------------
diff -ru kaffe-1.0.5.orig/libraries/javalib/java/awt/FontMetrics.java kaffe-1.0.5/libraries/javalib/java/awt/FontMetrics.java
--- kaffe-1.0.5.orig/libraries/javalib/java/awt/FontMetrics.java	Mon Oct 18 07:24:13 1999
+++ kaffe-1.0.5/libraries/javalib/java/awt/FontMetrics.java	Mon Apr 17 14:51:23 2000
@@ -18,6 +18,16 @@
 public class FontMetrics
   implements java.io.Serializable
+        // We store the font because the font metrics
+        // depends on the native data maintained by the font
+        // in this way the original font object will not be
+        // finalized (and the native data freed).
+        // Note that since fontmetrics instances are cached
+        // their life span is higher than the Font object one.
+        // (Maurizio De Cecco maurizio at mandrakesoft.com).
+        Font font;  
 	transient Ptr nativeData;
 	protected String fontSpec;
 	transient int height;
@@ -34,6 +44,7 @@
 	final private static long serialVersionUID = 1681126225205050147L;
 FontMetrics ( Font font ) {
+        this.font = font;
 	fontSpec = font.encode();
 	nativeData = Toolkit.fntInitFontMetrics( font.nativeData);	

-- snip ------------------------------------------------------------------------------
Maurizio De Cecco
MandrakeSoft 		http://www.mandrakesoft.com/

More information about the kaffe mailing list