从nodeJS模块调用libspotify注销时崩溃

我正在尝试编写一个包含libspotify的nodeJS模块。 目标是编写一个web应用程序,允许远程控制播放音乐的设备。

我决定沿着spshell的例子来确保线程的安全,并在纯C中编写一个“Spotify服务”,启动一个调用所有API函数的独立线程。

nodeJS模块然后调用几个提供的函数来与spotify进行交互。 该服务的代码可以在这里find: http : //pastebin.com/KB6uwSC8新的线程开始在底部。

现在,如果我在这样一个简单的程序中调用它(fget只是为了完成login有一个简单的方法)。 我使用c ++来获得尽可能接近node-gyp编译的代码。

#include <stdio.h> extern "C" { #include "objects/SpotifyService.h" } int main(int argc, char** argv) { login(); char string[100]; fgets(string, 100, stdin); fprintf(stdout, "Got: %s", string); logout(); fgets(string, 100, stdin); fprintf(stdout, "Got: %s", string); return 0; } 

它工作正常。 我不能让这个崩溃。

如果我在nodeJS中使用了相同的“服务”(意思是我只是调用login()logout()并且什么也不做login()logout()时会崩溃,如7-8 / 10次。 我已经尝试了很多东西,包括:

  • 将编译器标志从node-gyp复制到我的小例子
  • 摆弄spotify线程的线程属性
  • 在OSX和Debian上编译
  • 使用libuv而不是普通的pthreads
  • 编译我的“服务”到一个共享库,并从节点调用这个

无济于事。 它只是崩溃。 从gdb中调用的时候,似乎崩溃的更less,但可能是随机的。

来自gdb的堆栈跟踪显示如下:

 Thread 3 (Thread 0x7ffff65fd700 (LWP 21838)): #0 0x00007ffff678f746 in ?? () from /usr/local/lib/libspotify.so.12 #1 0x00007ffff6702289 in ?? () from /usr/local/lib/libspotify.so.12 #2 0x00007ffff6702535 in ?? () from /usr/local/lib/libspotify.so.12 #3 0x00007ffff6703b5a in ?? () from /usr/local/lib/libspotify.so.12 #4 0x00007ffff6703c86 in ?? () from /usr/local/lib/libspotify.so.12 #5 0x00007ffff66c5c8b in ?? () from /usr/local/lib/libspotify.so.12 #6 0x00007ffff679a5b3 in sp_session_process_events () from /usr/local/lib/libspotify.so.12 #7 0x00007ffff6aa7839 in spotifyLoop (nervNicht=<value optimized out>) at ../src/SpotifyService.c:103 #8 0x00007ffff70118ca in start_thread () from /lib/libpthread.so.0 #9 0x00007ffff6d78b6d in clone () from /lib/libc.so.6 #10 0x0000000000000000 in ?? () 

(在OSX中,gdb显示在libspotify中调用的函数被称为“process_title”。)

由于目前为止没有任何帮助,我只是没有任何想法,如果我能得到这个工作,或者如果它是在libspotify只是与nodeJS不兼容的东西。 我不明白如何node-gyp链接.o文件,也许有什么地方出错?

我在github上发现了另外两个尝试这样做的项目,但其中一个将spotify主循环实际放在Javascript中,另一个使用节点0.1.100和libspotify 0.0.4,并且在两年内没有更新。 我无法从他们两方面学到任何东西。

好吧,我已经玩了更多。 我只是忽略了注销错误,并继续实施其他function。

我在logged_incallback中添加了一个新的sp_playlist_container创build,显然有帮助。 之后,节点模块不再崩溃(或尚未)。

 static sp_playlistcontainer_callbacks pc_callbacks = { .container_loaded = &rootPlaylistContainerLoaded, }; static void rootPlaylistContainerLoaded(sp_playlistcontainer* pc, void* userdata) { int numPlaylists = sp_playlistcontainer_num_playlists(pc); fprintf(stdout, "Root playlist synchronized, number of Playlists: %d\n", numPlaylists); } static void loggedIn(sp_session* session, sp_error error) { if(SP_ERROR_OK != error) { fprintf(stderr, "Error logging in: %s\n", sp_error_message(error)); } else { fprintf(stdout, "Service is logged in!\n"); } //This is absolutely necessary here, otherwise following callbacks can crash. sp_playlistcontainer *pc = sp_session_playlistcontainer(spotifySession); sp_playlistcontainer_add_callbacks(pc, &pc_callbacks, NULL); } 

但是,sp_playlist_container创build必须在logged_incallback中,如果我在另一个函数(比如说“getPlaylistNames”)中调用它,程序也会崩溃。

我会看看它是否继续工作,并希望这个答案可以帮助别人。

Interesting Posts