os/kernelhwsrv/kerneltest/e32test/debug/t_logtofile.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\debyg\LogToFile.cpp
    15 // t_logtofile.exe tests (alongside with d_logtofile.ldd) trace handler hook (TTraceHandler).
    16 // Usage:
    17 // 1. start t_logtofile -p=Pattern
    18 // - Starts logging into memory.(RDebug::Pring, NKern::Print & PletSec log are all considered).
    19 // - Only logs that start with "Pattern" will be logged (case sensitive).Leave '-p=' empty to log them all.
    20 // - All debug loggings to serial port (or epocwnd.out on emulator) are suppressed.
    21 // - There are 64KB memory available for the log. Once the memory is full, the logging stops.
    22 // 2. start t_logtofile stop
    23 // - Stops the logging (unless already stopped due to full memory).
    24 // - Transfers collected logs into c:\logtofile.dat
    25 // The format of the file is as follows:
    26 // The pattern:		Pattern
    27 // Buffer Size is:		65536
    28 // Fast counter freq:	3579545
    29 // 93559955	U	MsgSent
    30 // 108774945	K	Thread t_suser.EXE::Main created @ 0x973fe8 - Win32 Thread ID 0xbbc
    31 // 108810756	U	RTEST TITLE: T_SUSER 2.00(1013)
    32 // The first column is the current value of the fast counter.
    33 // The second column indicates U - user side, K - kernel or P-PlatSec logging.
    34 // 
    35 //
    36 
    37 #include <e32debug.h>
    38 #include <e32cons.h>
    39 #include <f32file.h>
    40 #include <e32base.h>
    41 #include <e32base_private.h>
    42 #include "d_logtofile.h"
    43 
    44 
    45 // The name of the output file use to save the sample data
    46 _LIT(KFileName,"C:\\LogToFile.DAT");
    47 _LIT(KAppName,"Logtofile");
    48 const TInt KHeapSize=0x2000;
    49 
    50 #define KPatternMaxSize 10
    51 TBuf8<KPatternMaxSize> Pattern;
    52 
    53 /**Server*/
    54 class CLogToFileServer : public CServer2
    55 	{
    56 public:
    57 	static CLogToFileServer* New(TInt aPriority) {return new CLogToFileServer(aPriority);}
    58 private:
    59 	CLogToFileServer(TInt aPriority) : CServer2(aPriority){}
    60 	CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
    61 public:
    62 static RLogToFileDevice iDevice;
    63 static TChunkCreateStr iChunkStr;
    64 static RChunk Chunk;
    65 
    66 	};
    67 
    68 /**Session*/
    69 class CLogToFileSession : public CSession2
    70 	{
    71 public:
    72 	enum TState {EStart, EStop};
    73 private:
    74 	void ServiceL(const RMessage2& aMessage);
    75 	TInt Stop();
    76 	TInt Start();
    77 	};
    78 
    79 /*Client-side session*/
    80 class RLogToFileSession : private RSessionBase
    81 	{
    82 public:
    83 public:
    84 	static inline TInt Start(){return Control(CLogToFileSession::EStart);}
    85 	static inline TInt Stop() {return Control(CLogToFileSession::EStop);}
    86 private:
    87 	static inline TInt Control(CLogToFileSession::TState aRequest);
    88 	};
    89 
    90 //------------globals---------------------
    91 RLogToFileDevice CLogToFileServer::iDevice;
    92 TChunkCreateStr  CLogToFileServer::iChunkStr;
    93 RChunk           CLogToFileServer::Chunk;
    94 
    95 
    96 /**Creates a new client for this server.*/
    97 CSession2* CLogToFileServer::NewSessionL(const TVersion&, const RMessage2&) const
    98 	{
    99 	return new(ELeave) CLogToFileSession();
   100 	}
   101 
   102 /**Entry point of the session request*/
   103 void CLogToFileSession::ServiceL(const RMessage2& aMessage)
   104 	{
   105 	TInt r=KErrNone;
   106 	switch (aMessage.Function())
   107 		{
   108 	case EStart:
   109 		{
   110 		r = Start();
   111 		break;
   112 		}
   113 	case EStop:
   114 		{
   115 		r = Stop();
   116 		CActiveScheduler::Stop();//This will stop the server thread.
   117 		break;
   118 		}
   119 	default:
   120 		r=KErrNotSupported;
   121 		}
   122 	aMessage.Complete(r);
   123 	}
   124 
   125 /**
   126 This will:
   127  - Load t_logtofile.ldd
   128  - Tell ldd to create the chunk
   129  - Tell ldd to start logging
   130 */
   131 TInt CLogToFileSession::Start()
   132 	{
   133 	TInt r = User::LoadLogicalDevice(KLogToFileName);
   134 	if(r !=KErrNone && r!=KErrAlreadyExists)
   135 		return r;
   136 	if((r = CLogToFileServer::iDevice.Open())!=KErrNone)	
   137 		{
   138 		User::FreeLogicalDevice(KLogToFileName);
   139 		return r;
   140 		}
   141 	CLogToFileServer::iChunkStr.iSize = 0x10000; //64K chunk size - hard coded
   142 	if((r=CLogToFileServer::iDevice.CreateChunk(&CLogToFileServer::iChunkStr))<0)
   143 	{
   144 		User::FreeLogicalDevice(KLogToFileName);
   145 		return r;
   146 	}
   147 	CLogToFileServer::Chunk.SetHandle(r);
   148 	CLogToFileServer::iDevice.Start();	
   149 	return KErrNone;
   150 }
   151 
   152 /**
   153 This will:
   154  - Tell ldd to stop logging
   155  - Put the content of the chunk into c:\logtofile.dat
   156  - Tell ldd to close the chunk
   157  - Unload t_logtofile.ldd
   158 */
   159 TInt CLogToFileSession::Stop()
   160 {
   161 	TInt bytes = CLogToFileServer::iDevice.Stop();	
   162 
   163 	
   164 	RFs fs;
   165 	RFile file;
   166 	TInt r;
   167 	TRequestStatus status;
   168 
   169 	if(KErrNone != (r = fs.Connect()))
   170 		return r;
   171 	if(KErrNone != (r = file.Replace(fs, KFileName,EFileWrite)))
   172 		{
   173 		fs.Close();
   174 		return r;
   175 		}
   176 
   177 	TPtrC8 log(CLogToFileServer::Chunk.Base(),bytes);
   178 	file.Write(log,status);
   179 	User::WaitForRequest(status);
   180 	r = status.Int();
   181 	file.Close();
   182 	fs.Close();
   183 	CLogToFileServer::Chunk.Close();
   184 
   185 	CLogToFileServer::iDevice.RemoveChunk();	
   186 	User::FreeLogicalDevice(KLogToFileName);
   187 	return r;
   188 }
   189 
   190 /**Sends request to the server*/
   191 TInt RLogToFileSession::Control(CLogToFileSession::TState aRequest)
   192 	{
   193 	RLogToFileSession p;
   194 	TInt r = p.CreateSession(KAppName, TVersion(), 0);
   195 	if (r == KErrNone)
   196 		p.SendReceive(aRequest);
   197 	return r;
   198 	}
   199 
   200 /**The entry point for the server thread.*/
   201 LOCAL_C TInt serverThreadEntryPoint(TAny*)
   202 	{
   203 	TInt r=0;
   204 	CLogToFileServer* pS=0;
   205 	
   206 	CActiveScheduler *pR=new CActiveScheduler;
   207 	if (!pR) User::Panic(_L("Create ActSchdlr error"), KErrNoMemory);
   208 	CActiveScheduler::Install(pR);
   209 
   210 	pS=CLogToFileServer::New(0);
   211 	if (!pS)
   212 	{
   213 		delete pR;
   214 		User::Panic(_L("Create svr error"), KErrNoMemory);
   215 	}
   216 
   217 	r=pS->Start(KAppName);
   218 	if(r)
   219 		{
   220 		delete pS;
   221 		delete pR;
   222 		User::Panic(_L("Start svr error"), r);
   223 		}
   224 
   225 	RThread::Rendezvous(KErrNone);
   226 	CActiveScheduler::Start();
   227 	delete pS;
   228 	delete pR;
   229 	return(KErrNone);
   230 	}
   231 
   232 /**Reads the command line and set the matching pattern to be - what is after '-p='*/
   233 void SetPattern(void)
   234 	{
   235 	_LIT8(KPattern,"-p=");
   236 	TBuf<64> c;
   237 	User::CommandLine(c);
   238 	#if defined(_UNICODE)
   239 	TPtr8 ptr = c.Collapse();
   240 	#else
   241 	TPtr8 ptr(c.Ptr(),c.Length(),c.MaxLEngth());
   242 	#endif
   243 
   244 	TInt patternStart = ptr.FindF(KPattern);
   245 	if (patternStart < 0)
   246 		{
   247 		Pattern.SetLength(0);
   248 		return;
   249 		}
   250 	patternStart+=3;
   251 	
   252 	TPtrC8 pattern (ptr.Ptr()+patternStart,Min(ptr.Length()-patternStart, KPatternMaxSize) );
   253 	CLogToFileServer::iChunkStr.iPattern.Copy(pattern);
   254 	}
   255 
   256 /**The main program if we have to start logging
   257    It creates the server and sends start-logging request.*/
   258 void MainL()
   259 	{
   260 	RThread server;
   261 	TRequestStatus status;
   262 	TInt r = 0;
   263 
   264 	SetPattern();
   265 	r=server.Create(_L("LogToFileServer"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
   266 	User::LeaveIfError(r);
   267 	server.Resume();
   268 	server.Rendezvous(status);
   269 	User::WaitForRequest(status);
   270 	User::LeaveIfError(status.Int());
   271 
   272 	User::LeaveIfError(RLogToFileSession::Start());
   273 
   274 	server.Logon(status);
   275 	User::WaitForRequest(status);
   276 	}
   277 
   278 /**Returns true if 'stop' is found in the command line*/
   279 TBool GetStop()
   280 	{
   281 	_LIT(KStop,"stop");
   282 	TBuf<64> c;
   283 	User::CommandLine(c);
   284 	if (c.FindF(KStop) >= 0)
   285 		return ETrue;
   286 	return EFalse;
   287 	}
   288 
   289 /**LogToFile.exe entry point*/
   290 TInt E32Main()
   291 	{
   292 	if (GetStop())
   293 		return RLogToFileSession::Stop();
   294 
   295 	CTrapCleanup::New();
   296 	TRAPD(r,MainL());
   297 	return r;
   298 	}