2011年9月9日金曜日

(FreeBSD) Thunderbird6で、添付ファイルを送ろうとするとBus Error

以下は、FreeBSD/amd64 8.2-RELEASEで、2011年9月8日時点のports/mail/thunderbird でmake installしたThunderbid 6.0.2で、動作確認したときの話です。



メール送信ウインドウにて、テキスト形式のファイルを添付ファイルに追加してから、Draftsフォルダなどに保存すると、Bus errorで落ちてしまいます。



とりあえず、debugオプションを有効にして、thunderbird -g で実行してgdbでのぞいてみました。



Program received signal SIGBUS, Bus error.
[Switching to Thread 8094041c0 (LWP 101157/initial thread)]
0x00000008021a0df9 in nsSJISProber::HandleData (this=0x80eebf980,
    aBuf=0x7fffffff8890 "", aLen=0)
    at /..../ports/mail/thunderbird/work/comm-release/mozilla/extensions/universalchardet/src/base/nsSJISProber.cpp:82
82        mLastChar[0] = aBuf[aLen-1];



(gdb) p aBuf
$1 = 0x7fffffff8890 ""
(gdb) p *aBuf
$2 = 0 '\0'



aLenが0なので、aBuf[-1]という、配列の範囲外アクセスをしているようです。



まずそうなことをしているけど、それって、Bus errorなんだっけ?
*aBufも*mLastCharもcharだから、1バイトアクセスになるけど…



関数全体を、ざっと眺めてみると・・・



nsProbingState nsSJISProber::HandleData(const char* aBuf, PRUint32 aLen)
{
  nsSMState codingState;

  for (PRUint32 i = 0; i < aLen; i++)
  {
    codingState = mCodingSM->NextState(aBuf[i]);
    if (codingState == eItsMe)
    {
      mState = eFoundIt;
      break;
    }
    if (codingState == eStart)
    {
      PRUint32 charLen = mCodingSM->GetCurrentCharLen();
      if (i == 0)
      {
        mLastChar[1] = aBuf[0];
        mContextAnalyser.HandleOneChar(mLastChar+2-charLen, charLen);
        mDistributionAnalyser.HandleOneChar(mLastChar, charLen);
      }
      else
      {
        mContextAnalyser.HandleOneChar(aBuf+i+1-charLen, charLen);
        mDistributionAnalyser.HandleOneChar(aBuf+i-1, charLen);
      }
    }
  }

  mLastChar[0] = aBuf[aLen-1];

  if (mState == eDetecting)
    if (mContextAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD)
      mState = eFoundIt;

  return mState;
}



関数の引数aLenが0だと、どうやっても、[-1]をアクセスしにいきますね。



このあたりのコードは、昔から変わっていないみたいなので、なぜ急にBus errorなぞ出るようになったんでしょうか。コンパイラの最適化とか???



どこで、aLen=0になってるんでしょうか。



(gdb) where
#0  0x00000008021a0df9 in nsSJISProber::HandleData (this=0x80eebf980,
    aBuf=0x7fffffff8890 "", aLen=0)
    at /..../ports/mail/thunderbird/work/comm-release/mozilla/extensions/universalchardet/src/base/nsSJISProber.cpp:82
#1  0x000000080219f4c9 in nsMBCSGroupProber::HandleData (this=0x80ebaccc0,
    aBuf=0x7fffffff8890 "", aLen=0)
    at /..../ports/mail/thunderbird/work/comm-release/mozilla/extensions/universalchardet/src/base/nsMBCSGroupProber.cpp:159
#2  0x00000008021a188e in nsUniversalDetector::HandleData (this=0x80ebace10,
    aBuf=0x7fffffff8890 "", aLen=0)
    at /..../ports/mail/thunderbird/work/comm-release/mozilla/extensions/universalchardet/src/base/nsUniversalDetector.cpp:214
#3  0x000000080219c9c1 in nsXPCOMDetector::DoIt (this=0x80ebace10,
    aBuf=0x7fffffff8890 "", aLen=0, oDontFeedMe=0x7fffffff8998)
    at /..../ports/mail/thunderbird/work/comm-release/mozilla/extensions/universalchardet/src/xpcom/nsUdetXPCOMWrapper.cpp:89
#4  0x0000000802a7afec in nsMsgAttachmentHandler::PickCharset (this=Variable "this" is not available.
)
    at nsMsgAttachmentHandler.cpp:588
#5  0x0000000802a574f7 in nsMsgComposeAndSend::PreProcessPart (
    this=0x80ef0d0c0, ma=0x814de2f08, toppart=0x80eb9fb40)
    at nsMsgSend.cpp:1170
