[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#917034: xterm crashes on certain Unicode characters when font was selected with -fa



On Mon, Dec 31, 2018 at 06:11:23PM +0100, Alexander Meyer wrote:
> * Thomas Dickey <dickey@his.com> [2018-12-31 00:51]:
> 
> > On Sun, Dec 30, 2018 at 06:26:44PM +0100, Alexander Meyer wrote:
> > ...
> >> This is the behaviour I get across xterm versions:
> >> (everything with libfontconfig1 2.13.1-2)
> >> 
> >> fonts.conf enabled:
> >> 337: works
> >> 338: segfault
> >> 340: segfault
> >> 341: segfault
> > 
> > Can you make a backtrace for #341, please?
> 
> Here it is:

thanks.  I added some notes, but have not been able to reproduce the problem.
 
> Reading symbols from /usr/bin/xterm...Reading symbols from /usr/lib/debug/.build-id/b8/d462fb6f4969a6a228262ceff981af02a1a4d5.debug...done.
> done.
> (gdb) run -fa 'Noto Mono'

fwiw, my Debian/testing machine has these fonts (with "noto" in their names):

ii  fonts-noto                                    20181130-1                            all          metapackage to pull in all Noto fonts
ii  fonts-noto-cjk                                1:20170601+repack1-3                  all          "No Tofu" font families with large Unicode coverage (CJK regular and bold)
ii  fonts-noto-color-emoji                        0~20180810-1                          all          color emoji font from Google
ii  fonts-noto-hinted                             20181130-1                            all          "No Tofu" font families with large Unicode coverage (hinted)
ii  fonts-noto-mono                               20181130-1                            all          "No Tofu" monospaced font family with large Unicode coverage
ii  fonts-noto-unhinted                           20181130-1                            all          "No Tofu" font families with large Unicode coverage (unhinted)

> Starting program: /usr/bin/xterm -fa 'Noto Mono'
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff7d662d1 in FcConfigEvaluate (p=0x5555556f2430, p_pat=0x5555559dea90, kind=kind@entry=FcMatchFont, e=0x0) at fccfg.c:977
> (gdb) bt full
> #0  0x00007ffff7d662d1 in FcConfigEvaluate (p=0x5555556f2430, p_pat=0x5555559dea90, kind=kind@entry=FcMatchFont, e=0x0) at fccfg.c:977
>         v = {type = FcTypeVoid, u = {s = 0x5555556f1ad0 " \033oUUU", i = 1433344720, b = 1433344720, d = 4.6355706220021174e-310, m = 0x5555556f1ad0, c = 0x5555556f1ad0, f = 0x5555556f1ad0, 
>             l = 0x5555556f1ad0, r = 0x5555556f1ad0}}
>         vl = {type = 1433014944, u = {s = 0x0, i = 0, b = 0, d = 0, m = 0x0, c = 0x0, f = 0x0, l = 0x0, r = 0x0}}
>         vr = {type = 1436412560, u = {s = 0x0, i = 0, b = 0, d = 0, m = 0x0, c = 0x0, f = 0x0, l = 0x0, r = 0x0}}
>         vle = <optimized out>
>         vre = <optimized out>
>         m = <optimized out>
>         str = <optimized out>
>         op = <optimized out>

If "op" weren't optimized, we could see which case is breaking :-)
But since "e" is null, that says op is garbage anyway.

>         buf1 = {u = {d = 0, i = 0, l = 0, 
>             c = "\000\000\000\000\000\000\000\000\200\032oUUU\000\000\270\022jUUU\000\000\000\000\000\000\000\000\000\000\220\352\235UUU", '\000' <repeats 18 times>, "\256m\326\367\377\177\000\000\000\000\000\000\000\000\000\000\060\032oUUU\000\000\320\022jUUU\000\000\000\000\000\000\000\000\000\000\220\352\235UUU", '\000' <repeats 18 times>, "\256m\326\367\377\177\000\000\000\000\000\000\000\000\000\000\340\031oUUU\000\000\350\022jUUU\000\000\000\000\000\000\000\000\000\000\220\352\235UUU", '\000' <repeats 18 times>, "\256m\326\367\377\177\000\000\000\000\000\000\000\000\000\000"...}}
>         buf2 = {u = {d = 0, i = 0, l = 0, 
>             c = "\000\000\000\000\000\000\000\000@\031oUUU\000\000\030\023jUUU\000\000\000\000\000\000\000\000\000\000\025", '\000' <repeats 15 times>, "\a\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\020\300aUUU\000\000\017\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\260\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000\002\000\000\000\060", '\000' <repeats 19 times>, "[\000\000\000w", '\000' <repeats 11 times>, "n\000\000\000|\000\000\000\t\000\000\000\000\000\000\000\017\000\000\000\000\000\000\000\025", '\000' <repeats 15 times>, "\260\377\377\377\377\377\377\377"...}}
> #1  0x00007ffff7d66418 in FcConfigEvaluate (p=p@entry=0x5555556f2430, p_pat=p_pat@entry=0x5555559dea90, kind=kind@entry=FcMatchFont, e=e@entry=0x555555681218) at fccfg.c:1003
>         m = {xx = 1.4821969375237396e-323, xy = 6.9533490418283141e-310, yx = 1.4821969375237396e-323, yy = 1}
>         xx = <optimized out>
>         yy = <optimized out>
>         xy = <optimized out>
>         yx = <optimized out>
>         v = {type = FcTypeMatrix, u = {s = 0x3 <error: Cannot access memory at address 0x3>, i = 3, b = 3, d = 1.4821969375237396e-323, m = 0x3, c = 0x3, f = 0x3, l = 0x3, r = 0x3}}
>         vl = {type = FcTypeVoid, u = {s = 0x5555556f24b0 "Noto Color Emoji", i = 1433347248, b = 1433347248, d = 4.6355706221270172e-310, m = 0x5555556f24b0, c = 0x5555556f24b0, f = 0x5555556f24b0, 

========================================================================
It's still picking up the font with color-bitmaps (which Xft
does not handle).  Actually the functions beginning with "Fc"
are all in fontconfig, but reporting bugs for that package has
proven futile (ymmv).  So I'm just thinking about Xft...
========================================================================

That "address 0x3" business looks like a problem
where Xft/fontconfig has a null pointer to a structure.

There are a few pointers in that function, but I don't see anything obvious
(the function parameters are nonnull according to the trace, and the m/str
local variables are checked):

Line 1003 is this:
	  xx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xx), v, NULL);
