Symbian调试技术
来源:互联网 发布:数据之美 邱南森 pdf 编辑:程序博客网 时间:2024/05/18 20:33
== 模拟器不显示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宏的例子:
- void TestValue(TInt aValue)
- {
- _LIT(KPanicCategory, "TestValue");
- __ASSERT_DEBUG((aValue >= 0), User::Panic(KPanicCategory, 99));
- // Do something with aValue
- // ...
- }
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文件:
- #define ASSERT(x) __ASSERT_DEBUG(x, User::Invariant())
#define ASSERT(x) __ASSERT_DEBUG(x, User::Invariant())
这是一个如何使用ASSERT宏的例子:
- void TestValue(TInt aValue)
- {
- ASSERT(aValue >= 0);
- // Do something with aValue
- // ...
- }
void TestValue(TInt aValue){ ASSERT(aValue >= 0); // Do something with aValue // ...}
== 使用__UHEAP_MARK和__UHEAP_MARKEND宏检测内存泄漏 ==
检测你的代码正确地管理堆内存(换言之,不泄漏内存)的一个可能性是使用__UHEAP_MARK和__UHEAP_MARKEND宏。
- 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;
- }
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。在实践中,它们被用来使程序员先创建一个不变性测试函数,然后在需要检测对象状态的函数的开头和结尾调用之,这是典型的做法。
- 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
- }
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。推荐使用这两个重载版本,因为它们帮助检测清除栈的不正确使用。
- CClass* obj = new(ELeave) CClass;
- CleanupStack::PushL(obj);
- // ...
- 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
''注: 在发行版编译时,期望弹出项的检测将被禁用,因此使用它们在二进制大小和效率方面都不会影响发行版编译。''
- Symbian调试技术
- Symbian调试技术
- Symbian调试技术
- Symbian调试技术
- Symbian程序开发调试技术
- Symbian真机调试技术总结
- Symbian创建调试日志
- Symbian程序调试技巧
- symbian真机调试
- symbian 调试集锦
- Symbian音频技术探究
- Symbian音频技术探究
- Symbian音频技术探究
- Symbian音频技术探究
- Symbian音频技术探究
- Symbian音频技术探究
- Symbian音频技术探究
- Symbian音频技术探究
- MySQL中ROOT无权限问题
- 炫音制作
- Moblin=Mobile Linux, Intel领导下的linux开源项目
- html link rel rev
- DotA法球探讨
- Symbian调试技术
- 高效中英文字符串截取方法
- phoneME建立DirectFB
- 女人要怀有一颗珍惜之心
- JAVA上加密算法的实现用例
- 数据库设计技巧14则
- curl在win32平台下编译安装
- 编译BF537_EZkit_Display_Example报错误的解决办法
- JSP加QQ