Libspotify:注销或释放会话导致崩溃



这是对dan (dan^spotify on IRC)提供的查看我的测试用例的回应,但我把它贴在这里以防有人遇到类似的问题。

我遇到了libspotify的问题,在这两种情况下应用程序崩溃(内存访问冲突):

  • 在调用sp_session_logout()函数后调用的第一个sp_session_process_events(由notify主线程回调触发)导致应用程序崩溃
  • 跳过注销并调用sp_session_release()导致应用程序崩溃

我已经从会话回调中应用了足够的同步,否则我将在单个线程上操作。

我做了一个小的测试用例,它做了以下事情:

    <
  • 创建会话/gh>
  • 登录
  • 等待10秒
  • 尝试注销,然后崩溃(当调用sp_session_process_events()时)
  • 如果它成功注销(它没有),将调用sp_session_release()

我为测试用例制作了一个Gist。可以在这里找到:https://gist.github.com/4496396

测试用例是使用Qt(这是我使用我的项目),所以你需要Qt 5来编译它。我写这篇文章时也只考虑了Windows和Linux(没有Mac)。假设您已经安装了Qt 5和Qt Creator,说明如下:

  • 下载要点
  • 将libspotify文件夹复制到与.pro文件相同的文件夹
  • 复制appkey.c文件到同一文件夹
  • 编辑main.cpp用你的用户名和密码登录
  • 在sessiontest.cpp中编辑第38-39行,并设置缓存和设置路径到你喜欢的
  • 打开。pro文件并从Qt Creator中运行

如果有人能告诉我我做错了什么,我将非常感激,因为我花了很多时间去尝试任何我能想到的,或者只是盯着它看,我担心我现在已经对自己的错误视而不见了。

我已经在Windows 7和Linux Ubuntu 12.10上测试了它,我发现了一些不同的行为:

  • 在Windows上,无论设置和缓存路径如何,测试用例总是崩溃。
  • 在Linux上,如果设置设置和缓存为"(空字符串),注销和释放会话工作正常。
  • 在Linux上,如果路径是其他的,第一次运行(当文件夹不存在时)会退出并释放会话,但是在下一次运行(当文件夹已经存在时),它会以与Windows相同的方式崩溃。

此外,我可以报告sp_session_flush_caches() 导致崩溃。

编辑:另外,IRC上的hugo___很友好地为我在OSX上测试了它。他报告说,尽管连续运行了几次应用程序,但没有崩溃。

虽然您很可能正在查看libspotify中的错误,但我想指出对sp_session_process_events()的可能冗余调用,这是我从查看您的代码中收集的。

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()的后续调用。然而,当interval为0时,这段代码也将调用startTimer,这是严格来说没有必要的,或者更确切地说,这意味着应用程序可以继续做其他事情,直到它得到notify_main_thread回调。startTimer上的文档说"如果interval为0,那么每当没有更多的窗口系统事件需要处理时,计时器事件就会发生一次。"我不确定这到底是什么意思,但似乎它可以产生至少一个冗余调用sp_session_process_events()

http://qt project.org/doc/qt - 4.8 -/- qobject.html #开始时间

我注意到,当你调用sp_session_release时,如果你有一个轨道正在播放,你会得到一个崩溃

我今天一直在追这个问题。登录/注销在Mac上工作正常,但正如您在Windows上描述的那样,问题是100%重复的。

通过为offline_status_updatedcredentials_blob_updated注册空回调,崩溃就消失了。这是一个相当不令人满意的修复,我想知道是否有任何libspotify开发人员想要评论它。

在我的应用程序中注册的回调是:

  • logged_in
  • logged_out
  • notify_main_thread
  • log_message
  • offline_status_updated
  • credentials_blob_updated
我应该明确指出,我没有 在您提供的代码上尝试这个。想知道添加这两个额外的回调是否对您有效,这将是一件很有趣的事情。注意,我提供的函数完全不做任何事情。它们只需要在你创建会话时存在并注册。

在您的"已登录" libspotify回调中添加以下调用似乎可以修复此崩溃,详见此SO帖子:

sp_session_playlistcontainer(session);

最新更新