The editor in chief of this blog was born in 2004. She uses the 1997 window manager, Enlightenment E16, daily. In this article, I describe the process of fixing a show-stopping, rare bug that dates back to 2006 in the codebase. Surprisingly, the issue has roots in a faulty implementation of Newton’s algorithm.
Some may find it weird, but I actually greatly enjoy using Enlightenment E16 as my window manager. It’s themable, hackable, lightweight (24MB peak RSS!), amenable to heavy keyboard users like myself, and most importantly - it looks goregous:
E16 first came to be in 1997, thanks to Carsten Haitzler, and it has been in development ever since. Most have moved to E17 and other newer versions; a community of hardcore enthusiasts still uses E16, and I am one of them. The codebase is quite old, and it has accumulated a lot of technical debt over the years.
Bugs always come out of the woodworks in a time scramble and this one likely sensed a prime opportunity: I was doing a lot of last-minute work on a couple of slides for a course that I will be teaching. I had a couple of PDFs with lecture slides and an exercise sheet typeset in LaTeX. At some point, I opened one of them in Atril, and the entire desktop froze.
The bug⌗
I killed the X11 session from a TTY. Sadly, the hang was deterministic: every time I opened that specific PDF.
Attaching gdb to the live process showed every sample parked in imlib2’s font cache, under the same e16 caller:
#0 __strcmp_evex () #1 __imlib_hash_find (hash=0x55bc9c111420, key="\001\001\001\001\001") object.c:172 #2 __imlib_font_cache_glyph_get (fn=..., index=0) font_draw.c:30 #3 __imlib_font_get_next_glyph (... utf8="Kickoff.pdf — Introduction...") font_main.c:218 #4 __imlib_font_query_advance (...) font_query.c:89 #5 imlib_get_text_advance (...) api_text.c:231 #6 Efont_extents (...) text_ift.c:87 #7 _ift_TextSize (...) text_ift.c:156 #8 TextstateTextFitMB (ts=..., textwidth_limit=291) text.c:350 #9 TextstateTextFit (...) text.c:559 #10 TextstateTextDraw (... text="Kickoff.pdf — Introduction...") text.c:638 #11 ITApply (...) iclass.c:930 #12 ITApply (...) iclass.c:884 #13 _BorderWinpartITclassApply (ewin=..., i=2, force=1) borders.c:179 #14 EwinBorderUpdateInfo (ewin=...) borders.c:300 #15 EwinChangesProcess (...) ewins.c:2141 #16 EwinEventPropertyNotify (ewin=..., ev=...) ewins.c:1438 ... #21 main (...) main.c:320
Re-attaching repeatedly showed the program was not deadlocked. __imlib_font_cache_glyph_get was being called with different glyph indices (0, 20, 73, 81, 82, 87, 88, …) each time. So the inner font-measurement was making progress; the loop was somewhere outside it.
After some fudging, I found out that Frame 8 ( TextstateTextFitMB at text.c:350 ) was the constant. That’s a ts->ops->TextSize(ts, new_line, 0, pw, &hh, &ascent); call inside the middle-ellipsis truncation loop that tries to fit a string into textwidth_limit = 291 pixels by nuking characters out of the middle - used when rendering the title of the PDF, that happened to also be the title of the window, too long for the decoration to contain.
... continue reading