(so "e->u.mexpr->xx" is probably null).

and the enclosing function looks like this:

static FcValue
FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
{
    FcValue	v, vl, vr, vle, vre;
    FcMatrix	*m;
    FcChar8     *str;
    FcOp	op = FC_OP_GET_OP (e->op);
    FcValuePromotionBuffer buf1, buf2;

You might get some insight by running xterm with valgrind.  When I do that,
I add "--with-valgrind" to the configure options to reduce the noise level.
I do something like this for running valgrind (abstracted from a script):

#!/bin/sh
rm -f vgcore*.*

OPTS="-v \
	--num-callers=10 \
	--error-limit=no \
	--show-reachable=yes \
	--leak-resolution=high \
	--track-origins=yes \
	--leak-check=yes \
	--show-reachable=yes"
valgrind $OPTS \
	--log-fd=2 \
	"$@" 2>valgrind.log

>             l = 0x5555556f24b0, r = 0x5555556f24b0}}
>         vr = {type = FcTypeString, u = {s = 0x7ffff7d660a4 <FcConfigCompareValue+708> "\205\300\017\224\300\017\266\300\351\267\375\377\377L\211\346H\211\327\350\364=", i = -136945500, b = -136945500, 
>             d = 6.9533490418283141e-310, m = 0x7ffff7d660a4 <FcConfigCompareValue+708>, c = 0x7ffff7d660a4 <FcConfigCompareValue+708>, f = 0x7ffff7d660a4 <FcConfigCompareValue+708>, 
>             l = 0x7ffff7d660a4 <FcConfigCompareValue+708>, r = 0x7ffff7d660a4 <FcConfigCompareValue+708>}}
>         vle = <optimized out>
>         vre = <optimized out>
>         m = <optimized out>
>         str = <optimized out>
>         op = FcOpMatrix
>         buf1 = {u = {d = 4.6355706048940074e-310, i = 1432998448, l = 93824993579568, 
>             c = "0\322iUUU\000\000\002\000\000\000\000\000\000\000\060\026jUUU\000\000\354c\326\367\377\177\000\000\000\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\003", '\000' <repeats 15 times>, "\a\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\002\000\000\000UU\000\000\020\300aUUU\000\000\017\000\000\000\000\000\000\000@\000\000\000\000\000\000\000\260\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000\002\000\000\000\060", '\000' <repeats 19 times>, "\f\341\327\367\377\177\000\000\000\000\000\000\257\060\000\000\000\240\316\365\301\035?\376\003\000\000\000\000\000\000\000\256\340\327\367\377\177\000\000\200\326\377\377\264\060\000\000\000"...}}
>         buf2 = {u = {d = 4.6355706320533889e-310, i = 1433548160, l = 93824994129280, 
>             c = "\200\065rUUU\000\000\270\220B\365\377\177\000\000\000\000\000\000\000\000\000\000\362H\327\367\377\177\000\000 ", '\000' <repeats 15 times>, "\a\000\000\000\000\000\000\000\060\000\000\000\000\000\000\000\003\000\000\000\377\177\000\000\030\300aUUU\000\000\037\000\000\000\000\000\000\000P\000\000\000\000\000\000\000\260\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000\003\000\000\000\060", '\000' <repeats 19 times>, "[\000\000\000w", '\000' <repeats 11 times>, "n\000\000\000|\000\000\000\a\000\000\000\000\000\000\000\037\000\000\000\000\000\000\000 \000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\260\377\377\377\377\377\377\377"...}}
> #2  0x00007ffff7d6755f in FcConfigMatchValueList (values=0x5555556f3210, t=<optimized out>, kind=FcMatchFont, p_pat=0x5555559dea90, p=0x5555556f2430) at fccfg.c:1341
>         ret = 0x0
>         e = 0x555555681218
>         value = {type = FcTypeString, u = {s = 0x5555556f2ce0 "", i = 1433349344, b = 1433349344, d = 4.6355706222305733e-310, m = 0x5555556f2ce0, c = 0x5555556f2ce0, f = 0x5555556f2ce0, 
>             l = 0x5555556f2ce0, r = 0x5555556f2ce0}}
>         v = <optimized out>
>         ret = <optimized out>
>         e = <optimized out>
>         value = <optimized out>
>         v = <optimized out>
> #3  IA__FcConfigSubstituteWithPat (config=<optimized out>, config@entry=0x555555659fc0, p=p@entry=0x5555556f2430, p_pat=p_pat@entry=0x5555559dea90, kind=kind@entry=FcMatchFont) at fccfg.c:1742
>         v = {type = FcTypeVoid, u = {s = 0x7ffff7d7a74c <FcPatternObjectInsertElt+236> "\203E", i = -136861876, b = -136861876, d = 6.9533490459598886e-310, 
>             m = 0x7ffff7d7a74c <FcPatternObjectInsertElt+236>, c = 0x7ffff7d7a74c <FcPatternObjectInsertElt+236>, f = 0x7ffff7d7a74c <FcPatternObjectInsertElt+236>, 
>             l = 0x7ffff7d7a74c <FcPatternObjectInsertElt+236>, r = 0x7ffff7d7a74c <FcPatternObjectInsertElt+236>}}
>         s = 0x555555668c60
>         iter = {dummy1 = 0x555555668c60, dummy2 = 0x5555556b4640, dummy3 = 0x55555567b420}
>         iter2 = {dummy1 = 0x55555568eaf0, dummy2 = 0x555555690a30, dummy3 = 0x0}
>         r = 0x555555690a10
>         rs = <optimized out>
>         l = <optimized out>
>         value = 0x555555694380
>         vl = <optimized out>
>         m = 0x5555556f2430
>         strs = <optimized out>
>         object = <optimized out>
>         elt = 0x5555556a7ea0
>         e = 0x5555556f2fc0
>         i = <optimized out>
>         nobjs = 53
>         retval = 1
>         tst = 0x555555694180
> #4  0x00007ffff7d779bd in IA__FcFontRenderPrepare (config=0x555555659fc0, pat=pat@entry=0x5555559dea90, font=0x7ffff5428840) at fcmatch.c:719
>         new = 0x5555556f2430
>         i = <optimized out>
>         fe = <optimized out>
>         pe = <optimized out>
>         v = {type = FcTypeBool, u = {s = 0x0, i = 0, b = 0, d = 0, m = 0x0, c = 0x0, f = 0x0, l = 0x0, r = 0x0}}
>         result = FcResultMatch
>         variable = 0
>         variations = {buf = 0x0, allocated = 0, failed = 1083129856, len = -272072704, size = 1115635585, 
>           buf_static = "@\\\337\366\377\177", '\000' <repeats 63 times>, "@\217@", '\000' <repeats 13 times>, "@\237@\000\000\000\000\000P\217@", '\000' <repeats 31 times>}
>         __PRETTY_FUNCTION__ = "IA__FcFontRenderPrepare"
> #5  0x00007ffff7d77d2b in IA__FcFontSetMatch (config=<optimized out>, sets=sets@entry=0x7fffffffdb10, nsets=nsets@entry=1, p=p@entry=0x5555559dea90, result=result@entry=0x7fffffffdb0c) at fcmatch.c:863
>         best = <optimized out>
>         __PRETTY_FUNCTION__ = "IA__FcFontSetMatch"
> #6  0x00005555555a7193 in findXftGlyph (xw=xw@entry=0x55555564deb0, given=given@entry=0x5555556bbd90, wc=wc@entry=127876) at ../fontutils.c:3861

