Pregunta

I was testing out libspotify library (version 12.1.51 x86 for linux) and the application keeps crashing when I call sp_session_create() with a segmentation fault.

I don't have application key, nor a Premium Spotify account (yet), but that shouldn't be the reason for the crash, since if I remember correctly, there is an error code for invalid application key.

My code is as follows:

static uint_8_t g_appkey[] = {1, 2, 3};
static const char *username = "MyUsername";
static const char *password = "MyPassword";
static int logged_in;

static sp_session_callbacks session_callbacks;
static sp_session_config spconfig;

static void on_login(sp_session *session, sp_error error) {
    printf("Callback: on_login");
    if (error != SP_ERROR_OK) {
        printf("Error: Unable to login: %d\n", (int) error);
        exit(-1);
    }
    logged_in = 1;
}

static void on_main_thread_notified(sp_session *session) {
    printf("callback: on_main_thread_notified");
}

static void on_log_message(sp_session *session, const char *data) {
    printf("callback: on_log_message");
}

int main(int argc, char **argv) {
    sp_error error;
    sp_session *session;
    int next_timeout;

    /* struct fill */
    memset(&session_callbacks, 0, sizeof(session_callbacks));
    memset(&spconfig, 0, sizeof(spconfig)); 

    session_callbacks.logged_in          = &on_login;
    session_callbacks.notify_main_thread = &on_main_thread_notified;
    session_callbacks.log_message        = &on_log_message; 

    spconfig.api_version          = SPOTIFY_API_VERSION;
    spconfig.cache_location       = "tmp";
    spconfig.settings_location    = "tmp";
    spconfig.application_key      = g_appkey;
    spconfig.application_key_size = sizeof(g_appkey);
    spconfig.user_agent           = "spot";
    spconfig.callbacks            = &session_callbacks;

    /* session creation */  
    error = sp_session_create(&spconfig, &session);
    if (error != SP_ERROR_OK) {
        printf("ERROR: Unable to create spotify session: %s\n", sp_error_message(error));
        exit(-1);
    }

    /* log in */
    logged_in = 0;
    sp_session_login(session, username, password, 0, NULL);
    while(!logged_in) {
        sp_session_process_events(session, &next_timeout);
        sleep(next_timeout);
    }

    printf("Sucess!!");
    exit(0);
}

Any tips for where could be the problem?

Appreciated for any help given.


backtrace from gdb:

[Thread debugging using libthread_db enabled]
[New Thread 0xb7fe6b70 (LWP 1839)]
[New Thread 0xb7f65b70 (LWP 1840)]

Program received signal SIGSEGV, Segmentation fault.
0x002b9b36 in sp_session_create () from /usr/local/lib/libspotify.so.12
(gdb) thread apply all backtrace

Thread 3 (Thread 0xb7f65b70 (LWP 1840)):
#0  0x0012d422 in __kernel_vsyscall ()
#1  0x003e6ce6 in nanosleep () at ../sysdeps/unix/syscall-template.S:82
#2  0x0041644c in usleep (useconds=10000) at ../sysdeps/unix/sysv/linux/usleep.c:33
#3  0x00293581 in ?? () from /usr/local/lib/libspotify.so.12
#4  0x00293990 in ?? () from /usr/local/lib/libspotify.so.12
#5  0x001d42b7 in ?? () from /usr/local/lib/libspotify.so.12
#6  0x004ae96e in start_thread (arg=0xb7f65b70) at pthread_create.c:300
#7  0x0041ca4e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130

Thread 2 (Thread 0xb7fe6b70 (LWP 1839)):
#0  0x0012d422 in __kernel_vsyscall ()
#1  0x004b5245 in sem_wait@@GLIBC_2.1 () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/sem_wait.S:80
#2  0x002178fa in ?? () from /usr/local/lib/libspotify.so.12
#3  0x001d42b7 in ?? () from /usr/local/lib/libspotify.so.12
#4  0x004ae96e in start_thread (arg=0xb7fe6b70) at pthread_create.c:300
#5  0x0041ca4e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130

Thread 1 (Thread 0xb7fe78d0 (LWP 1836)):
#0  0x002b9b36 in sp_session_create () from /usr/local/lib/libspotify.so.12
#1  0x080487d5 in main ()
(gdb) 
¿Fue útil?

Solución

Problem solved.

I got a valid application key from spotify, tested out my code and now it works.

It seems that the current live libspotify version has a bug when entering invalid application keys.

Otros consejos

variables with storage class static do not need to be nullified, they are by default

/* struct fill */
memset(&session_callbacks, 0, sizeof(session_callbacks));
memset(&spconfig, 0, sizeof(spconfig));

Make sure these folders actually exist

EDIT: Actually cache_location should be created by the lib.

spconfig.cache_location       = "tmp";
spconfig.settings_location    = "tmp";

For a complete example see:

http://damienradtke.org/playing-with-the-spotify-api/

Your fake app-key is very short. Looking at a valid app-key, it's 321 bytes long and the first two bytes are the big-endian number 322. I'd guess that perhaps those first two bytes tell libspotify how big a null-terminated string it needs to allocate to store the whole key. If libspotify trusts that instead of application_key_size, that might be why it's crashing instead of returning an error.

I took this code and built it against libspotify-12, and got it to execute with the expected error about app ID:

libspotify/examples/jukebox$ make
cc -I/usr/include/alsa   -I/home/nik/Code/spotify/libspotify/targets/Linux-x86_64-release/include -Wall   -Wl,-rpath,/home/nik/Code/spotify/libspotify/targets/Linux-x86_64-release/lib -L/home/nik/Code/spotify/libspotify/targets/Linux-x86_64-release/lib jukebox.o appkey.o alsa-audio.o audio.o -o jukebox -lasound   -lpthread -lspotify
libspotify/examples/jukebox$ ./jukebox
ERROR: Unable to create spotify session: Invalid application key

If you're having trouble getting things up and running, I would encourage you to take a look at the example code which ships with libspotify, specifically the jukebox example. In the above shell example, I just replaced jukebox.c with your code and got it to build with no problems.

It is possible that there is some bug here which was fixed in a later version of libspotify (disclaimer: I work for Spotify and actually compiled the above example with the latest 12.x code, which may contain some unreleased bugfixes). However, the code itself doesn't seem to do anything out of the ordinary, but again, if you're having problems I would suggest adapting jukebox.c to your purposes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top