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)
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.
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.
Related
I am using Linux8 environment and i have installed oracle 19c client. I have tried sample example of C program in which uses olog() oci function to connect to a remote database using
the client. when I execute the program with exiting database name(Giving database name in olog() function) then i am getting segmentation fault issue. If i am passing wrong database in olog() function then i am getting other issues, not segmentation fault.
below is the sample code:
//
static Lda_Def lda;
ub4 hda[HDA_SIZE / sizeof(size_t)];
void logon();
main(argc, argv)
eword argc;
text **argv;
{
printf("\nWelcome\n");
logon();
}
void err_report(cursor)
Cda_Def *cursor;
{
sword n;
text msg[512];
if (cursor->fc > 0)
printf("\n-- ORACLE error when processing OCI function %s \n\n",
oci_func_tab[cursor->fc]);
else
printf("\n-- ORACLE error\n");
n = (sword)oerhms(&lda, cursor->rc, msg, (sword) sizeof msg);
printf("%s\n", msg);
}
void logon()
{
if (olog(&lda, (ub1 *)hda, (text *)"skills", -1, (text *)"skill", -1,
(text *)"ORCLPDB", -1, OCI_LM_DEF))
{
err_report((Cda_Def *)&lda);
exit(OCI_EXIT_FAILURE);
}
printf("\n Connected to ORACLE as ocitest\n");
}
below is the error stack:
gdb) run
Using host libthread_db library "/usr/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff5051992 in kpuhhaerr () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
Missing separate debuginfos, use: debuginfo-install glibc-2.17-323.0.1.el7_9.x86_64 libaio-0.3.109-13.el7.x86_64 libgcc-4.8.5-28.0.1.el7_5.1.x86_64 numactl-libs-2.0.9-7.el7.x86_64
(gdb) where
#0 0x00007ffff5051992 in kpuhhaerr () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#1 0x00007ffff6f70f8b in ttcrbur () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#2 0x00007ffff6f51b40 in ttcdrv () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#3 0x00007ffff6f2157d in nioqwa () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#4 0x00007ffff6f02aa8 in upirtrc () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#5 0x00007ffff41cba55 in upirtr () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#6 0x00007ffff41c657f in upilgni () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#7 0x00007ffff51647ca in upilogc () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#8 0x00007ffff51646de in upilog () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#9 0x00007ffff50b20f7 in ocilog () from /oraclient/19.4.0.0.0/client/lib/libclntsh.so.19.1
#10 0x000000000040172c in logon()
#11 0x0000000000400d30 in main (argc=1, argv=0x7fffffffdf28)
Please help me to solve this issue.
Thanks in advance.
I've been experimenting with wrapping some Qt classes with a C interface to use with my latest D project. For what ever reason, this code works fine on Windows but segfaults on Linux and I haven't been able to track down the reason behind it. I haven't tried building on OSX yet.
I'm using Qt 5.3, and running Linux Mint.
The code is kind of spread out over a few different files so I thought it might be easier if I put all the related code into some pastebins.
QApplication Wrapper Stuff
QMainWindow Wrapper Stuff
These are very thin wrappers though, so even if you don't look at them it should be easy enough to understand my test program.
#include <Application.h>
#include <MainWindow.h>
int main( int argc, char* argv[])
{
Qt_Application* app = Qt_Application_create(argc, argv);
Qt_MainWindow* window = Qt_MainWindow_create();
Qt_MainWindow_show(window);//<- Segfault happens here
Qt_Application_exec(app);
Qt_Application_destroy(app);
Qt_MainWindow_destroy(window);
return 0;
}
Due to some printf tests, I know the segfault happens on when I try to call Qt_MainWindow_show, and likewise I know the window object exists when I pass it so that isn't the cause. Also, if I comment Qt_MainWindow_show out, Qt_Application_exec will get called no problem so as far as I know the wrapped objects are being created correctly.
When I run gdb, it says:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff789a92a in strlen () from /lib/x86_64-linux-gnu/libc.so.6
getting the backtrace at the point of the segfault shows this:
#0 0x00007ffff789a92a in strlen () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6b6c6bc in QCoreApplication::arguments() ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Core.so.5
#2 0x00007ffff1470213 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#3 0x00007ffff14705f9 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#4 0x00007ffff147d127 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#5 0x00007ffff1470009 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#6 0x00007ffff5d47e03 in QWindow::create() ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Gui.so.5
#7 0x00007ffff716b97a in QWidgetPrivate::create_sys(unsigned long long, bool, bool) () from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Widgets.so.5
#8 0x00007ffff714e6f5 in QWidget::create(unsigned long long, bool, bool) ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Widgets.so.5
#9 0x00007ffff71512ea in QWidget::setVisible(bool) ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Widgets.so.5
#10 0x00007ffff7bd8205 in Qt_MainWindow_show ()
from /home/jebbs/Documents/projects/HeliosCTest/libqtcl.so.1
#11 0x0000000000400922 in main (argc=1, argv=0x7fffffffe158) at main.cpp:22 <-actually points to Qt_MainWindow_show(window), but this is from a test with printf's in it
So it looks like some string somewhere is NULL and strlen cries? I couldn't find any reason that QMainWindow.show() might segfault. Any pointers into where I should look or what I should do next would be an excellent help.
I'm getting a segfault when using libCURL in my HTTP flooder that I wrote for load-testing my site.
Here is the relevant code: https://gist.github.com/AppleDash/a26e0ce0b138cd9eacd2 (A bit large to paste here.)
Here's a link to the line it is segfaulting on: https://gist.github.com/AppleDash/a26e0ce0b138cd9eacd2#file-httpflood-improved-c-L57
And here is a backtrace of the segfault:
#0 0x00007ffff760d65b in fwrite () from /usr/lib/libc.so.6
#1 0x00007ffff79656d8 in ?? () from /usr/lib/libcurl.so.4
#2 0x00007ffff797a76b in ?? () from /usr/lib/libcurl.so.4
#3 0x00007ffff7984349 in ?? () from /usr/lib/libcurl.so.4
#4 0x00007ffff7984b11 in curl_multi_perform () from /usr/lib/libcurl.so.4
#5 0x00007ffff797b977 in curl_easy_perform () from /usr/lib/libcurl.so.4
#6 0x0000000000400f42 in flood (structPointer=0x7fffffffe060) at httpflood.c:57
#7 0x00007ffff7bc5124 in start_thread () from /usr/lib/libpthread.so.0
#8 0x00007ffff768b4bd in clone () from /usr/lib/libc.so.6
I don't see why this call would cause a segfault. Any ideas?
I know you're meant to only provide a small sample of relevant code, but here I am providing the whole thing due to the fact that I feel like context is needed here. (The fact it is being run from many threads and such.)
This is your problem:
for (i = 0; i < threadnum; i++) {
struct flood_data ddosData;
memset(&ddosData, 0, sizeof(struct flood_data));
ddosData.url = url;
ddosData.proxy = getProxy();
pthread_create(&threads[i], NULL, flood, (void *)&ddosData);
}
You're allocating a single struct flood_data instance on the stack and passing that to all of the new threads simultaneously. Each time you iterate through the loop, you overwrite the same instance at the same time that threads spawned from earlier iterations might be trying to read from it. Major undefined behavior.
The proper way to do this is to dynamically allocate a separate instance for each thread:
for (i = 0; i < threadnum; i++) {
struct flood_data *ddosData = calloc(1, sizeof(*ddosData));
ddosData->url = url;
ddosData->proxy = getProxy();
pthread_create(&threads[i], NULL, flood, ddosData);
}
...
void *flood(void *structPointer) {
struct flood_data *data = structPointer;
char *bootable = data->url;
char *proxy = data->proxy;
free(data);
...
}
As pointed out in the comments, you also need to check your system calls for failure. You should validate that all of your calls to fopen() are succeeding, as you could very well be hitting the maximum number of file descriptors open in your process. Rather than opening up a file to /dev/null, why don't you just set a no-op write function with the CURLOPT_WRITEFUNCTION option?
static size_t noop_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
// Do nothing
return size * nmemb;
}
...
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &noop_write_callback);
// No need to call fopen("/dev/null") or set CURLOPT_WRITEDATA now
I'm attempting to integrate zeromq into a glib main loop, but I can't figure out why my program is segfault'ing.
Here's the function that guarantees a segfault after also running g_main_loop_run(loop):
/** set poll fn to operate on zmq or unix sockets */
g_main_context_set_poll_func( g_context, (GPollFunc) zmq_poll );
I thought this would work, considering that zmq_poll shares the same structure as poll, and calling this same function with s/zmq_poll/poll/ works fine.
Stripped version of my code with it still segfault'ing: http://paste.pocoo.org/show/568289/.
(untested) Full version: http://paste.pocoo.org/show/568292/.
Stacktrace:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6a2bd50 in ?? ()
from /usr/lib/libzmq.so.1
(gdb) bt
#0 0x00007ffff6a2bd50 in ?? ()
from /usr/lib/libzmq.so.1
#1 0x00007ffff6a34b4d in zmq_getsockopt ()
from /usr/lib/libzmq.so.1
#2 0x00007ffff6a34e1b in zmq_poll ()
from /usr/lib/libzmq.so.1
#3 0x00007ffff6c89dc8 in ?? ()
from /usr/lib/libglib-2.0.so.0
#4 0x00007ffff6c8a5f2 in g_main_loop_run ()
from /usr/lib/libglib-2.0.so.0
#5 0x0000000000402978 in main (argc=1,
argv=0x7fffffffe5e8) at server.c:229
Compile the code (assuming you have gstreamer and zeromq installed) with:
gcc --debug `pkg-config gstreamer-0.10 --libs` -lzmq `pkg-config gstreamer-0.10 --cflags` -o test test.c
What am I doing wrong?
Any and all help is appreciated, thanks.
EDIT: Got it to work with what alexander suggested by using this function as my poll replacement:
gint zmq_poll_adapter(GPollFD *ufds, guint nfsd, gint timeout_)
{
zmq_pollitem_t ufds0[nfsd];
int i;
for (i = 0; i < nfsd; i++)
{
ufds0[i].socket = NULL;
ufds0[i].fd = ufds[i].fd;
ufds0[i].events = ufds[i].events;
ufds0[i].revents = ufds[i].revents;
}
zmq_poll(ufds0, nfsd, timeout_);
}
To be honest I'm not even sure how this worked as well as it did, but I'm a C newbie and have little idea how to make a more adaptive adapt().
Expected data format for GPollFunc callback is
struct GPollFD {
#if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8
gint64 fd;
#else
gint fd;
#endif
gushort events;
gushort revents;
};
Expected data format for zmq_poll is
typedef struct
{
void //*socket//;
int //fd//;
short //events//;
short //revents//;
} zmq_pollitem_t;
The solution is to write adapter and pass it to g_main_context_set_poll_func:
gint zmq_poll_adapter(GPollFD *ufds, guint nfsd, gint timeout_)
{
zmq_pollitem_t *ufds0 = adapt(ufds, nfsd);
zmq_poll(ufds0, nfsd, timeout_);
}
I have the following c program which launches a Gtk Program on ubuntu:
#include <unistd.h>
int main( int argc, const char* argv[] )
{
char *args[2] = { "testarg", 0 };
char *envp[1] = { 0 };
execve("/home/michael/MyGtkApp",args,envp);
}
I get "Gtk-WARNING **: cannot open display: " and my program is not launched.
I have tried setting char *envp[1] = {"DISPLAY:0.0"}; and execute 'xhost +' , I don't see the 'cannot open display' warning, but my program is still not launched.
Does anyone know how to fix my problem?
Thank you.
char *envp[1] = {"DISPLAY:0.0"};
Very wrong. Separate name and value by =, and terminate the list by NULL like args.
char *envp[2] = {"DISPLAY=:0.0", 0};
or better yet, don't hard-code the display, and use Xauthority too.
char *display = 0, *xauthority = 0;
char *envp[3] = {0};
asprintf(&display, "DISPLAY=%s", getenv("DISPLAY"));
asprintf(&xauthority, "XAUTHORITY=%s", getenv("XAUTHORITY"));
envp[0] = display;
envp[1] = xauthority;
I'm left wondering why you give the program such a sparse environment, though – depending on how you're configured and what you're using, Gtk+ may not be entirely happy with DBUS_SESSION_BUS_ADDRESS,GTK2_RC_FILES,GTK_IM_MODULE,HOME,LANG*,LC_*,PATH,XDG_* etc. environment variables gone. Why don't you just use execv or execvp, and just allow the parent's environment to be inherited?
I tried setting the envp to this, and it tries to launch my application.
char *envp[2] = { (char*)"DISPLAY=:0.0", 0 };
But I end up with a Segmentation Fault (my program runs fine when I launch it via command prompt:
(gdb) bt
#0 0x007e5f4e in g_main_context_prepare () from /lib/libglib-2.0.so.0
#1 0x007e6351 in ?? () from /lib/libglib-2.0.so.0
#2 0x007e6b9f in g_main_loop_run () from /lib/libglib-2.0.so.0
#3 0x0041b419 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0
#4 0x08049191 in main (argc=1, argv=0xbffffed4)
at main.c:471
If you ended up with a segmentation fault in MyGtkApp, your app is buggy and this has nothing to do with the program you posted.
Some suggestions:
I would never use 0 instead of NULL, it is a pain generator on 64 bit platforms: use at least (void *) 0;
no need to specify the array size if you're initializing it;
the first argument is (by convention) always the program name, so:
char *args[] = { "/home/michael/MyGtkApp", "testarg", (void *) 0 };