Reputation: 216
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 :
Upvotes: 5
Views: 5353
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