简体   繁体   中英

Q_ASSERT in Qt. How to get calling function

I am using QVector<double> in a lot of source files. When I run program it gives an error:

ASSERT failure in QVector<T>::operator[]: "index out of range", file C:/Qt/qt-5.5.0-x64-mingw510r0-seh-rev0/qt-5.5.0-x64-mingw510r0-seh-rev0/include/QtCore/qvector.h, line 401

I understand what that error means. However it links to qvector.h whick is not helpful, because I don't know which source gives that error. How can I find which of my source files gives that error?

If you are using QtCreator and GCC/GDB, try setting the Stop when qFatal() is called option.

Steps to set the option:

  1. Select Tools -> Options from the menu.
  2. Select Debugger in the list on the left.
  3. Select GDB Extended tab.
  4. Check Stop when qFatal() is called .
  5. Click Ok .

Run your application. QtCreator should stop and display a stack trace when the Q_ASSERT macro evaluates to false. You can use the stack trace to determine the file and line in your source code that called QVector<T>::operator[] .

I created a simple program to test. Note the bad index t[200] .

#include <QCoreApplication>
#include <QVector>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QVector<int> t;

    t << 1;
    t << 2;

    int x = t[1];
    int y = t[200];

    return a.exec();
}

Without the option set, I get the debug output in the Console and QtCreator shows some assembly language. With the option set, I get a stack trace as shown in the following image:

Qt堆栈跟踪

Note the stack trace indicates my problem is on line 14 in function main in file main.cpp .

Q_ASSERT within Qt is implemented as a macro. Q_ASSERT uses qFatal() as noted in the documentation for Q_ASSERT at http://doc.qt.io/qt-5/qtglobal.html#Q_ASSERT .

Thus, setting the option will cause QtCreator to stop on Q_ASSERT s.

Note that the application must be built in DEBUG mode. Per the documentation, the Q_ASSERT statements do nothing if QT_NO_DEBUG is set.

Tested in Windows 7 using QtCreator 3.5.1 and Qt 5.5.1.

You can us the qInstallMsgHandler function in Qt to also get you to where the issue happens.

If you implement the sample code on the provided link you can add something like the following in the myMessageOutput function:

if(QString(msg).conains("index out of range") == true) {
    qDebug() << "Out of range"; // <- put a breakpoint here.
} 

If the application hits the breakpoint you can also check the stack trace to see where the issue occurred in the same way that @esorton suggested.

PS: I was not aware of of the "GDB Extended" tab and the options in Qt Creator so this is what I normally did. The benefit of my suggestion is that you can trace any type of message like this.

Not sure why but doing what @esorton suggested my QtC gives me an assembly Disassembler (??) output without any help on where the issue occurred (perhaps something is broken with my setup, Ubuntu gcc 4.8 with Qt 5.4):

    Function: _Z11qt_assert_xPKcS0_S0_i
0x7f0c731757ea  <+0x003a>        24 08                          and    $0x8,%al
0x7f0c731757ec  <+0x003c>        00 00                          add    %al,(%rax)
0x7f0c731757ee  <+0x003e>        00 00                          add    %al,(%rax)
0x7f0c731757f0  <+0x0040>        48 c7 44 24 10 00 00 00 00     movq   $0x0,0x10(%rsp)
0x7f0c731757f9  <+0x0049>        e8 92 52 00 00                 callq  0x7f0c7317aa90 <_ZNK14QMessageLogger5fatalEPKcz>
0x7f0c731757fe                   66 90                          xchg   %ax,%ax

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM