Project

General

Profile

Mysterious segfault on exit when using QNetworkAccessManager

Added by Róbert Čerňanský over 8 years ago

Hi,

I'm trying to use QNetworkAccessManager class from Qt 5 but Audacious mysteriously segfaults upon exit if this class is instantiated in a plugin. It does not matter if the plugin was active or not at the moment when user closed Audacious; it only has to be active at least once in the application lifetime and constructor of QNetworkAccessManager has to be called. The crash actually occurs outside of Audacious code after exit from main():

Audacious' main.cc:

...
    aud_cleanup ();
    initted = false;

    return EXIT_SUCCESS;
} <-- Crashes here!

The backtrace is not very helpful (even on a system with debug symbols):

#0 0x00007fffdacb7e69 in ?? ()
#1 0x0000000000000000 in ?? ()

I found out that crash does not occur if g_module_close() is not called for the particular plugin (the one which contains QNetworkAccessManager).

plugin_load.cc, function static void plugin_unload (LoadedModule & loaded):

...
#ifndef VALGRIND_FRIENDLY
    g_module_close (loaded.module);  <-- if not called, Audacious exits normally
#endif
}

This is the minimal test plugin the crash is reproducible with:

#define AUD_PLUGIN_QT_ONLY
#include <QNetworkAccessManager>
#include <QWidget>
#include <libaudcore/plugin.h>

class QnamTest: public GeneralPlugin {
public:
    static constexpr PluginInfo pluginInfo = {"QNetworkAccessManager Test", PACKAGE};
    constexpr QnamTest(): GeneralPlugin(pluginInfo, false) { }
    void* get_qt_widget() override;
};

void* QnamTest::get_qt_widget() {
    auto widget = new QWidget;
    // creation of QNetworkAccessManager instance causes Audacious to crash upon exit; the same happens also
    // if it is created on stack (thus destroyed when this function ends) and without the parent (the
    // 'widget' argument)
    new QNetworkAccessManager(widget); // crashes also if QNetworkAccessManager is on stack and with no parent
    return widget;
}

EXPORT QnamTest aud_plugin_instance;

Anyone have a clue what might be wrong?


Replies (4)

RE: Mysterious segfault on exit when using QNetworkAccessManager - Added by John Lindgren over 8 years ago

Just a hunch, but does the crash go away if you link libaudcore to -lQt5Network?

RE: Mysterious segfault on exit when using QNetworkAccessManager - Added by John Lindgren over 8 years ago

We can assume that something is registering an atexit() handler within Qt5Network. Then the module is unloaded before exit(), leaving a pointer to an address that's no longer valid. See if you can reduce your test case so that it stands alone (without Audacious), then report a bug to the Qt project.

RE: Mysterious segfault on exit when using QNetworkAccessManager - Added by Róbert Čerňanský over 8 years ago

I do not know how should I reproduce it alone I'm afraid. I've tried to create a small library that uses QNetworkAccessManager and an app (not linked to Qt5Network) that uses the lib but it works as expected. The main() function of the app looks like this:

#include <iostream>
#include <QApplication>
#include "qnam_lib.h" 
#include "qnam_test.h" 

using namespace std;

static qnam_lib* qnl = nullptr;

static void onExit() {
    cout << "onExit" << endl;
    delete qnl;
}

int main(int argc, char** argv) {
    atexit(onExit);
    QApplication app(argc, argv);
    qnl = new qnam_lib();
    qnam_test qnam_test;
    qnam_test.show(); // shows a "Hello World" window
    return app.exec();
}
    (1-4/4)