有一段时间,我无法再调试我的应用程序,每次在调试模式下启动它时都会崩溃。另一方面,只执行它就可以正常运行。
我做了很多不同配置的测试:
在Linux上,没问题,一切正常。
在Windows 7或10上,应用程序在打开后立即崩溃,并显示以下消息(两次):
Microsoft Visual C ++运行时库: 此应用程序已请求运行时以不寻常的方式终止它。
输出面板提供以下信息:
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
编译输出中没有提到问题。
在网上搜索,我无法找到问题的根源。
你知道如何解决这一点吗?
提前谢谢。
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
以下是错误代码的片段:
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
}
}
我担心的是这个警告:部分未找到.gnu_debuglink
为什么在.exe.debug文件中找不到此部分?
答案 0 :(得分:2)
.gnu_debuglink是gdb用于将单独的调试信息与实际二进制文件相关联的机制。它可能与插件加载引起的崩溃有关,或者gdb可能只是通知它与正在加载的其他插件有关。
我怀疑你的问题可能与Qt bug引起的OOM有关,Qt 5.9.5中的fixed。同时,你可以测试是否剥离qtgeoservices_mapboxgld.dll文件可以防止崩溃(在bugreport评论中说过)。
此外,为了使您的代码更健壮,您应该从Qt.createQmlObject中捕获异常,因为如果插件加载失败,则会抛出错误:
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)
}
}
&#34;传递给C运行时函数的参数无效。&#34;警告消息可能是由Qt在上述错误发生时调用某些C运行时函数引起的。
用于跟踪的通用解决方案&#34;传递给C运行时函数的无效参数。&#34;起源由Dennis Yurichev提供。下面,我为您提供了如何操作的步骤(来自我的环境的路径)。
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();
}
在命令提示符中:
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)
我们可以看到用__stream = 0x0调用fprintf会导致段错误。
修改强>
我使用mapviewer示例进行了一些测试。当我在调试模式下运行它时:
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
然后我剥离了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
在调试模式下剥离运行成功后:
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
这样你至少应该在你的应用程序漏洞中取得进展。
你使用的是哪个Qt和mingw版本?