uninitialized data passed to QStringList QCoreApplication::arguments()
-
I am observing access violation exceptions (see attached screenshot) due to uninitialized data when exec() (see the code below) calls QStringList QCoreApplication::arguments(), verified in Qt 6.8.3
CODE
int argc = 1; const char* argv[] = {"MyDll"," "," "}; qapp_pt = cv_new QGuiApplication(argc, (char**) argv); if (qapp_pt == NULL) { return(false); } QQmlApplicationEngine* QmlEngine; QmlEngine = cv_new QQmlApplicationEngine(); if (QmlEngine == NULL) { return(result); } // run QMLEngine and load Main.qml, QmlEngine->load(QUrl(QStringLiteral("qrc:/GuiModule/mydll/resource/Main.qml"))); // in this version loadFromModule() doesn't work, // maybe a different CMake configuration or a different call to loadFromModule ? // QmlEngine->addImportPath("mydll/resource"); // QmlEngine->loadFromModule("GuiModule","Main"); // exception thrown here !! result = qapp_pt->exec();
the code is inside a shared library (Qt project) the CMakeList.txt to create the project is
CMAKEFILE.TXT
cmake_minimum_required(VERSION 3.16) find_package(Qt6 REQUIRED COMPONENTS Quick Gui Core QmlImportScanner) qt_add_library(mydll SHARED mydll/mydllx.cpp ) qt_add_qml_module(mydll VERSION 1.28 URI GuiModule RESOURCE_PREFIX "/" NO_PLUGIN IMPORTS Quick Gui Qml Core SOURCES mydll/gxpage/test_page.cpp RESOURCES mydll/mydllresources.qrc QML_FILES mydll/resource/Main.qml ) set_target_properties(mydll PROPERTIES PREFIX "" OUTPUT_NAME "mydll" SUFFIX ".dll") # link QT-QML libraries and mylib target_link_libraries(mydll PRIVATE Qt6::Gui Qt6::Quick Qt::QuickControls2 ${CMAKE_BINARY_DIR}/mylib.lib ) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT /Ox") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /Ox") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
DISCUSSION
Qt should initialize (by default) all the vars passed to QCoreApplication but according many tests there are exceptions...
To solve the reported problem I think there are at least two options :
-
modify qcoreapplication.cpp and recompile (from source) Qt library, the problem is that when I edit / change qcoreapplication.cpp , run configure.bat and then compile there are several errors generated, probably I can't run configure but follow some other procedure, do you know if a detailed procedure to edit / modify source in Qt library is available for review ?
-
before to call qapp_pt->exec() (see the code above) call some method in Qt library to force a reliable initialization of all vars passed to QCoreApplication, do you know if there is a method which does that ?
Thank you for help !!
-
-
There must be a problem on your side. Please provide a minimal compileable example of the problem.
If there would be a problem with argv handling it would already be revealed long time ago.Btw: your argc is wrong when you want to pass a parameter it must be 2, not 1.
-
Cristian,
thank you for the comment,
I do not wish to pass parameters via argc / argv , just tested several combinations of argc /argv to see if the problem disappears, however passing the result of
const char* argv[] = {"MyDll"," "," "};
should be correct.
By the way problem is not about passing parameters, I do not care for that, the problem is about uninitialized vars in QCoreApplication (see the screenshot : argc = 318415888 ! )do you have answers to my questions :
modify qcoreapplication.cpp and recompile (from source) Qt library, the problem is that when I edit / change qcoreapplication.cpp , run configure.bat and then compile there are several errors generated, probably I can't run configure but follow some other procedure, do you know if a detailed procedure to edit / modify source in Qt library is available for review ? before to call qapp_pt->exec() (see the code above) call some method in Qt library to force a reliable initialization of all vars passed to QCoreApplication, do you know if there is a method which does that ?
-
Cristian,
thank you for the comment,
I do not wish to pass parameters via argc / argv , just tested several combinations of argc /argv to see if the problem disappears, however passing the result of
const char* argv[] = {"MyDll"," "," "};
should be correct.
By the way problem is not about passing parameters, I do not care for that, the problem is about uninitialized vars in QCoreApplication (see the screenshot : argc = 318415888 ! )do you have answers to my questions :
modify qcoreapplication.cpp and recompile (from source) Qt library, the problem is that when I edit / change qcoreapplication.cpp , run configure.bat and then compile there are several errors generated, probably I can't run configure but follow some other procedure, do you know if a detailed procedure to edit / modify source in Qt library is available for review ? before to call qapp_pt->exec() (see the code above) call some method in Qt library to force a reliable initialization of all vars passed to QCoreApplication, do you know if there is a method which does that ?
@rparon
What @Christian-Ehrlicher says is right, and I don't know why you might be thinking of modifying any Qt core files.Why don't you try printing out (
qDebug()
maybe?)QCoreApplication::arguments()
immediately after your creation ofQGuiApplication(argc, (char**) argv)
(and its test fornullptr
)?You should assume
If there would be a problem with argv handling it would already be revealed long time ago.
rather than a fault in Qt or any need to:
call some method in Qt library to force a reliable initialization of all vars passed to QCoreApplication
-
I am observing access violation exceptions (see attached screenshot) due to uninitialized data when exec() (see the code below) calls QStringList QCoreApplication::arguments(), verified in Qt 6.8.3
CODE
int argc = 1; const char* argv[] = {"MyDll"," "," "}; qapp_pt = cv_new QGuiApplication(argc, (char**) argv); if (qapp_pt == NULL) { return(false); } QQmlApplicationEngine* QmlEngine; QmlEngine = cv_new QQmlApplicationEngine(); if (QmlEngine == NULL) { return(result); } // run QMLEngine and load Main.qml, QmlEngine->load(QUrl(QStringLiteral("qrc:/GuiModule/mydll/resource/Main.qml"))); // in this version loadFromModule() doesn't work, // maybe a different CMake configuration or a different call to loadFromModule ? // QmlEngine->addImportPath("mydll/resource"); // QmlEngine->loadFromModule("GuiModule","Main"); // exception thrown here !! result = qapp_pt->exec();
the code is inside a shared library (Qt project) the CMakeList.txt to create the project is
CMAKEFILE.TXT
cmake_minimum_required(VERSION 3.16) find_package(Qt6 REQUIRED COMPONENTS Quick Gui Core QmlImportScanner) qt_add_library(mydll SHARED mydll/mydllx.cpp ) qt_add_qml_module(mydll VERSION 1.28 URI GuiModule RESOURCE_PREFIX "/" NO_PLUGIN IMPORTS Quick Gui Qml Core SOURCES mydll/gxpage/test_page.cpp RESOURCES mydll/mydllresources.qrc QML_FILES mydll/resource/Main.qml ) set_target_properties(mydll PROPERTIES PREFIX "" OUTPUT_NAME "mydll" SUFFIX ".dll") # link QT-QML libraries and mylib target_link_libraries(mydll PRIVATE Qt6::Gui Qt6::Quick Qt::QuickControls2 ${CMAKE_BINARY_DIR}/mylib.lib ) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT /Ox") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /Ox") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
DISCUSSION
Qt should initialize (by default) all the vars passed to QCoreApplication but according many tests there are exceptions...
To solve the reported problem I think there are at least two options :
-
modify qcoreapplication.cpp and recompile (from source) Qt library, the problem is that when I edit / change qcoreapplication.cpp , run configure.bat and then compile there are several errors generated, probably I can't run configure but follow some other procedure, do you know if a detailed procedure to edit / modify source in Qt library is available for review ?
-
before to call qapp_pt->exec() (see the code above) call some method in Qt library to force a reliable initialization of all vars passed to QCoreApplication, do you know if there is a method which does that ?
Thank you for help !!
@rparon said in uninitialized data passed to QStringList QCoreApplication::arguments():
cv_new
What is it? Do you have custom memory management? Could the problem be related to that?
-
-
Hi JonB,
thank you for the comment, I understand your point of view , yes I am debugging the launch, the vars are passed correctly to QGuiApplication(argc, (char**) argv) but then there are many other lines of code... and finally the app calls QCoreApplication::arguments() passing wrong data... sure I could put memory breakpoints to inspect possible operations on these vars... but it would take a lot of time to do that and I hope there is a shorter solution... what I need is to make sure they are properly initialized (before the call from QCoreApplication::arguments() ... -
Hi JonB,
thank you for the comment, I understand your point of view , yes I am debugging the launch, the vars are passed correctly to QGuiApplication(argc, (char**) argv) but then there are many other lines of code... and finally the app calls QCoreApplication::arguments() passing wrong data... sure I could put memory breakpoints to inspect possible operations on these vars... but it would take a lot of time to do that and I hope there is a shorter solution... what I need is to make sure they are properly initialized (before the call from QCoreApplication::arguments() ...@rparon said in uninitialized data passed to QStringList QCoreApplication::arguments():
what I need is to make sure they are properly initialized (before the call from QCoreApplication::arguments() ...
As I said, I do not know what this means. You need to show some minimal reproducible example. The code you showed should work e.g. if it's the
main()
of a program. If not you have done something wrong, perhaps after you calledQGuiApplication(argc, (char**) argv)
and beforeQGuiApplication::exec()
.Do you change
argc
orargv
? Very importantly, is yourQGuiApplication::exec()
really in the same function as theargv[]
variable? If it's actually in a different function your code will crash.QCoreApplication::arguments()
will get its answer fromQGuiApplication
's idea of the values you pass to it. If they have been corrupted you will lose. I don't see much of a shortcut to putting in a couple of breakpoints at judicious points, don't put in thousands just "divide and conquer" your code and refine depending where it goes wrong. -
Hi jsulm,
it is standard memory management :#define cv_new new
as far as I know Qt should work without problems with that but I don't know if it may create problems with automatic initialization of vars.. (I don't know the details of QCore...)
-
Hi JonB,
yes, it is all the code in main {...} , note it is a dll but that should not create problems except maybe when catching signals from (in this case) Windows system... I confirm that argc, argv passed to QGuiApplication(argc, (char**) argv) do not change...
From your answers I presume there is not a public method to reset / clear / redefine these vars
I would think the vars argc, argv passed to QGuiApplication(..) are the same passed from Qt to QStringList QCoreApplication::arguments() ....
so the problem could be to identify where these are modified... -
Hi JonB,
yes, it is all the code in main {...} , note it is a dll but that should not create problems except maybe when catching signals from (in this case) Windows system... I confirm that argc, argv passed to QGuiApplication(argc, (char**) argv) do not change...
From your answers I presume there is not a public method to reset / clear / redefine these vars
I would think the vars argc, argv passed to QGuiApplication(..) are the same passed from Qt to QStringList QCoreApplication::arguments() ....
so the problem could be to identify where these are modified... -
Hi JonB,
yes, it is all the code in main {...} , note it is a dll but that should not create problems except maybe when catching signals from (in this case) Windows system... I confirm that argc, argv passed to QGuiApplication(argc, (char**) argv) do not change...
From your answers I presume there is not a public method to reset / clear / redefine these vars
I would think the vars argc, argv passed to QGuiApplication(..) are the same passed from Qt to QStringList QCoreApplication::arguments() ....
so the problem could be to identify where these are modified...@rparon
Although you may really need a repro....
From your screenshot, can you please start by clicking the Show Call Stack and showing us (clearly) the stack, in case there is any useful clue there.And what is the
pppx.dll
? Is that your DLL? Theprops.exe
? Is that a main program of yours using the DLL?In the screenshot the whole
#if defined(Q_OS_WIN)
is "dimmed", indicating to me that symbol is not defined. Yet since the error shows "DLL"s are you not on Windows? -
Hi JonB,
thanks to C preprocessor, in that case cv_news is the same of new, but I understand your perplexity :-)
Yes, those are the names of the dll and executable.
About the Call Stack, sure, I attach the screenshot for your review....
@rparon
FWIW: You claim you get the error during yourresult = qapp_pt->exec();
. I think the call stack shows that is not the case and it dies duringQmlEngine->load(QUrl(QStringLiteral("qrc:/GuiModule/mydll/resource/Main.qml")));
What is the function
ppx.dll!edS(int stream)
?Can you please print out
QCoreApplication::arguments()
immediately above that line in your code. Is it right at that point? If so I am unconvinced the argc, argv it is looking at have anything to do with your argc, argv here. -
Hi JonB,
correct, the problem appears executing QmlEngine->load(....)
the function pppx.dll!edS(int stream) includes all the code to load Qt (see above)int argc = 1;
const char* argv[] = {"MyDll"," "," "};
qapp_pt = cv_new QGuiApplication(argc, (char**) argv);
.......
result = qapp_pt->exec();as far as I can see QCoreApplication::arguments() is not called before QmlEngine->load(QUrl...)....
-
Hi JonB,
correct, the problem appears executing QmlEngine->load(....)
the function pppx.dll!edS(int stream) includes all the code to load Qt (see above)int argc = 1;
const char* argv[] = {"MyDll"," "," "};
qapp_pt = cv_new QGuiApplication(argc, (char**) argv);
.......
result = qapp_pt->exec();as far as I can see QCoreApplication::arguments() is not called before QmlEngine->load(QUrl...)....
@rparon said in uninitialized data passed to QStringList QCoreApplication::arguments():
as far as I can see QCoreApplication::arguments() is not called before QmlEngine->load(QUrl...)....
I asked you to paste
qDebug() << QCoreApplication::arguments();
into your code immediately above
QmlEngine->load(QUrl...)
-
Hi JonB,
I have included the direct call just before load()QmlEngine = cv_new QQmlApplicationEngine(); if (QmlEngine == NULL) { return(result); } // direct call to inspect argc, argv QStringList c = QCoreApplication::arguments(); // run QMLEngine and load Main.qml, // note that only upper case file names are exported by default QmlEngine->load(QUrl(QStringLiteral("qrc:/GuiModule/pppx/resource/Main.qml")));
indeed the var argc shows a wrong value : -6213....
now the area of investigation is somewhat restricted.... I'll try to go further calling the same just afterqapp_pt = cv_new QGuiApplication(argc, (char**) argv);
to see what is happening , could it be related with new operator ?
-
a trick that I am testing is to put the initializing argc, argv values
int argc = 1; const char* argv[] = {"MyDll"," "," "};
as extern (equivalent to static)
this seems to solve the problem but I am surprised that Qt doesn't make an internal copy...
indeed I did assume that (the internal copy) and never presumed they must be static...
were you aware of that ? -
a trick that I am testing is to put the initializing argc, argv values
int argc = 1; const char* argv[] = {"MyDll"," "," "};
as extern (equivalent to static)
this seems to solve the problem but I am surprised that Qt doesn't make an internal copy...
indeed I did assume that (the internal copy) and never presumed they must be static...
were you aware of that ?@rparon said in uninitialized data passed to QStringList QCoreApplication::arguments():
a trick that I am testing is to put the initializing argc, argv values
int argc = 1; const char* argv[] = {"MyDll"," "," "};
as extern (equivalent to static)
this seems to solve the problem but I am surprised that Qt doesn't make an internal copy...
indeed I did assume that (the internal copy) and never presumed they must be static...
were you aware of that ?command line arguments are (from the perspective of the child) considered to be immutable, so I'm not aware of many apps that copy them, as why would you, unless you want to modify them?