(Openfoundary.org的Issue Tracker我不会用><只好发文在这里)
前情提要:作业系统为Ubuntu 12.04.2,libXft为version 2.2.0
昨天去下载pcmanx-gtk2-1.2,上PTT时常会Segmentation fault。目前只找到一篇可使
bug重复出现的文章:http://www.ptt.cc/bbs/TigerBlue/M.1361860974.A.A8C.html。我
装回pcmanx-gtk2-1.1问题仍然存在。(昨天是小弟第一次上唬烂版)
节录gdb的内容如下:
(gdb) bt
#0 XftCharExists (dpy=0x76d880, pub=0x0, ucs4=63269) at
../../src/xftglyphs.c:836
#1 0x00000000004346ef in CFontConfig::SearchFontFor (this=0xa377a0,
ucs4=63269) at cfontconfig.cpp:120
#2 0x0000000000431538 in CTermView::DrawChar (this=0x9c9e30, row=<optimized
out>, col=<optimized out>) at termview.cpp:557
(...#3 CTermData::DoUpdateDisplay()到#10 main()略...)
src/core/cfontconfig.cpp的SearchFontFor()内容为:
XftFont* CFontConfig::SearchFontFor(FcChar32 ucs4)
{
Display *display = gdk_x11_get_default_xdisplay();
gint screen = gdk_x11_get_default_screen();
for (vector<CFontPack*>::iterator it = fonts.begin(); it != fonts.end();
it++) {
if ((*it)->check == false) {
(*it)->font = XftFontOpen(display, screen,
FC_FAMILY, FcTypeString, (*it)->name,
FC_SIZE, FcTypeDouble, (double) 16,
FC_WEIGHT, FcTypeInteger, FC_WEIGHT_MEDIUM,
FC_ANTIALIAS, FcTypeBool, FcTrue,
XFT_CORE, FcTypeBool, FcFalse,
NULL);
(*it)->check = true;
}
if (XftCharExists(display, (*it)->font, ucs4) == FcTrue) {
return (*it)->font;
}
}
return NULL;
}
由于XftCharExists()并没有检查第二个参数是不是合法的指标,而且XftFontOpen找不到
适合的字型时会回传NULL,因此就有机会Segfault
(我参考的XftCharExists()的code: http://tinyurl.com/cq9j7xz Line 705~713)
如果先检查指标,再传给XftCharExists(),可能就可以避免Segfault,例如:
// XftOpenFont returns NULL if no match found, buf XftCharExists
// assumes the second parameter valid
if ((*it)->font) {
if (XftCharExists(display, (*it)->font, ucs4) == FcTrue) {
return (*it)->font;
}
}
如此找不到适当字型时SearchFont()就会回传NULL
呼叫SearchFont()的CTermView::DrawChar()在return value为NULL时便采用默认的字型
画出字符(src/core/termview.cpp Line 557~562),所以这样改应该不会有不好的影响。
只是抛砖引玉,希望有更好的解决方法,也希望这个bug早日修复!