3

これは、私のテストケースを調べるというdan(IRCのdan ^ spotify)の申し出に応えたものですが、誰かが同様の問題に遭遇した場合に備えて、ここに投稿します。

次の2つのシナリオの両方で、アプリケーションがクラッシュする(メモリアクセス違反)libspotifyで問題が発生しています。

  • sp_session_logout()関数が呼び出された後に呼び出される最初のsp_session_process_events(メインスレッドのコールバックの通知によってトリガーされる)は、アプリケーションをクラッシュさせます
  • ログアウトをスキップしてsp_session_release()を呼び出すと、アプリケーションがクラッシュします

セッションコールバックから十分な同期を適用しましたが、それ以外の場合は単一スレッドで操作しています。

私は次のことを行う小さなテストケースを作成しました。

  • セッションを作成します
  • ログイン
  • 10秒待つ
  • ログアウトしようとするとクラッシュします(sp_session_process_events()を呼び出す場合)
  • ログアウトに成功した場合(そうではありません)、sp_session_release()を呼び出します。

テストケースの要点を作成しました。ここで見つけることができます:https ://gist.github.com/4496396

テストケースはQt(私のプロジェクトで使用しているもの)を使用して作成されているため、コンパイルするにはQt5が必要です。また、WindowsとLinuxのみを念頭に置いて作成しました(Macは使用していません)。Qt5とQtCreatorがインストールされていると仮定すると、手順は次のとおりです。

  • 要旨をダウンロード
  • libspotifyフォルダーを.proファイルと同じフォルダーにコピーします
  • appkey.cファイルを同じフォルダーにコピーします
  • main.cppを編集して、ユーザー名とパスワードでログインします
  • sessiontest.cppの38〜39行目を編集し、キャッシュと設定のパスを好みに合わせて設定します
  • .proファイルを開き、QtCreatorから実行します

私は自分の考えていることを何でも試したり、見つめたりするのに何時間も費やしてきたので、誰かが私が間違っていることを教えてくれたらとてもありがたいです。今では。

Windows7とLinuxUbuntu12.10の両方でテストしましたが、動作にいくつかの違いがあります。

  • Windowsでは、設定やキャッシュパスに関係なく、テストケースは常にクラッシュします。
  • Linuxでは、設定とキャッシュを ""(空の文字列)に設定すると、ログアウトしてセッションを解放できます。
  • Linuxでは、パスがそれ以外の場合、最初の実行(フォルダーがまだ存在しない場合)はログアウトしてセッションを解放しますが、次の実行(フォルダーが既に存在する場合)では、まったく同じ方法でクラッシュします。 Windowsで行います。

また、sp_session_flush_caches()がクラッシュを引き起こさないことを報告できます。

編集:また、IRCのhugo___は親切にもOSXでテストしてくれました。彼は、アプリケーションを連続して数回実行したにもかかわらず、クラッシュは発生しなかったと報告しました。

4

4 に答える 4

1

sp_session_process_events()あなたは libspotify のバグを見ているかもしれませんが、私があなたのコードを見て集めたものから、おそらく冗長な への呼び出しを指摘したいと思います。

void SessionTest::processSpotifyEvents()
{
  if (m_session == 0)
  {
    qDebug() << "Process: No session.";
    return;
  }
  int interval = 0;
  sp_session_process_events(m_session, &interval);
  qDebug() << interval;
  m_timerId = startTimer(interval);
}

このコードは、interval値を取得してタイマーを開始し、次の への呼び出しをトリガーするようevent()です。ただし、このコードはstartTimerinterval が 0 の場合にも呼び出されますが、これは厳密には必要ありません。つまり、アプリがnotify_main_threadコールバックを取得するまで他のことを実行できることを意味します。ドキュメントにstartTimerは、「間隔が 0 の場合、処理するウィンドウ システム イベントがなくなるたびにタイマー イベントが 1 回発生する」と記載されています。それが正確に何を意味するのかはわかりませんが、 への少なくとも 1 つの冗長な呼び出しを生成できるようsp_session_process_events()です。

http://qt-project.org/doc/qt-4.8/qobject.html#startTimer

于 2013-01-10T12:08:18.300 に答える
0

私は今日、この問題を追いかけてきました。ログイン/ログアウトは Mac では問題なく機能しますが、Windows で説明したように、問題は 100% 再現可能でした。

offline_status_updatedとの空のコールバックを登録することcredentials_blob_updatedで、クラッシュはなくなりました。これはかなり満足のいく修正ではありませんでした。libspotify開発者がコメントしたいかどうか疑問に思います。

私のアプリに登録されているコールバックは次のとおりです。

  • logged_in
  • logged_out
  • notify_main_thread
  • log_message
  • offline_status_updated
  • credentials_blob_updated

あなたが提供したコードでこれを試していないことを明示的に指摘する必要があります。これら 2 つの追加のコールバックを追加することがうまくいくかどうかを知ることは興味深いでしょう。私が提供する関数はまったく何もしないことに注意してください。セッションを作成するときに、それらがそこにあり、登録されている必要があります。

于 2014-05-06T06:41:29.930 に答える
0

「ログイン済み」の libspotify コールバックに次の呼び出しを追加すると、この SO 投稿で詳しく説明されているように、このクラッシュが修正されるようです。

sp_session_playlistcontainer(session);

于 2014-11-30T11:05:02.977 に答える