#6  0x0000000802a59757 in nsMsgComposeAndSend::GatherMimeAttachments (
    this=0x80ef0d0c0) at nsMsgSend.cpp:1020
#7  0x0000000802a54ecf in nsMsgComposeAndSend::HackAttachments (
    this=0x80ef0d0c0, attachments=0x0, preloaded_attachments=0x7fffffff8e20)
    at nsMsgSend.cpp:2734
#8  0x0000000802a55881 in nsMsgComposeAndSend::Init (this=0x80ef0d0c0,
    aUserIdentity=0x80ebd9940, aAccountKey=0x0, fields=0x817cd2fc0,
    sendFile=0x0, digest_p=0, dont_deliver_p=0, mode=4, msgToReplace=0x0,
    attachment1_type=0x80325d080 "text/html",
    attachment1_body=0x818050a00 "<html>\n  <head>\n    <meta http-equiv=\"content-type\" content=\"text/html;\n      charset=ISO-8859-1\">\n  </head>\n  <body bgcolor=\"#FFFFFF\" text=\"#000000\">\n    hello<br>\n    <br>\n  </body>\n</html>\n\n", attachment1_body_length=193, attachments=0x0,
    preloaded_attachments=0x0, password=0x803dd9188 "",
    aOriginalMsgURI=@0x81d4af3b8, aType=9) at nsMsgSend.cpp:3449
#9  0x0000000802a560ad in nsMsgComposeAndSend::CreateAndSendMessage (
    this=0x80ef0d0c0, aEditor=0x816529400, aUserIdentity=0x80ebd9940,
    aAccountKey=0x0, fields=0x817cd2fc0, digest_p=0, dont_deliver_p=0, mode=4,
    msgToReplace=0x0, attachment1_type=0x80325d080 "text/html",
    attachment1_body=0x818050a00 "<html>\n  <head>\n    <meta http-equiv=\"content-type\" content=\"text/html;\n      charset=ISO-8859-1\">\n  </head>\n  <body bgcolor=\"#FFFFFF\" text=\"#000000\">\n    hello<br>\n    <br>\n  </body>\n</html>\n\n", attachment1_body_length=193, attachments=0x0,
    preloaded_attachments=0x0, relatedPart=0x0, parentWindow=0x817d23300,
    progress=0x80eac7fd0, aListener=0x81470bc88, password=0x803dd9188 "",
    aOriginalMsgURI=@0x81d4af3b8, aType=9) at nsMsgSend.cpp:4285
#10 0x0000000802a959dc in nsMsgCompose::_SendMsg (this=0x81d4af380,
    deliverMode=4, identity=0x80ebd9940, accountKey=0x0,
    entityConversionDone=0) at nsMsgCompose.cpp:1045
#11 0x0000000802a9fd0b in nsMsgCompose::SendMsg (this=0x81d4af380,



えーと、ここですね。



./comm-release/mailnews/compose/src/nsMsgAttachmentHandler.cpp



#4  0x0000000802a7afec in nsMsgAttachmentHandler::PickCharset (this=Variable "this" is not available.
)
    at nsMsgAttachmentHandler.cpp:588
588           detector->DoIt(buffer.get(), buffer.Length(), &dontFeed);



(gdb) p buffer
$12 = {<nsFixedCString> = {<nsCString> = {<nsACString_internal> = {
        mData = 0x7fffffff8890 "", mLength = 0,
        mFlags = 65553}, <No data fields>}, mFixedCapacity = 63,
    mFixedBuf = 0x7fffffff8890 ""},
  mStorage = ".................省略........................."}



なぜbuffer.Length()が0なのかはよくわかりませんが、とりあえず、こんな風に、0チェックのコードを追加。



    while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore)))
    {
      if ( buffer.Length() == 0 ) continue; // ADD THIS LINE
      detector->DoIt(buffer.get(), buffer.Length(), &dontFeed);
      if (dontFeed)
        break;
    }



そしてmakeしてから、動作確認。libxul.soだけ置き換えればよさそう。



# mv /usr/local/lib/thunderbird/libxul.so  /usr/local/lib/thunderbird/libxul.so.ORG
# ln -s /..../ports/mail/thunderbird/work/comm-release/mozilla/toolkit/library/libxul.so /usr/local/lib/thunderbird/libxul.so



実行してみると、Bus errorはでなくなりましたし、一応、問題なく動いてるみたいです。



これで、しばらく様子見。



0 件のコメント:

コメントを投稿