QT核心程式設計之除錯技術 (7)

2021-06-09 04:09:26 字數 4379 閱讀 1194

qt應用程式的除錯可以通過ddd進行跟蹤除錯和列印各種除錯或警告資訊。ddd(data display debugger)是使用gdb除錯工具的圖形工具,它安裝在linux作業系統中,使用方法可參考ddd的幫助文件。下面說明如何列印各種除錯或警告資訊

1、命令列引數

當你執行q應用程式時,你可以指定幾個命令列引數來幫助你除錯。這幾個命令列引數說明如下:

-nograb 應用程式不再捕獲滑鼠或者鍵盤。當程式在linux下執行在gdb偵錯程式中時這個選項是預設的。

-dograb 忽略任何隱含的或明顯得-nograb。即使-nograb出現在命令列的最後,-dograb也會超過-nograb生效的。

-sync 在x同步模式下執行應用程式。同步模式強迫x伺服器立即執行每乙個x客戶端的請求,而不使用快取優化。它使得程式更加容易測試並且通常會更慢。-sync模式只對x11版本的qt有效。

2、列印警告和除錯訊息

qt使用三個全域性函式qdebug、qwarning和qfatal來列印警告和除錯資訊到標準錯誤輸出stderr(它在預設情況下為顯示屏,也可指定為檔案)。 這三個函式說明如下:

qdebug()用來列印除錯資訊,在除錯版本中輸出資訊,在發布版本中,函式將不起作用。

qwarning()用來在程式發生錯誤時列印警告資訊。

qfatal()用來列印致命錯誤訊息並且退出。

這些函式的qt實現在unix/x11下把文字列印到標準錯誤輸出(stderr),在windows下會列印到除錯器。你可以通過安裝乙個訊息處理器,qinstallmsghandler()來接收這些函式。

因為這3個函式的實現類似,這裡只分析函式qdebug,qdebug函式的引數格式與函式printf類似,列印格式化字串。qdebug函式列出如下(在src/tools/qglobal.cpp中):

static qtmsghandler handler = 0;  //指向使用者定義的列印輸出函式的控制代碼  

static const int qt_buffer_length = 8196; //內部buffer長度  

void qdebug( const char *msg, ... ) //msg格式化的需要列印的字串  

else   

}

在src/tools/qglobal.h中定義了qtmsghandler的函式型別,並將函式qinstallmsghandler定義為從動態庫中輸出函式名。這兩個定義列出如下:

typedef void (*qtmsghandler)(qtmsgtype, const char *);// q_export表示動態庫中輸出這個函式名q_export qtmsghandler qinstallmsghandler( qtmsghandler );

函式qinstallmsghandler被使用者用來定義乙個安裝處理函式,並返回以前定義的訊息處理函式的指標。在乙個應用程式中只能定義乙個訊息處理函式。恢復以前的訊息處理函式時,呼叫qinstallmsghandler(0)。函式列出如下(在src/tools/qglobal.cpp中):

qtmsghandler qinstallmsghandler( qtmsghandler h ) 

示例:應用qinstallmsghandler

下面的例子說明如果在乙個應用程式中安裝自己的程式執行資訊輸出函式。這個例子先定義了資訊輸出函式mymessageoutput,然後,在程式的main函式中安裝了資訊輸出函式。當這個應用函式執行時,就會使用函式mymessageoutput輸出執行資訊。**如下:

#include <

>

#include <

stdio.h

>

#include <

stdlib.h

>

void mymessageoutput( qtmsgtype type, const char *msg )//定義資訊輸出函式  

}   

int main( int argc, char **argv ) 

還有另外兩個列印物件資訊的除錯函式qobject::dumpobjecttree()和qobject::dumpobjectinfo()。它們只在程式除錯版本下,輸出資訊,在發布版本中,這兩個函式不起作用。函式qobject::dumpobjectinfo()列印乙個物件訊號連線等方面的資訊。函式qobject::dumpobjecttree()列印出子物件樹。

