2016-02-04 97 views
1

的Qt应用程序崩溃,甚至调试模式下,它就是我得到:如何获得有关该错误的更多信息?

宣扬: “的isEmpty()!” 在文件 C:\ Qt的\ Qt5.5.0 \ 5.5 \ mingw492_32 \包括\ QtCore/qlist.h,线321

该行的文件指向:

inline void removeLast() { Q_ASSERT(!isEmpty()); erase(--end()); } 

但我想更多的信息。就像源代码中的哪一行正在使用它(来自搜索,没有直接调用removeLast()完成)。 这可能吗?

+1

任何人都可以在没有看到您的代码的情况下回答问题? –

+0

你是通过代码来找出发生的地方吗? – NathanOliver

+0

@RSahu:这是来自一个很大的代码库,我甚至不知道错误来自哪里,这就是为什么我问我如何知道更多。 – Jack

回答

1

就像源代码中的哪一行正在使用它(从搜索中,没有直接调用removeLast()done)。这可能吗?

不幸的是assert()Q_ASSERT()宏只是表明条件是错误的,而不是哪些代码导致这些条件。

尤其是如果多次调用和/或从很多地方调用,断言对于检测实际导致它的代码没有什么帮助。


您可以设置isEmpty()条件的条件断点,如果这是可以和您的调试器支持。

如果您有权访问调试符号,则还可以在标准abort()函数中设置断点。


如果有没有,如果你有充分的访问源代码(你有在头内联函数)可以解决这方面的缺陷。我经常要去的方式,就是暂时改变这种代码

void removeLast() 
{ 
    if(isEmpty()) { // <<<<<<<<<<< Put an encapsulating if clause here 
     return; // <<<<<<<<<<<< set breakpoint  
    } 
    Q_ASSERT(!isEmpty()); erase(--end()); 
} 

,并设置一个断点调试器。当从调试器运行代码时命中断点时,我将检查调用堆栈以查看其来源。

+0

它是否有区别,这是从库中的Qt函数而不是OP的代码? – NathanOliver

+0

@NathanOliver:它的确如此,因为你不应该修改Qt来调试代码中的问题。 – peppe

+0

@NathanOliver因为有所作为。有点编辑我的答案。尽管该技术特别有用,但我可以在其中更改源代码。否则,有条件的断点可能会有帮助。 –

3

如果你在调试器中运行你的程序,它将停止断言,你将能够检查堆栈跟踪。例如用此程序在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; 
} 

当你运行它:

(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 

断言停止调试器,你可以要求堆栈跟踪:

(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 

你可以看到removeLastpop_back调用,我的代码从第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 

在这里,您可以检查该帧中其他变量的值。

如果您使用的是Qt Creator,请参见Viewing Call Stack Trace

+0

第一次输出是我期待的。我无法管理在Qt之外打开一个调试版本。因此,我不应该'gdb myfile.exe',而应该在Qt cretor中执行它。查看堆栈不会导致相同的行为。您发布的代码作为示例在C:\ Qt \ Qt5.5.0 \ 5.5 \ mingw492_32 \ include \ QtCore/qlist中运行并崩溃时出现Microsoft Visual C++运行时错误,并且只有一个'ASSERT:“!isEmpty() h,第321行 '在控制台输出窗口中。调用堆栈跟踪在Qt创建器中为空。这不是当我运行这个代码时:'char * p = 0; * p ='a';' – Jack

+0

Someway调试器在这种情况下不会捕获assert()故障 – Jack

+0

为了使它更短,如果我使用示例中的qlist运行代码,它会崩溃,并显示相同的错误消息在我的问题。堆栈视图看起来像这样:http://prntscr.com/9ztq44但如果我跑'char * p = 0; * p ='a';'看起来正是我想要的东西http://prntscr.com/9ztq7m – Jack

相关问题