Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 57
Текст из файла (страница 57)
In Carbide.c++, select Run,Debug. In the Debugging tab, select the View Process output andView Windows system messages checkboxes. In CodeWarrior, selectEdit, Settings for your target. In the Debugger, Debugger Settingspanel, select the Log System Messages checkbox.• JustInTime: if set to 1, enables just-in-time debugging for a process.This prevents the emulator closing down when a panic occurs. ByEMULATOR DEBUGGING295default, just-in-time debugging is enabled. This option can also be setby calling User::SetJustInTime() in your code.The emulator maps the Symbian OS device’s file system onto the PC’sfile system, as described in Section 10.1. Two drives, C: (the internal filesystem) and Z: (the device ROM), are created by default. The defaultlocation for these drives is:C: = %EPOCROOT%\epoc32\wins\cZ: = %EPOCROOT%\epoc32\data\z + %EPOCROOT%\epoc32\release\wins\udeb\zFurther drives can be configured in epoc.ini, for example a D: drivecan be defined as:_EPOC_DRIVE_D \epoc32\winscw\dThere are other ways to configure the Windows emulator supplied withthe S60 and UIQ SDKs.
More details can be found within the developerdocumentation.Certificates for Emulator TestingIn Symbian OS v9, applications that run on phones usually need tobe digitally signed. The UIQ 3 SDK supports this by allowing onlysigned SIS (installation) files to be installed on the emulator. The UIQ 3SDK includes three sets of certificates and keys to use when preparing applications for testing on the emulator. The certification filesare located at \epoc32\tools\cert and should be installed into\epoc32\winscw\c\system\data.Note that these certificates only work on the emulator. For applicationsto run on a phone, the SIS file must be signed via the Symbian Signedprocess (see Chapter 9).Which certificate to use depends on whether the application UID isin the protected range and whether system capabilities are required. Thecertificates provided are:• NoCaps.cert and NoCaps.key, which is a dummy certificate tosign SIS files that require only user capabilities or no capabilities atall; it is needed because all SIS files must be signed before they canbe installed• AllUserCaps.cert and AllUserCaps.key, which blocks theGrant capabilities dialog when one or more user certificates aredefined in binaries that are included in the SIS file296DEBUGGING AND THE EMULATOR• AllCaps.cert and AllCaps.key, which allows you to install SISfiles that include binaries with system capabilities.One way of finding out which certificate you need is to test them oneat a time in the above order.Making the Most of the Emulator Log FileThe emulator writes debugging information to a log file, calledepocwind.out (typically in the directory specified by the %temp%environment variable), when it runs.
This log file contains additionalinformation which can prove useful when debugging your code.Using RDebug::Print() statementsOne technique for aiding debugging using the emulator is to addRDebug::Print() statements to your code (you need to include thee32debug.h header file to use RDebug).
This function is used to printformatted text to the emulator log file, helping you trace what your program is doing. RDebug::Print() can be used to print all kinds of data,including memory addresses and values of variables.You can use % followed by a format character in the arguments toRDebug::Print() to print out variables. For example, the followingcode writes Info, value: 4 to the log file:TInt numberOfWheels = 4;_LIT(KMsgDebug, "Info, value: %d");RDebug::Print(KMsgDebug, error);When using RDebug::Print() to display the contents of descriptors,the address of the descriptor should be passed instead of the descriptoritself, otherwise a KERN-EXEC 3 panic is raised:TBuf des;...RDebug::Print(_L(‘‘%S’’), des); // PanicRDebug::Print(_L(‘‘%S’’), &des); // OKA useful macro,the source code file:LINE, evaluates to the current line number inRDebug::Print(_L("Debug on line %d"), __LINE__);EMULATOR DEBUGGING297Using RTestIf you are performing tests within your code, you might find that the RTestclass provides some useful facilities.
RTest creates a console windowto which test results can be logged. Specifically, different overloads ofoperator() can be used to check the test condition, print out failuremessages and panic the test code. RTest can also get characters fromthe keyboard. If the logging flag is set using RTest::SetLogged(),the console output is also written to the debug output represented byan RDebug object. Details of the RTest class APIs can be found in theSymbian Developer Library within SDKs.Platform SecurityAs we have seen, security is a major concern in Symbian OS v9, and thelog file contains details which may help you track down problems relatedto Platform Security capabilities.The start of the log file contains information about the platform securitysettings:PlatSecEnforcement OFFPlatSecDiagnostics OFFPlatSecProcessIsolation ONPlatSecEnforceSysBin ONPlatSecDisabledCaps NONE0.000 Thread 53bf1280 created @ 0x53bf1280 - Win32 Thread ID 0x8900.120 Thread EFile.exe::Main created @ 0x98fa18 - Win32 Thread ID 0xb3c1.015 SysStart: using resource file Z:\private\10205C44\SSCForStartupMode1088.rsc13.300 SysStart: starting Z:\sys\bin\HelloWorld.exe13.305 Thread HelloWorld.exe::Main created @ 0xf92c3c - Win32Thread ID 0x5d8These settings are discussed in the Emulator Settings section.
Theyallow you to determine whether you want to see errors related to platformsecurity whilst running your code or in the log file. Capturing thediagnostic messages in the log file is particularly useful, as they areproduced when an application attempts to call a function or performan action for which it does not have the required capabilities: the errormessage tells you which capabilities are needed.Below is the next part of the epocwind.out file:13.305 Thread HelloWorld.exe::Main created @ 0xf92c3c - Win32Thread ID 0x5d813.320 Thread HelloWorld.exe::Worker135988996 444077980 created @0xf92454 - Win32 Thread ID 0xa0013.330 *PlatSec* ERROR - Capability check failed - A Message(function number=0x00000005) from Thread HelloWorld.exe[10282281]0001::Worker135988996 444077980, sent to Server298DEBUGGING AND THE EMULATOR!LogServ, was checked by Thread LogServ.EXE[101f401d]0001::LogServ and was found to be missing the capability:WriteDeviceData.13.340 Thread HelloWorld.exe::Worker135988996 444077980Panic E32USER-CBase 47Here we can see, at time 13.330, that the running program,HelloWorld.exe, made a call to the LogServer, but the server rejectedthe call, as HelloWorld didn’t have the WriteDeviceData capability.
Thiswould cause the program to fail, but can be remedied by granting theprogram the WriteDeviceData capability, if appropriate.PanicsThe log file also shows details of other run-time failures (panics) in theprogram. A message is placed in the log whenever a thread panics and iswritten in the following format:Thread <program>::<thread> <a thread identifier> Panic <panic type><panic number>Referring back to the log file excerpt above, the entry at 13.340 showsthat a panic has occurred. The panic is of type E32USER-CBase and ispanic number 47.
Looking up this information in the SDK, in the SystemPanic reference section within the Symbian OS Reference, tells us thatsomething caused an active object’s RunL() function to leave, resultingin the active scheduler generating the panic E32USER-CBase 47.LoggingIn order to examine the dynamic behavior of your programs, you canadd logging in your code. Logging is very useful when debugging activeobjects and client–server framework applications as well as other interprocess communication mechanisms.While testing on the emulator, RFileLogger is a client–server APIthat can be used for logging messages into a file. The logging messagecontains a time stamp, a thread ID, severity, location (file name andline number) as well as the message.
Two formats are supported: anXML-formatted log and a plain-text log. The format is decided by theextension of the filename the user supplied: XML or TXT.Two types of API usage are shown in the following example code,static and non-static. The difference is in the version of the I/O functionsused; in practice, the static version may be slower than the non-staticEMULATOR DEBUGGING299version since the non-static version is designed for a one-time connectionwhich is continuously used, while the static version implicitly reconnectseach time.#include <flogger.h>...RFileFlogger logger;TInt err = logger.Connect();if(err)return EFail; // failed to create a session_LIT(KLogFilexml, "c:\\TestinXML.xml");err = logger.CreateLog(KLogFilexml, RFileFlogger::ELogModeAppend);if(err)return EFail; // failed to create a fileTInt n=0;_LIT(K16BitFormatText, "logger string int = %d, string = %S");logger.SetLogLevel(RFileFlogger::ESevrWarn);//As severity is ESevrWarn, warn only; print error to log_LIT(K16BitString, "The String16");TBuf<20> buf16(K16BitString);logger.Log(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrAll,K16BitFormatText, n++, &buf16);logger.Log(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrInfo,K16BitFormatText, n++, &buf16);logger.Log(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrWarn,K16BitFormatText, n++, &buf16);logger.Log(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrErr,K16BitFormatText, n++, &buf16);TInt length = 2;TExtraLogField logField[2];logField[0].iLogFieldName.Copy(_L("SUITE_NAME"));logField[0].iLogFieldValue.Copy(_L("SUITE_VALUE"));logField[1].iLogFieldName.Copy(_L("TEST_NAME"));logField[1].iLogFieldValue.Copy(_L("TEST_VALUE"));logger.Log(((TText8*)__FILE__), __LINE__, RFileFlogger::ESevrErr,length, logField, K16BitFormatText, n++, &buf16);logger.Close();// from now on, static methods are used to create the logs_LIT(KLogFolder, "Logs");_LIT(KLogFile, " TestinTXT.txt");_LIT(KSomeText, "Log me.");RFileLogger::Write(KLogFolder(), KLogFile(),EFileLoggingModeAppend, KSomeText());TUint num1 = 100;_LIT(KWriteNumber, "Writing a number to the log: %d")RFileLogger::WriteFormat(KTestLogDir2(), KTestLogFileName1(),EFileLoggingModeAppend, KWriteNumber, num1);RFileLogger should not be used for debugging on devices, as it isnot supported on all Symbian OS phones.300DEBUGGING AND THE EMULATORUsing eshelleshell is a simple command-line shell, available on both the emulator and on some target hardware, which you may find quite useful.You can run it directly from the UIQ 3 emulator (see Figure 10.8)or change to the emulator’s startup directory (\epoc32\release\winscw\udeb\) from the Windows command line and type eshell.
Information on available commands can be accessed by typing help in eshell.Figure 10.8 eshell on UIQ SDKThe ps command provides you with many options to view the currentrunning processes, threads, etc. During debugging, you can use thesecommands to display the running processes and check whether yourprogram or the applications (servers, libraries) invoked by your programshave started correctly.• A displays all container objects.• T lists threads.• S lists servers.• L lists libraries.• E lists semaphores.EMULATOR DEBUGGING301Figure 10.9 Process list on UIQ SDKFigure 10.9 shows an example of the ps command output on the UIQemulator.