Reputation: 16724
An Qt application is crashing and even debugger mode it's all I get:
ASSERT: "!isEmpty()" in file C:\Qt\Qt5.5.0\5.5\mingw492_32\include\QtCore/qlist.h, line 321
That line in the file points to:
inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); }
But I'd like more information. Like what line exactly in the source code is using it (from search, no direct call to removeLast()
done).
Is this possible?
Upvotes: 2
Views: 2119
Reputation: 2917
If you run your program in a debugger, it will stop on the assertion and you'll be able to examine the stack trace. For example with this program in GDB :
#include <QList>
int main(int argc,char* argv[])
{
QList<int> my_list;
my_list.append(1);
my_list.pop_back(); // 1
my_list.pop_back(); // 2
return 0;
}
When you run it :
(gdb) r
Starting program: /home/leiaz/tmp/qttest/build/proj
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
ASSERT: "!isEmpty()" in file /usr/include/qt/QtCore/qlist.h, line 321
Program received signal SIGABRT, Aborted.
0x00007ffff61275f8 in raise () from /usr/lib/libc.so.6
The assertion stop the debugger, and you can ask for the stack trace :
(gdb) backtrace
#0 0x00007ffff61275f8 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff6128a7a in abort () from /usr/lib/libc.so.6
#2 0x00007ffff6dc11e1 in QMessageLogger::fatal(char const*, ...) const () from /usr/lib/libQt5Core.so.5
#3 0x00007ffff6dbc34e in qt_assert(char const*, char const*, int) () from /usr/lib/libQt5Core.so.5
#4 0x00000000004060aa in QList<int>::removeLast (this=0x7fffffffe4d0)
at /usr/include/qt/QtCore/qlist.h:321
#5 0x0000000000405de0 in QList<int>::pop_back (this=0x7fffffffe4d0)
at /usr/include/qt/QtCore/qlist.h:337
#6 0x0000000000405ad4 in main (argc=1, argv=0x7fffffffe5d8) at /home/leiaz/tmp/qttest/main.cc:9
You can see removeLast
was called by pop_back
and my code start at frame 6 :
(gdb) frame 6
#6 0x0000000000405ad4 in main (argc=1, argv=0x7fffffffe5d8) at /home/leiaz/tmp/qttest/main.cc:9
9 my_list.pop_back(); // 2
Here you can examine the values of other variables in that frame.
If you are using Qt Creator see Viewing Call Stack Trace.
Upvotes: 3
Reputation: 1
Like what line exactly in the source code is using it (from search, no direct call to removeLast() done). Is this possible?
Unfortunately assert()
or Q_ASSERT()
macros just show that the conditions were wrong, not which code was causing these conditions.
Especially if called many times and/or from many places, assertions aren't very helpful to detect what code actually was causing it.
You can set a conditional breakpoint for the isEmpty()
condition, if that's well supported with your debugger.
You can also set a breakpoint in the standard abort()
function, if you have access to the debug symbols.
If there's not, and if you have full access to the source code (which you have for a function inlined in a header) you can work around that deficiency. The way I'm usually going, is to change such code temporarily to
void removeLast()
{
if(isEmpty()) { // <<<<<<<<<<< Put an encapsulating if clause here
return; // <<<<<<<<<<<< set breakpoint
}
Q_ASSERT(!isEmpty()); erase(--end());
}
and set a debugger breakpoint. When the breakpoint is hit while running the code from the debugger, I'll examine the call stack to see where this came from.
Upvotes: 1