Symbian調試技術

來源:互聯網
上載者:User

Symbian調試技術

  • == 模擬器不顯示Panic細節 ==  

若Panic發生了,除非在指定的位置有一個名叫“ErrRd”的檔案,否則模擬器不顯示Panic的細節。這使得很難知道是什麼引起Panic。

在SDK 3rd版以前,ErrRd檔案必須手工建立,但從3rd版以後,這個檔案可以預設在目錄“C:/Symbian/9.2/S60_3rd_FP1/Epoc32/winscw/c/resource”下找到。有了ErrRd,Panic發生時的輸出像這樣:

''提示: 如果即使使用3rd版的SDK,ErrRd檔案也找不到,那就啟動模擬器,選擇 Tools > Preferences'',然後勾上Extended panic code file。

  • == 使用斷言檢測Bug ==

使用斷言檢測所做的“代碼是正確的”的假設,例如: 對象的狀態,期望的函數參數和傳回值等。Symbian OS中定義了兩個斷言宏: __ASSERT_ALWAYS 和__ASSERT_DEBUG。它們之間的區別是__ASSERT_DEBUG不會影響產品代碼而__ASSERT_ALWAYS會。

這是一個如何使用__ASSERT_DEBUG宏的例子:

view plaincopy to clipboardprint?
  1. void TestValue(TInt aValue)   
  2. {   
  3.   _LIT(KPanicCategory, "TestValue");   
  4.   __ASSERT_DEBUG((aValue >= 0), User::Panic(KPanicCategory, 99));   
  5.   // Do something with aValue   
  6.   // ...   
  7. }  