3、除錯巨集

在程式執行中還常使用巨集q_assert和q_check_ptr來輸出資訊,這兩個巨集說明如下:

(1)q_assert(b)中的b是乙個布林表示式,當b是false的時候,列印出類似的警告資訊:"assert:『b』 in file file.cpp (234)"。

(2)q_check_ptr(p)中的p是乙個指標。如果p是空的話,列印出類似的警告資訊:"in file file.cpp, line 234: out of memory"。

巨集q_assert實質上是呼叫函式qfatal或qwarning輸出資訊,列出如下(在src/tools/qglobal.h中):

#if !defined(q_assert)  

#  if defined(qt_check_state)  

#  if defined(qt_fatal_assert)  

#  define q_assert(x)   //列印x,檔名,在程式源**中的行號  

#   else  

#  define q_assert(x)    

#    endif  

#  else  

#    define q_assert(x)  

#  endif#endif  

巨集q_check_ptr實質上呼叫函式qwarning輸出資訊,巨集定義q_check_ptr列出如下(在src/tools/qglobal.h中):

#if defined(qt_check_null)  

#  define q_check_ptr(p) (qt_check_pointer#else#  define q_check_ptr(p)  

#endif q_export bool qt_check_pointer( bool c, const char *, int );  

函式qt_check_pointer實現資訊輸出操作,函式列出如下(在src/tools/qglobal.cpp中):

bool qt_check_pointer( bool c, const char *n, int l ) 

示例2:執行巨集q_assert和q_assert

巨集q_assert和q_assert常用來檢測程式錯誤,下面例子使用了這兩個巨集:

char *alloc( int size ) 

qt基於不同的除錯標記列印不同型別的警告資訊。qt使用了下面的巨集定義說明了不同的除錯標記(在src/tools/qglobal.h中):

qt_check_state:檢測一致的/期望的物件狀態

qt_check_range:檢測變數範圍錯誤

qt_check_null:檢測危險的空指標

qt_check_math:檢測危險的數學,比如被0除

qt_no_check:關閉所有的qt_check_...標記

qt_debug:使除錯**生效

qt_no_debug:關閉qt_debug標記

預設情況下,qt_debug和所有的qt_check標記都是開啟的。如果要關閉qt_debug,請定義qt_no_debug。如果要關閉qt_check標記,請定義qt_no_check。

示例3: 列印不同型別的警告資訊

下面的例子根據不同的巨集定義列印不同型別的警告資訊。**如下:

void f( char *p, int i ) 

qt核心程式設計之qt模板庫(1)

qt核心程式設計之集合類 (2)

qt核心程式設計之qt執行緒 (3)

qt核心程式設計之滑鼠拖放 (4)

qt核心程式設計之鍵盤焦點 (5)

qt核心程式設計之會話管理 (6)

Qt程式設計之除錯技術

17 除錯技術 qt應用程式的除錯可以通過ddd進行跟蹤除錯和列印各種除錯或警告資訊。ddd data display debugger 是使用gdb除錯工具的圖形工具,它安裝在linux作業系統中,使用方法可參考ddd的幫助文件。下面說明如何列印各種除錯或警告資訊 17.1 命令列引數 當你執行q...

Qt核心程式設計

qt模板庫 qttemplate library 簡稱qtl 是一套提供物件容器的模板。如果你的編譯器沒有適當的stl 標準模板庫 可用,qtl將被代替使用。qtl提供了物件的鍊錶 物件的向量 動態陣列 從乙個型別到另乙個型別的對映 或稱為字典 和相關的迭代器和演算法。乙個容器是包含和管理其它物件的...

Linux核心除錯技術

最常見的除錯技術和在應用程式中的printf一樣,將鎖需要的資訊通過控制台輸出 int console printk 4 核心中定義列印級別如上所示 linux 3.4.2 kerne printk.c 定義幾個巨集,將其放入console printk 4 使用cat proc sys kerne...