This part is in the newer function which handles fallback fonts.
Since your trace shows line-numbers, I'm assuming it's not the Debian package.
(Actually the trace seems to show that you've compiled fontconfig -- turning
off the optimization might help pinpoint the details).

Since the crash is in FcFontSetMatch, I suppose it's possible that
something in the built-up pattern is what's amiss:

		FcDefaultSubstitute(myPattern);

		matchedFont = FcFontSetMatch(FcConfigGetCurrent(),

The fixes that I made in #341 are a little later in the process,
after the call to XftFontOpenPattern().  The crashes that I was
able to reproduce were triggered by Xft attempting to compute the
width of a glyph.

>         myReport = 0x0
>         matchedFont = <optimized out>
>         myFontSets = {0x5555559de400}
>         myPattern = 0x5555559dea90
>         myCharSet = 0x5555557232b0
>         check = <optimized out>
>         screen = 0x55555564e058
>         which = 0x555555652c88
>         result = 0x0
>         fontnum = <optimized out>
>         table = {19504, 21304, 23104, 24904, 26704, 28504}
>         n = 0
>         status = FcResultMatch
>         tag = 0x5555555e2648 "fNorm"
> #7  0x00005555555c7b9c in drawXtermText (xw=xw@entry=0x55555564deb0, attr_flags=attr_flags@entry=0, draw_flags=<optimized out>, draw_flags@entry=0, gc=0x555555659d10, start_x=2, start_y=<optimized out>, 
>     chrset=0, text=0x555555674ab0, len=1, on_wide=0) at ../util.c:3721
>         test = <optimized out>
>         part = 127876
>         filler = 0
>         replace = 0 '\000'
>         missing = 0 '\000'
>         ch = 127876