void TestValue(TInt aValue){  _LIT(KPanicCategory, "TestValue");  __ASSERT_DEBUG((aValue >= 0), User::Panic(KPanicCategory, 99));  // Do something with aValue  // ...}

上例中,如果參數aValue小於0,拋出"Panic -99"。

''註: 斷言宏預設不拋Panic, 允許你來決定宣告失敗時調用什麼過程。儘管如此,這種情況下你應該總是拋出Panic而不是返回錯誤或Leave。''

因為上例使用__ASSERT_DEBUG宏,只在debug編譯時間才檢測aValue。如果有必要在產品代碼中也檢測參數,就應當用__ASSERT_ALWAYS。

當你不希望外部調用者需要跟蹤Panic時,使用__ASSERT_DEBUG的一個替代品: ASSERT宏。ASSERT完全象是斷言宏,除了它不要要你提供panic類別或描述符。

這裡是該宏的定義,來自e32def.h檔案:

view plaincopy to clipboardprint?
  1. #define ASSERT(x) __ASSERT_DEBUG(x, User::Invariant())  
#define ASSERT(x) __ASSERT_DEBUG(x, User::Invariant())

這是一個如何使用ASSERT宏的例子:

view plaincopy to clipboardprint?
  1. void TestValue(TInt aValue)   
  2. {   
  3.   ASSERT(aValue >= 0);   
  4.   // Do something with aValue   
  5.   // ...   
  6. }  
void TestValue(TInt aValue){  ASSERT(aValue >= 0);  // Do something with aValue  // ...}
  • == 使用__UHEAP_MARK和__UHEAP_MARKEND宏檢測記憶體流失 ==

檢測你的代碼正確地管理堆記憶體(換言之,不泄漏記憶體)的一個可能性是使用__UHEAP_MARK和__UHEAP_MARKEND宏。

view plaincopy to clipboardprint?
  1. GLDEF_C TInt E32Main()   
  2. {   
  3.   // Start checking memory leaks   
  4.   __UHEAP_MARK;   
  5.   
  6.   // Create a fixed-length, flat array, which contains 10 integers   
  7.   CArrayFixFlat<TInt>* fixFlatArray;   
  8.   fixFlatArray = new(ELeave) CArrayFixFlat<TInt>(10);   
  9.   // Array is not deleted, so memory will leak   
  10.   
  11.   // Stop checking memory leaks and cause a panic if there is a leak   
  12.   __UHEAP_MARKEND;   
  13.   
  14.   return KErrNone;   
  15. }  
GLDEF_C TInt E32Main(){  // Start checking memory leaks  __UHEAP_MARK;  // Create a fixed-length, flat array, which contains 10 integers  CArrayFixFlat<TInt>* fixFlatArray;  fixFlatArray = new(ELeave) CArrayFixFlat<TInt>(10);  // Array is not deleted, so memory will leak  // Stop checking memory leaks and cause a panic if there is a leak  __UHEAP_MARKEND;  return KErrNone;}

由於資料未被刪除和記憶體流失檢測宏,上例代碼在應用程式關閉時將引起一個Panic,如所示:

值得一提的是堆檢測宏只編譯進debug版,因此可以安全地留在產品代碼中而不會影響代碼的大小或速度。

  • == 對象不變性宏 ==

有兩個宏允許你檢查對象的狀態: __DECLARE_TEST 和 __TEST_INVARIANT。在實踐中,它們被用來使程式員先建立一個不變性測試函數,然後在需要檢測對象狀態的函數的開頭和結尾調用之,這是典型的做法。

view plaincopy to clipboardprint?
  1. class CLivingPerson : public CBase   
  2. {   
  3. public:   
  4.   enum TGender {EMale, EFemale};   
  5. public:   
  6.   CLivingPerson(TGender aGender);   
  7.   ~CLivingPerson();   
  8. public:   
  9.   void SetAge(const TInt aAge);   
  10. private:   
  11.   TGender iGender;   
  12.   TInt iAgeInYears;   
  13.   __DECLARE_TEST;  // Object invariance testing   
  14. };   
  15.   
  16. CLivingPerson::CLivingPerson(TGender aGender) : iGender(aGender) {}   
  17. CLivingPerson::~CLivingPerson() {}   
  18.   
  19. void CLivingPerson::SetAge(const TInt aAge)   
  20. {   
  21.   // Set age and check object invariance   
  22.   __TEST_INVARIANT;   
  23.   iAgeInYears = aAge;   
  24.   __TEST_INVARIANT;   
  25. }   
  26.   
  27. void CLivingPerson::__DbgTestInvariant() const  
  28. {  
  29.   #ifdef _DEBUG  // Built into debug code only   
  30.   // Person should be either male or female   
  31.   ASSERT((iGender == EMale) || (iGender == EFemale));   
  32.      
  33.   // Person's age shouldn't be negative   
  34.   ASSERT(iAgeInYears >= 0);  
  35.   #endif   
  36. }  
class CLivingPerson : public CBase{public:  enum TGender {EMale, EFemale};public:  CLivingPerson(TGender aGender);  ~CLivingPerson();public:  void SetAge(const TInt aAge);private:  TGender iGender;  TInt iAgeInYears;  __DECLARE_TEST;  // Object invariance testing};CLivingPerson::CLivingPerson(TGender aGender) : iGender(aGender) {}CLivingPerson::~CLivingPerson() {}void CLivingPerson::SetAge(const TInt aAge){  // Set age and check object invariance  __TEST_INVARIANT;  iAgeInYears = aAge;  __TEST_INVARIANT;}void CLivingPerson::__DbgTestInvariant() const{  #ifdef _DEBUG  // Built into debug code only  // Person should be either male or female  ASSERT((iGender == EMale) || (iGender == EFemale));    // Person's age shouldn't be negative  ASSERT(iAgeInYears >= 0);  #endif}

由於上例使用ASSERT宏,若對象狀態不正確時就拋出"USER 0"Panic。

  • == 用期望的彈出項檢測清除棧的不正確使用 ==

清除棧中的對象在不再有機會被Leave成孤兒時應被彈出。因此,彈出通常恰好發生在對象被刪除之前。一般使用PopAndDestroy函數代替Pop函數,因為它確保對象一彈出就被刪除,避免了記憶體流失的可能性。CleanupStack::Pop 和 CleanupStack::PopAndDestroy都有一個重載版本,允許調用者聲明“期望的彈出項”,指明該項應從棧中彈出。在期望的彈出項不匹配所彈出的項時,將拋出"E32USER-CBase 90" Painc。推薦使用這兩個重載版本,因為它們協助檢測清除棧的不正確使用。

view plaincopy to clipboardprint?
  1. CClass* obj = new(ELeave) CClass;   
  2. CleanupStack::PushL(obj);   
  3. // ...   
  4. CleanupStack::PopAndDestroy(obj);  // Panics if ‘obj’ not on top  
CClass* obj = new(ELeave) CClass;CleanupStack::PushL(obj);// ...CleanupStack::PopAndDestroy(obj);  // Panics if ‘obj’ not on top

''註: 在發行版編譯時間,期望彈出項的檢測將被禁用,因此使用它們在二進位大小和效率方面都不會影響發行版編譯。''

  • == 相關連結 ==
  1. Debugging techniques
  2. 調試技術

轉貼:http://wiki.forum.nokia.com/index.php/%E8%B0%83%E8%AF%95%E6%8A%80%E6%9C%AF

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.