@Publicnamer said in QString optimized out, causes segmentation fault:
Anyone know why this might happen?
It really does crash for me compiling with G++ and with clang.
Yes, the code presented in the original post will crash for exactly the reason described by @mchinand. The result almost certainly will not change with compiler or optimization level, but might be more informative if compiled for debug.
Here is your example, or something "virtually identical" to it:
#include <QCoreApplication>
#include <QString>
#include <QVector>
#include <QDebug>
struct mystruct {
QString s;
int i;
};
int main (int argc, char **argv) {
QCoreApplication app(argc, argv);
qDebug() << "Starting";
QVector<mystruct> v; // <<<< this vector has no members
v[3].s = "abc";
v[3].i = 123;
qDebug() << v[3].s << v[3].i;
qDebug() << "Ending";
qDebug() << "Ending";
return 0;
}
Here is what happens when compiled for release (-O2 optimization, gcc version 9.3.0)
chrisw@newton:/tmp/crash$ qmake -v
QMake version 3.1
Using Qt version 5.12.8 in /usr/lib/x86_64-linux-gnu
chrisw@newton:/tmp/crash$ qmake CONFIG+=release
Info: creating stash file /tmp/crash/.qmake.stash
chrisw@newton:/tmp/crash$ make
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I. -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o main.o main.cpp
g++ -Wl,-O1 -o crash main.o /usr/lib/x86_64-linux-gnu/libQt5Gui.so /usr/lib/x86_64-linux-gnu/libQt5Core.so /usr/lib/x86_64-linux-gnu/libGL.so -lpthread
chrisw@newton:/tmp/crash$ ./crash
Starting
Segmentation fault (core dumped)
... and for debug (no optimization at all, and debug symbols):
chrisw@newton:/tmp/crash$ make distclean
rm -f moc_predefs.h
rm -f main.o
rm -f *~ core *.core
rm -f crash
rm -f .qmake.stash
rm -f Makefile
chrisw@newton:/tmp/crash$ qmake CONFIG+=debug
Info: creating stash file /tmp/crash/.qmake.stash
chrisw@newton:/tmp/crash$ make
g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_GUI_LIB -DQT_CORE_LIB -I. -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o main.o main.cpp
g++ -o crash main.o /usr/lib/x86_64-linux-gnu/libQt5Gui.so /usr/lib/x86_64-linux-gnu/libQt5Core.so /usr/lib/x86_64-linux-gnu/libGL.so -lpthread
chrisw@newton:/tmp/crash$ ./crash
Starting
ASSERT failure in QVector<T>::operator[]: "index out of range", file /usr/include/x86_64-linux-gnu/qt5/QtCore/qvector.h, line 437
Aborted (core dumped)
With/without optimization, same result, ergo not optimization induced.
Debug version tells you exactly why it crashed, if only you looked.
gdb, on a debug version, will tell you which line of your code triggered it:
chrisw@newton:/tmp/crash$ gdb ./crash
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
...
Reading symbols from ./crash...
(gdb) run
Starting program: /tmp/crash/crash
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Starting
ASSERT failure in QVector<T>::operator[]: "index out of range", file /usr/include/x86_64-linux-gnu/qt5/QtCore/qvector.h, line 437
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1 0x00007ffff7694859 in __GI_abort () at abort.c:79
#2 0x00007ffff7ae3aad in QMessageLogger::fatal(char const*, ...) const () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#3 0x00007ffff7ae2f46 in qt_assert_x(char const*, char const*, char const*, int) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#4 0x0000555555555d85 in QVector<mystruct>::operator[] (this=0x7fffffffdf60, i=3) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qvector.h:437
#5 0x0000555555555453 in main (argc=1, argv=0x7fffffffe0b8) at main.cpp:16
(gdb)
If you correct your erroneous code to, for example:
#include <QCoreApplication>
#include <QString>
#include <QVector>
#include <QDebug>
struct mystruct {
mystruct(): s(), i(0) { } // <<<< a constructor so the int is never undefined
QString s;
int i;
};
int main (int argc, char **argv) {
QCoreApplication app(argc, argv);
qDebug() << "Starting";
QVector<mystruct> v(4); // <<<< this vector actually has 4 default constructed members
v[3].s = "abc";
v[3].i = 123;
qDebug() << v[3].s << v[3].i;
qDebug() << "Ending";
return 0;
}
Then, oddly, it does not crash:
chrisw@newton:/tmp/crash$ make
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I. -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -o main.o main.cpp
g++ -Wl,-O1 -o crash main.o /usr/lib/x86_64-linux-gnu/libQt5Gui.so /usr/lib/x86_64-linux-gnu/libQt5Core.so /usr/lib/x86_64-linux-gnu/libGL.so -lpthread
chrisw@newton:/tmp/crash$ ./crash
Starting
"abc" 123
Ending