2016-02-04 115 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

相關問題