Symbian Security Studio

About symbian software programming ,security analysis and other things about symbian.

Thursday, November 20, 2008

Symbian S60真机调试及定位问题 - alex_hua的专栏 - CSDNBlog

Symbian真机调试技术总结



基于Symbian平台(2nd/3rd)开发的程序软件,很多人都会碰到在模拟器上运行的非常正常,但一到真机上运行,就会碰到这样那样的问题。一旦在真机上出现问题,一般情况下就不会很方便的就可以解决,这就涉及到如何调试真机程序,快速准确地定位到问题所在。

总结真机调试的经验,给出如下结论:



“使用文件系统写log,同时让真机也像模拟器那样在出现Panic的时候弹出提示框”





一.使用文件系统写日志

Symbian平台本身提供了一个写log类-RFileLogger,该类可以很方便地将需要的日志写到文件中,但该类有局限性,在程序开发中需考虑是否使用。

1. 必须将log文件写到一定的路径中(C:\Logs)

2. 一次log写入长度有限制(KLogBufferSize=150,flogger.h)



基于上面所列,所以在非小型程序中不推荐使用RFileLogger类,而推荐使用一般的基于IO的写日志方法(后面附上一个简单可用的TRACE类)。



二.在真机上弹出Panic提示框(带Panic类别及错误号)

想要在真机上也像模拟器那样,在出现Panic的时候,弹出详细的Panic类别及错误号,这对定位真机问题非常有帮助。不过该机制在Symbain S60 2nd和3rd上有不同。在Symbain S60 3rd及以上,只需在.pkg文件中的文件安装部分加上如下语句即可:

;Files to install

"ErrRd" -"!:\resource\ErrRd"



但在Symbian 2nd(不知道是否是全部2nd版本还是某些版本)上,按上述方法不能得到预期的结果(2nd FP2就是这样)。这时就需要额外软件帮助了,有个叫TaskSpy的免费软件可以用来实现我们想要的功能。



三.总结

虽然在使用Carbie C++ IDE时,可以利用TRK进行真机联机调试,但使用TRK调试的效果并不是很好,尤其是稍微复杂或者大型的软件。“使用文件系统写log,同时让真机也像模拟器那样在出现Panic的时候弹出提示框”,这个方法应该是最适合真机调试及定位问题。



附:CTraceLog类



//TraceLog.h



#ifndef TRACELOG_H

#define TRACELOG_H



// INCLUDES

#include

#include

#include

#include



// CLASS DECLARATION

const TInt KMaxLogSize = 4096;

/**

* CTraceLog

*

*/

class CTraceLog : public CBase

{

public:

// Constructors and destructor



/**

* Destructor.

*/

~CTraceLog();



/**

* Two-phased constructor.

*/

static CTraceLog* NewL();



/**

* Two-phased constructor.

*/

static CTraceLog* NewLC();



void OutPutlog(TUint8 aLevel,TRefByValue< const TDesC16 > aFmt,...);

void OutPutlog(TUint8 aLevel,TRefByValue< const TDesC8 > aFmt,...);

void OutPutlog(TUint8 aLevel,const char *aFmt,...);



private:



/**

* Constructor for performing 1st stage construction

*/

CTraceLog();



/**

* EPOC default constructor for performing 2nd stage construction

*/

void ConstructL();



private:

RFile iFile;

RFileWriteStream iOutputStream;

TTime iTraceTime;

TBuf iLogBuf16;

TBuf8 iLogBuf8;



};



#endif // TRACELOG_H



// TraceLog.cpp



#include "TraceLog.h"

#include



_LIT(KTimeFormat,"%Y%M%D%1-%2-%3 %H:%T:%S");

_LIT(KLogFile,"e:\\logs\\paysercer_log.txt");

_LIT(K16LogLevel0," : ");

_LIT(K16LogLevel1," : ");

_LIT(K16LogEOF,"\r\n");

_LIT8(K8LogLevel0," : ");

_LIT8(K8LogLevel1," : ");

_LIT8(K8LogEOF,"\r\n");



CTraceLog::CTraceLog()

{

// No implementation required

}



CTraceLog::~CTraceLog()

{

iOutputStream.Close();

iFile.Close();

iFs.Close();

}



CTraceLog* CTraceLog::NewLC()

{

CTraceLog* self = new (ELeave)CTraceLog();

CleanupStack::PushL(self);

self->ConstructL();

return self;

}



CTraceLog* CTraceLog::NewL()

{

CTraceLog* self=CTraceLog::NewLC();

CleanupStack::Pop(); // self;

return self;

}



void CTraceLog::ConstructL()

{

TInt ret;

User::LeaveIfError(iFs.Connect());

ret = iFs.MkDirAll(KLogFile);

if( (KErrNone!=ret) && (KErrAlreadyExists!=ret) )

User::Leave(ret);



User::LeaveIfError(iFile.Open(iFs,

KLogFile,

EFileWrite) );

iOutputStream.Attach(iFile);

iOutputStream.Sink()->SeekL(MStreamBuf::EWrite,EStreamEnd);

}



void CTraceLog::OutPutlog(TUint8 aLevel,TRefByValue< const TDesC16 > aFmt,...)

{

iTraceTime.HomeTime();

iTraceTime.FormatL(iLogBuf16,KTimeFormat);

if(aLevel == 0) //EInfo

iLogBuf16.Append(K16LogLevel0);

else //EError

iLogBuf16.Append(K16LogLevel1);



VA_LIST ap;

VA_START(ap,aFmt);

iLogBuf16.AppendFormatList(aFmt,ap);

VA_END(ap);

iLogBuf16.Append(K16LogEOF);

iLogBuf8.Copy(iLogBuf16);

iOutputStream.WriteL(iLogBuf8);

iOutputStream.CommitL();

}



void CTraceLog::OutPutlog(TUint8 aLevel,TRefByValue< const TDesC8 > aFmt,...)

{

iTraceTime.HomeTime();

iTraceTime.FormatL(iLogBuf16,KTimeFormat);

iLogBuf8.Copy(iLogBuf16);

if(aLevel == 0) //EInfo

iLogBuf8.Append(K8LogLevel0);

else //EError

iLogBuf8.Append(K8LogLevel1);



VA_LIST ap;

VA_START(ap,aFmt);

iLogBuf8.AppendFormatList(aFmt,ap);

VA_END(ap);

iLogBuf8.Append(K8LogEOF);

iOutputStream.WriteL(iLogBuf8);

iOutputStream.CommitL();

}



void CTraceLog::OutPutlog(TUint8 aLevel,const char *aFmt,...)

{

iTraceTime.HomeTime();

iTraceTime.FormatL(iLogBuf16,KTimeFormat);

iLogBuf8.Copy(iLogBuf16);

if(aLevel == 0) //EInfo

iLogBuf8.Append(K8LogLevel0);

else //EError

iLogBuf8.Append(K8LogLevel1);



TPtrC8 fmt((TUint8*)aFmt);

VA_LIST ap;

VA_START(ap,aFmt);

iLogBuf8.AppendFormatList(fmt,ap);

VA_END(ap);

iLogBuf8.Append(K8LogEOF);

iOutputStream.WriteL(iLogBuf8);

iOutputStream.CommitL();

}