SSブログ

【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) 
共通テーマ:パソコン・インターネット

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。