So-net無料ブログ作成

【Ubuntu 12.04 alpha 2】ファイルマネージャー(Nautilus)を起動するとnautilus-dropboxが原因でコアダンプで落ちる。-- glibが2.31.18になったのが原因みたい(修正済みです) [ubuntu]

--- 2012/2/24 追記 ---

もう修正版の2.31.18-0ubuntu2が出ています。

やはりオーバーフローが問題でした。それに、バグ報告は下記メインのものでした。

https://bugs.launchpad.net/ubuntu/+source/nautilus-dropbox/+bug/932627

修正の考え方は基本的に同じですが、実際のコードは明らかに私の方が下手です。キャストすればいいのは分かてたのですが、どこでキャストすればいいかよく分からなかったので、一番安全策でコーディングしました。

ただ、不思議なのは、g_async_queue_timed_popは直しておいて、次に記述してある関数g_async_queue_timed_pop_unlockedも同じ問題があるに直していません。

なぜ?? 使わないからかな??

--- 2012/2/24 追記終わり ---

先日(2012/2/21前後)から、ファイルマネージャー(Nautilus)を起動するとnautilus-dropboxが原因で落ちるようになってしまいました。

結構、Dropboxの中にデータを入れているので困ってしまいました。

SS-nautilus-dropbox-001.jpeg

Launchpad にも報告されていて、下記です。

https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/932556

pthread_cond_timedwaitという関数が入力パラメータがおかしいというエラーです。

それで、 pthread_cond_timedwaitという関数はnautilus-dropboxからどのように呼ばれているかというと、

nautilus_dropbox_get_file_items ( nautilus-dropbox.c: nautilus-dropbox)

     ↓

g_async_queue_timed_pop  ( gasyncqueue.c :glib)

     ↓

g_async_queue_pop_intern_unlocked ( gasyncqueue.c :glib)

     ↓

g_cond_wait_until ( gthread-posix.c :glib)

     ↓

pthread_cond_timedwait

と呼ばれていきます。

それで、glibを経由して呼ばれているのですがglib2.0 2.1.18( https://launchpad.net/ubuntu/+source/glib2.0/2.31.18-0ubuntu1)の下記のdiffを見ると、

http://launchpadlibrarian.net/93542878/glib2.0_2.31.16-0ubuntu2_2.31.18-0ubuntu1.diff.gz

上記リンクの内容を見ると、g_async_queue_pop_intern_unlocked関数に修正が入っています。

修正内容というのが、g_cond_timed_wait関数を呼んでいたのを止めて、g_cond_waitまたはg_cond_wait_untilを呼ぶようにした事。それと、引数のend_timeの型がGTimeVal * から gint64になったことです。

問題はGTimeValの中身は2つの要素があってそれぞれglong型。ところが、 g_async_queue_pop_intern_unlockedの引数であるend_timeはgint64型です。

そこで、g_async_queue_timed_pop関数は下記のようなコードです。(ver. 2.31.18時点)

gpointer
g_async_queue_timed_pop (GAsyncQueue *queue,
                         GTimeVal    *end_time)
{
    gint64 m_end_time;
    gpointer retval;

    g_return_val_if_fail (queue, NULL);

    if (end_time != NULL)
    {
    m_end_time = g_get_monotonic_time () +
        (end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec -
         g_get_real_time ()
);
    }
  else
    m_end_time = -1;

  g_mutex_lock (&queue->mutex);
  retval = g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time);
  g_mutex_unlock (&queue->mutex);

  return retval;
}

上記の赤字の所はglong型(end_time->tv_secend_time->tv_usec)に入っているデータを計算してgint64型(m_end_time)に入れていますが、私の使っているのは32bit版なので、glongは4バイトgint64は8バイトになります。

私の記憶が正しければ、 end_time->tv_sec * G_USEC_PER_SECの計算やその結果を一旦格納する型はglong型(32bitレジスターが1つ分のサイズ)なはず・・・運が悪いとオーバーフローしてしまいます。

というわけで、下記のように書き直して見ました。

gpointer
g_async_queue_timed_pop_unlocked (GAsyncQueue *queue,
                                  GTimeVal    *end_time)
{
  gint64 m_end_time,tmp_end_time;

  g_return_val_if_fail (queue, NULL);

  if (end_time != NULL)
    {
      m_end_time = g_get_monotonic_time ();
      tmp_end_time = end_time->tv_sec;
      tmp_end_time *= G_USEC_PER_SEC;
      m_end_time += tmp_end_time;
      m_end_time += end_time->tv_usec;
      m_end_time -= g_get_real_time ();
    }
  else
    m_end_time = -1;

  return g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time);
}

※記述がスマートでなくてすみません。

要するに、一回gint64型の変数に代入してから全て計算しているだけです。

g_async_queue_timed_pop_unlocked関数も同じようになっていたので、同じように修正しました。

あとはビルドして入れたら、下記のように動きました。

SS-nautilus-dropbox-002.jpeg

上図のdpkg- l  libglib2.0-0の出力結果は、リポジトリのものそのままの値になっていますが、実際には本記事に記述したように私が修正したものです。

それと、私の修正が正しければ32bit版を使用している人のみ発生するはずで、64bit版の方は大丈夫なはずです。(glongの型の大きさとgint64の型の大きさが一緒だから)

早く直してね。。(*・人・*) オ・ネ・ガ・イ♪

 

 ←耐水ノート

    この前テレビでこれ見ました。
    この製品かはわかりませんが・・・
    水の中でも鉛筆でかける。
    私はヨットに乗るので、こういうのはいいかも・・・


nice!(0)  コメント(0) 
共通テーマ:パソコン・インターネット
メッセージを送る