(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早日修復!