This is the character that isn't found in the current font: U+1f384 
But (XFT_DEBUG=1023), I'm only seeing the regular noto mono font loaded
when printing this character.  (Just for variety, I tried bold and underline too):

XFT_DEBUG=1023
XftDisplayInfoGet Default visual 0x21 format 0,16,8,0
XftDisplayInfoGet initialized, hasRender set to "True"
global max cache memory 4194304
global max unref fonts 16
FontFile /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf/0 matches new
XftFontInfoFill: /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf: 0 (26.6667 pixels)
New font /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf/0 size 26x26
Loading file /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf/0
Set face size to 26x26 (1706x1706)
Set face matrix to (1,0,0,1)
FontFile /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf/0 matches existing (2)
XftFontInfoFill: /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf: 0 (26.6667 pixels)
New font /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf/0 size 26x26
FontFile /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf/0 matches existing (3)
XftFontInfoFill: /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf: 0 (26.6667 pixels)
New font /usr/share/fonts/truetype/noto/NotoMono-Regular.ttf/0 size 26x26
Set face matrix to (1,0.199997,0,1)
Set face matrix to (1,0,0,1)

>         needed = <optimized out>
>         currFont = 0x5555556bbd90
>         tempFont = 0x0
>         last = 0
>         old_high = <optimized out>
>         first = 0
>         old_wide = <optimized out>
>         curX = 2
>         dpy = <optimized out>
>         font0 = 0x5555556bbd90
>         values = {function = <optimized out>, plane_mask = <optimized out>, foreground = 15066597, background = <optimized out>, line_width = <optimized out>, line_style = <optimized out>, 
>           cap_style = <optimized out>, join_style = <optimized out>, fill_style = <optimized out>, fill_rule = <optimized out>, arc_mode = <optimized out>, tile = <optimized out>, 
>           stipple = <optimized out>, ts_x_origin = <optimized out>, ts_y_origin = <optimized out>, font = <optimized out>, subwindow_mode = <optimized out>, graphics_exposures = <optimized out>, 
>           clip_x_origin = <optimized out>, clip_y_origin = <optimized out>, clip_mask = <optimized out>, dash_offset = <optimized out>, dashes = <optimized out>}
>         wfont0 = 0x0
>         currentWin = <optimized out>
>         font = 0x5555556bbd90
>         wfont = 0x0
>         x = 2
>         y = 25
>         screen = 0x55555564e058
>         real_length = 1
>         underline_len = 0
>         font_width = <optimized out>
>         did_ul = 0
>         curFont = <optimized out>
>         need_clipping = 0
> #8  0x00005555555cccfb in WriteText (xw=xw@entry=0x55555564deb0, str=str@entry=0x555555674ab0, len=len@entry=1) at ../util.c:1172
>         test = 65536
>         screen = <optimized out>
>         ld = <optimized out>
>         attr_flags = 65536
>         fg_bg = {fg = 0, bg = 0}
>         cells = 2
>         currentGC = <optimized out>
> #9  0x0000555555584829 in dotext (xw=xw@entry=0x55555564deb0, charset=nrc_ASCII, buf=<optimized out>, len=1) at ../charproc.c:5584
>         right = <optimized out>
>         width_available = <optimized out>
>         need_wrap = 0 '\000'
>         did_wrap = 0 '\000'
>         width_here = <optimized out>
>         last_chomp = <optimized out>
>         force_wrap = 0 '\000'
>         screen = 0x55555564e058
>         chars_chomped = <optimized out>
>         next_col = 0
>         offset = <optimized out>
>         rmargin = 79
> #10 0x000055555558a995 in doparsing (xw=xw@entry=0x55555564deb0, c=127876, sp=0x555555611ea0 <myState>) at ../charproc.c:2414
>         single = <optimized out>
>         this_is_wide = 1
>         screen = 0x55555564e058
>         item = 1432518520
>         count = <optimized out>
>         value = 21845
>         laststate = 6
>         thischar = 127876
>         myRect = {top = 0, left = 0, bottom = 0, right = 0}
> #11 0x0000555555591295 in VTparse (xw=xw@entry=0x55555564deb0) at ../charproc.c:5377
> No locals.
> #12 0x00005555555914a9 in VTRun (xw=0x55555564deb0) at ../charproc.c:7726
>         screen = 0x55555564e058
> #13 0x000055555557898a in main (argc=<optimized out>, argv=<optimized out>) at ../main.c:2826
>         tblFullscreen = {{name = 0x5555555d963e "Always", code = 2}, {name = 0x5555555d9638 "Never", code = 3}}
>         form_top = 0x55555563db80
>         menu_top = 0x55555563db80
>         menu_high = 0
>         screen = <optimized out>
>         mode = <optimized out>
>         my_class = 0x55555561c260 "XTerm"
>         line_speed = 15
>         winToEmbedInto = 0
> (gdb) quit
> 

-- 
Thomas E. Dickey <dickey@invisible-island.net>
https://invisible-island.net
ftp://ftp.invisible-island.net

Attachment: signature.asc
Description: Digital signature


Reply to: