kontiki
kontiki

Reputation: 216

Runtime crashes when debugging with qtcreator

For some time, I can't debug anymore my application which crashes each time I launch it in debug mode. On the other hand, it runs fine when only execute it.

I did many tests with different configurations:

On Linux, no problem, everything works fine.

On windows 7 or 10 the application crashes as soon as it is opened, with the following message (twice) :

Microsoft Visual C++ Runtime Library : This application has requested the Runtime to terminate it in an unusual way.

The output panel gives the following information:

Debugging starts
section .gnu_debuglink not found in ...\build-Integration GspvMapviewer-Desktop_Qt_5_9_2_MinGW_32bit-Debug\debug\Integration GspvMapviewer.exe.debug
QML debugging is enabled. Only use this in a safe environment.
QML Debugger: Waiting for connection on port 49727...
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
ASSERT: "!m_thread.isRunning()" in file qqmldebugserver.cpp, line 655
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
Debugging has finished

No problem mentioned in compilation output.

Searching the net, I can't find track on the origin of the problem.

Would you know how to solve this point ?

Thank you in advance.

EDIT1

.pro

QT += quick positioning widgets
CONFIG += c++11

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
    main.cpp \
    waypointsfilter.cpp

RESOURCES += gspv.qrc \
    resource.qrc

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

HEADERS += \
    waypointsfilter.h \
    waypointsmodel.h \
    airport.h \
    waypoint.h \
    airportsmodel.h \
    landmark.h \
    runwaymodel.h

OTHER_FILES +=main.qml \
    helper.js \
    images/marker.png \
    images/scale.png \
    images/scale_end.png \
    map/MapComponent.qml \
    map/Marker.qml \
    map/MapSliders.qml \
    menus/MainMenu.qml \
    forms/Message.qml \
    forms/MessageForm.ui.qml

DISTFILES += \
    forms/SplitInterface.qml \
    forms/IME.qml \
    map/SimpleMap.qml \ 
    map/Airport.qml \
    images/BlackWaypoint.bmp \
    map/Runway.qml \
    forms/InitialAirport.qml

main.cpp

#include "waypointsmodel.h"
#include "waypointsfilter.h"
#include "airportsmodel.h"
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>
#include <QDateTime>


int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication app(argc, argv);


    WaypointsModel model;
    AirportsModel apModel;

    QVariantMap parameters;
    parameters[QStringLiteral("esri.useragent")] = QStringLiteral("Générateur Simplifié de Plans de Vol");

    model.readFromCSV(QCoreApplication::applicationDirPath() + "/files/Waypoints.txt");
    apModel.readFromTXT(QCoreApplication::applicationDirPath() + "/files/Airports.txt");

    WaypointsFilter proxyModel(&model);


    QQmlApplicationEngine engine;
    engine.addImportPath(QStringLiteral(":/imports"));

    engine.rootContext()->setContextProperty("waypointsFilter", &proxyModel);
    engine.rootContext()->setContextProperty("airportsModel", &apModel);

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    QObject::connect(&engine, SIGNAL(quit()), qApp, SLOT(quit()));

    QObject *item = engine.rootObjects().first();
    Q_ASSERT(item);


// The crash occurs after this line is executed
    QMetaObject::invokeMethod(item, "initializeProviders",
                              Q_ARG(QVariant, QVariant::fromValue(parameters)));


    return app.exec();
}

EDIT2

Here is snippet of the faulty code :

function getPlugins()
{
    //crash is here !
    var plugin = Qt.createQmlObject ('import QtLocation 5.6; Plugin {}', mainWindow)
    var myArray = new Array()
    for (var i = 0; i<plugin.availableServiceProviders.length; i++) {
        var tempPlugin = Qt.createQmlObject ('import QtLocation 5.6; Plugin {name: "' + plugin.availableServiceProviders[i]+ '"}', mainWindow)

        if (tempPlugin.supportsMapping()
                && !(tempPlugin.name === "itemsoverlay")
                && !(tempPlugin.name === "here")
                && !(tempPlugin.name === "mapbox")
                && !(tempPlugin.name === "mapboxgl"))
            myArray.push(tempPlugin.name)
    }

    myArray.sort()
    return myArray
}

function initializeProviders(pluginParameters)
{

    var parameters = new Array()
    for (var prop in pluginParameters){
        var parameter = Qt.createQmlObject('import QtLocation 5.6; PluginParameter{ name: "'+ prop + '"; value: "' + pluginParameters[prop]+'"}',mainWindow)
        console.log ("plugin name :" + prop + "value : " +pluginParameters[prop] )
        parameters.push(parameter)
    }
    mainWindow.parameters = parameters
    var plugins = getPlugins()
    mainMenu.providerMenu.createMenu(plugins)
    for (var i = 0; i<plugins.length; i++) {
        if (plugins[i] === "esri")
            mainMenu.selectProvider(plugins[i]) //Génère la création de la carte par déclenchement de onSelectProvider
    }
}

My concern is this warning : section .gnu_debuglink not found

Why this section is not found into the .exe.debug file ?

Here is the status of debugging just before crash : Here is the status of debugging just before crash

and after crash : debug after crash

Upvotes: 5

Views: 5353

Answers (1)

talamaki
talamaki

Reputation: 5472

.gnu_debuglink is a mechanism that gdb uses to relate the separate debug info to the actual binary. It might be related to the crash caused by plugin loading or gdb might just inform it related to some other plugin being loaded.

I suspect your problem could be related to OOM caused by a bug in Qt which will be fixed in Qt 5.9.5. Meanwhile, you could test if stripping the qtgeoservices_mapboxgld.dll file prevents the crash (that was said in the bugreport comments).

Also, to make your code more robust you should catch exceptions from Qt.createQmlObject because if plugin loading fails it throws error:

try {
    var newObject = Qt.createQmlObject('import QtLocation 5.6; ...);
} catch (error) {
    console.log ("Error loading QML : ")
    for (var i = 0; i < error.qmlErrors.length; i++) {
        console.log("lineNumber: " + error.qmlErrors[i].lineNumber)
        console.log("columnNumber: " + error.qmlErrors[i].columnNumber)
        console.log("fileName: " + error.qmlErrors[i].fileName)
        console.log("message: " + error.qmlErrors[i].message)
    }
}

"Invalid parameter passed to C runtime function." warning messages a probably caused by Qt calling some C runtime functions when the above mentioned bug hits.

Generic solution for tracking "Invalid parameter passed to C runtime function." origins has been provided by Dennis Yurichev. Below, I provide you steps how to do it (paths from my env).

QML:

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    function initializeProviders(anObject) {
        for (var prop in anObject) {
            console.log("Object item:", prop, "=", anObject[prop])
        }
    }

    Text {
        id: textLabel
        anchors.centerIn: parent
        text: qsTr("text")
    }
}

C++:

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    QVariantMap parameters;
    parameters[QStringLiteral("esri.useragent")] = QStringLiteral("Générateur Simplifié de Plans de Vol");

    QObject *item = engine.rootObjects().first();
    Q_ASSERT(item);

    QMetaObject::invokeMethod(item, "initializeProviders",
                              Q_ARG(QVariant, QVariant::fromValue(parameters)));

    // Generate error: file open fails
    FILE *pFile = fopen (NULL,"w");
    // fputs with invalid file displays in debug mode "Invalid parameter passed to C runtime function."
    fputs("abc",pFile);
    // fprintf with invalid file crashes the program
    fprintf(pFile, "def\n");

    return app.exec();
}

In command prompt:

C:\> SET PATH=%PATH%;C:\Qt\5.9.4\mingw53_32\bin
C:\> cd proj\build-quickTest-Desktop_Qt_5_9_4_MinGW_32bit-Debug\debug
C:\> C:\Qt\Tools\mingw530_32\bin\gdb quickTest.exe
(gdb) break OutputDebugStringA
Function "OutputDebugStringA" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (OutputDebugStringA) pending.
(gdb) r
when it breaks print the backtrace
(gdb) bt
<backtrace...>
(gdb) c
Continuing.
warning: QML debugging is enabled. Only use this in a safe environment.
(gdb) bt
<backtrace...>
(gdb) c
Continuing.
warning: qml: Object item: esri.useragent = Générateur Simplifié de Plans de Vol


Breakpoint 1, 0x74d535fc in OutputDebugStringA ()
   from C:\Windows\syswow64\KernelBase.dll
(gdb) bt
#0  0x74d535fc in OutputDebugStringA ()
   from C:\Windows\syswow64\KernelBase.dll
#1  0x754569c4 in msvcrt!_chkesp () from C:\Windows\syswow64\msvcrt.dll
#2  0x754569d0 in msvcrt!_chkesp () from C:\Windows\syswow64\msvcrt.dll
#3  0x00010001 in ?? ()
#4  0x7543b9b7 in msvcrt!_ftol2_sse_excpt ()
   from C:\Windows\syswow64\msvcrt.dll
#5  0x00000000 in ?? ()
(gdb) c
Continuing.
warning: Invalid parameter passed to C runtime function.

Program received signal SIGSEGV, Segmentation fault.
0x770a2302 in ntdll!RtlEnterCriticalSection ()
   from C:\Windows\SysWOW64\ntdll.dll
(gdb) bt
#0  0x770a2302 in ntdll!RtlEnterCriticalSection ()
   from C:\Windows\SysWOW64\ntdll.dll
#1  0x004080b7 in _lock_file ()
#2  0x00402fe1 in __mingw_vfprintf ()
#3  0x00401656 in fprintf (__stream=0x0,
    __format=0x40b1fa <qMain(int, char**)::{lambda()#3}::operator()() const::qst
ring_literal+154> "def\n")
    at C:/Qt/Tools/mingw530_32/i686-w64-mingw32/include/stdio.h:289
#4  0x00401b2d in qMain (argc=1, argv=argv@entry=0x21319038)
    at ..\quickTest\main.cpp:32
#5  0x00402f05 in WinMain@16 () at qtmain_win.cpp:104
#6  0x0040949d in main ()
(gdb)

We can see that fprintf is called with __stream=0x0 which causes the segfault.

Edit:

I did some testing with mapviewer example. When I ran it in debug mode:

Debugging starts
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
QMutex: destroying locked mutex
Debugging has finished

Then I stripped qtgeoservices_mapboxgld.dll:

C:\...> SET PATH=C:\Qt\5.9.4\mingw53_32\bin;%PATH%
C:\...> cd C:\Qt\5.9.4\mingw53_32\plugins\geoservices
C:\...> strip qtgeoservices_mapboxgld.dll

After stripping running in debug mode succeeded:

qml: initializeProviders: osm.useragent = QtLocation Mapviewer example
qml: getPlugins: esri
qml: getPlugins: pushing esri
qml: getPlugins: mapbox
qml: getPlugins: pushing mapbox
qml: getPlugins: mapboxgl
qml: getPlugins: pushing mapboxgl
qml: getPlugins: here
qml: getPlugins: pushing here
qml: getPlugins: itemsoverlay
qml: getPlugins: pushing itemsoverlay
qml: getPlugins: osm
qml: getPlugins: pushing osm

This way you should at least get forward in your app bug hunting.

Which Qt and mingw version are you using?

Upvotes: 2

Related Questions