ttt

getttyent

(FreeBSD) USBキーボード/マウスを抜き差しするとたまにXサーバーがsegmentation faultで落ちる

2010-11-16 22:17:06 | デジタル・インターネット

am64なFreeBSD 8.1-STABLE、けっこう最新のportsでインストールしたXorgな環境なのですが、しばらく前から、Xサーバーがsegmentation faultで落ちるようになりまして、

  • GNOMEをKDEに変えてみたり
  • on-boardのintelなビデオを、Radeon HDなビデオカードに換えたり
  • portupgradeしまくったり
  • 最新のRELENG_8へcsup、make buildworld、…したり

いろいろやってみたものの、やっぱりたまにsegmentation fault。

仕方ないので、Xのcoreを吐いて、gdbでのぞいてみました。

setuidしてあるバイナリはcoreを出力しないようになっているらしく(セキュリティ的な仕様だと思う)、最初、わざわざrootでログインして、Xサーバを立ち上げて、segmentation faultが起きるまで、気長に待つ、なんてことをやってたんですが
一般ユーザーで普通にログインして、Xサーバを立ち上げて、gdbで、実行中のXサーバのプロセスにattachすればよかったのでした。

というわけで、落ちてる場所が特定できました。

Xorgのマウスドライバであるxf86-input-mouse-1.5.0の、

#8  0x000000081300815d in MouseCtrl (device=0x801e2dc00, ctrl=0x814aafba8) at mouse.c:1570

というところ。
デバッグシンボルが入ってないので、ソースコードは見えませんが、portsでmake patchして、該当箇所のソースを確認。
すると、

(gdb) p pMse
$5 = 0x0

ということがわかりました。

なぜNULLが渡されてるのかはよくわかりませんが、とりあえず、以下のように、NULLポインタのチェックを追加。いいのか、こんなので?!という気もしますが…

static void
MouseCtrl(DeviceIntPtr device, PtrCtrl *ctrl)
{
    InputInfoPtr pInfo;
    MouseDevPtr pMse;

    pInfo = device->public.devicePrivate;
    pMse = pInfo->private;

#ifdef EXTMOUSEDEBUG
    ErrorF("MouseCtrl pMse=%p\n", pMse);
#endif

    if ( pMse != NULL ) {
        pMse->num       = ctrl->num;
        pMse->den       = ctrl->den;
        pMse->threshold = ctrl->threshold;
    }
}

マウスだけでなく、キーボードの方でも、似たような落ち方をしてたんですが、ちょっと思うところがありまして(後述)、キーボードがUSB接続だったのをやめて、PS2接続にしました。

ソースコードが見えないと困るので、デバッグ用オプションを付けて、マウスドライバだけ、再インストール。portsって便利。これだけでできちゃう。

env WITH_DEBUG=yes portupgrade -wWf xf86-input-mouse-1.5.0

その後、普通にXを立ち上げて、gdbでattachして、segmentation faultが起きないか、ビクビクしながら使っていますが、1週間以上、落ちずに動いています。

いつXサーバが落ちるのか、何か条件があるか探っていたのですが、わかりました。

なぜか、USBデバイス(キーボードとマウス)が、勝手に、切断され、またすぐに再接続される、という謎の現象が起きていました。

この、勝手にUSBデバイスがdetachされるという珍現象は、実は以前からたびたび発生していました。

  • USBキーボードは、たまに、抜いて、刺したことになってる。接触不良なんてことはない
  • マザーボード背面のUSBコネクタに、USBマウスをつないでいると、あるとき突然、マウスが動かなくなる
  • コネクタを抜いて、別のポートにつなぐと、また動くようになる
  • マザーボード背面のUSBコネクタよりは、ヘッダピンのUSBの方が、若干、調子いい
  • USBマウスを2個つないでおいたほうが、具合がいい (なんじゃ、その、おまじない…)

マザーボードは、ASUSのP5Q-EMというものなんですが、ネット検索してみると、P5Qシリーズの中に、USBのトラブルが発生するものがあるそうですね。う~ん、ハズレをひいた?

というわけで、USBが勝手にdetachとattachを繰り返すせいで、絶妙なタイミングで、Xorgを落としてくれちゃった、っていうことのようです。

ちなみに、ビデオドライバは、intel(オンボードビデオのとき)、radeon、radeonhd(PCIeなビデオカードのとき)、いろいろためしていて、うすうす気がついてたんですが

  • Xサーバは、1回しか起動できない
  • 一度終了して、次に起動しようとすると、変な画面になったり、固まったり、勝手リブートしたりすることがある

なんていう不具合も起きてます。
まあ、こっちについては、Xを終了したあとは、必ずOSを再起動する、という後ろ向きな対処をしています。

20101116