--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/debug/t_logtofile.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,298 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test\debyg\LogToFile.cpp
+// t_logtofile.exe tests (alongside with d_logtofile.ldd) trace handler hook (TTraceHandler).
+// Usage:
+// 1. start t_logtofile -p=Pattern
+// - Starts logging into memory.(RDebug::Pring, NKern::Print & PletSec log are all considered).
+// - Only logs that start with "Pattern" will be logged (case sensitive).Leave '-p=' empty to log them all.
+// - All debug loggings to serial port (or epocwnd.out on emulator) are suppressed.
+// - There are 64KB memory available for the log. Once the memory is full, the logging stops.
+// 2. start t_logtofile stop
+// - Stops the logging (unless already stopped due to full memory).
+// - Transfers collected logs into c:\logtofile.dat
+// The format of the file is as follows:
+// The pattern: Pattern
+// Buffer Size is: 65536
+// Fast counter freq: 3579545
+// 93559955 U MsgSent
+// 108774945 K Thread t_suser.EXE::Main created @ 0x973fe8 - Win32 Thread ID 0xbbc
+// 108810756 U RTEST TITLE: T_SUSER 2.00(1013)
+// The first column is the current value of the fast counter.
+// The second column indicates U - user side, K - kernel or P-PlatSec logging.
+//
+//
+
+#include <e32debug.h>
+#include <e32cons.h>
+#include <f32file.h>
+#include <e32base.h>
+#include <e32base_private.h>
+#include "d_logtofile.h"
+
+
+// The name of the output file use to save the sample data
+_LIT(KFileName,"C:\\LogToFile.DAT");
+_LIT(KAppName,"Logtofile");
+const TInt KHeapSize=0x2000;
+
+#define KPatternMaxSize 10
+TBuf8<KPatternMaxSize> Pattern;
+
+/**Server*/
+class CLogToFileServer : public CServer2
+ {
+public:
+ static CLogToFileServer* New(TInt aPriority) {return new CLogToFileServer(aPriority);}
+private:
+ CLogToFileServer(TInt aPriority) : CServer2(aPriority){}
+ CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const;
+public:
+static RLogToFileDevice iDevice;
+static TChunkCreateStr iChunkStr;
+static RChunk Chunk;
+
+ };
+
+/**Session*/
+class CLogToFileSession : public CSession2
+ {
+public:
+ enum TState {EStart, EStop};
+private:
+ void ServiceL(const RMessage2& aMessage);
+ TInt Stop();
+ TInt Start();
+ };
+
+/*Client-side session*/
+class RLogToFileSession : private RSessionBase
+ {
+public:
+public:
+ static inline TInt Start(){return Control(CLogToFileSession::EStart);}
+ static inline TInt Stop() {return Control(CLogToFileSession::EStop);}
+private:
+ static inline TInt Control(CLogToFileSession::TState aRequest);
+ };
+
+//------------globals---------------------
+RLogToFileDevice CLogToFileServer::iDevice;
+TChunkCreateStr CLogToFileServer::iChunkStr;
+RChunk CLogToFileServer::Chunk;
+
+
+/**Creates a new client for this server.*/
+CSession2* CLogToFileServer::NewSessionL(const TVersion&, const RMessage2&) const
+ {
+ return new(ELeave) CLogToFileSession();
+ }
+
+/**Entry point of the session request*/
+void CLogToFileSession::ServiceL(const RMessage2& aMessage)
+ {
+ TInt r=KErrNone;
+ switch (aMessage.Function())
+ {
+ case EStart:
+ {
+ r = Start();
+ break;
+ }
+ case EStop:
+ {
+ r = Stop();
+ CActiveScheduler::Stop();//This will stop the server thread.
+ break;
+ }
+ default:
+ r=KErrNotSupported;
+ }
+ aMessage.Complete(r);
+ }
+
+/**
+This will:
+ - Load t_logtofile.ldd
+ - Tell ldd to create the chunk
+ - Tell ldd to start logging
+*/
+TInt CLogToFileSession::Start()
+ {
+ TInt r = User::LoadLogicalDevice(KLogToFileName);
+ if(r !=KErrNone && r!=KErrAlreadyExists)
+ return r;
+ if((r = CLogToFileServer::iDevice.Open())!=KErrNone)
+ {
+ User::FreeLogicalDevice(KLogToFileName);
+ return r;
+ }
+ CLogToFileServer::iChunkStr.iSize = 0x10000; //64K chunk size - hard coded
+ if((r=CLogToFileServer::iDevice.CreateChunk(&CLogToFileServer::iChunkStr))<0)
+ {
+ User::FreeLogicalDevice(KLogToFileName);
+ return r;
+ }
+ CLogToFileServer::Chunk.SetHandle(r);
+ CLogToFileServer::iDevice.Start();
+ return KErrNone;
+}
+
+/**
+This will:
+ - Tell ldd to stop logging
+ - Put the content of the chunk into c:\logtofile.dat
+ - Tell ldd to close the chunk
+ - Unload t_logtofile.ldd
+*/
+TInt CLogToFileSession::Stop()
+{
+ TInt bytes = CLogToFileServer::iDevice.Stop();
+
+
+ RFs fs;
+ RFile file;
+ TInt r;
+ TRequestStatus status;
+
+ if(KErrNone != (r = fs.Connect()))
+ return r;
+ if(KErrNone != (r = file.Replace(fs, KFileName,EFileWrite)))
+ {
+ fs.Close();
+ return r;
+ }
+
+ TPtrC8 log(CLogToFileServer::Chunk.Base(),bytes);
+ file.Write(log,status);
+ User::WaitForRequest(status);
+ r = status.Int();
+ file.Close();
+ fs.Close();
+ CLogToFileServer::Chunk.Close();
+
+ CLogToFileServer::iDevice.RemoveChunk();
+ User::FreeLogicalDevice(KLogToFileName);
+ return r;
+}
+
+/**Sends request to the server*/
+TInt RLogToFileSession::Control(CLogToFileSession::TState aRequest)
+ {
+ RLogToFileSession p;
+ TInt r = p.CreateSession(KAppName, TVersion(), 0);
+ if (r == KErrNone)
+ p.SendReceive(aRequest);
+ return r;
+ }
+
+/**The entry point for the server thread.*/
+LOCAL_C TInt serverThreadEntryPoint(TAny*)
+ {
+ TInt r=0;
+ CLogToFileServer* pS=0;
+
+ CActiveScheduler *pR=new CActiveScheduler;
+ if (!pR) User::Panic(_L("Create ActSchdlr error"), KErrNoMemory);
+ CActiveScheduler::Install(pR);
+
+ pS=CLogToFileServer::New(0);
+ if (!pS)
+ {
+ delete pR;
+ User::Panic(_L("Create svr error"), KErrNoMemory);
+ }
+
+ r=pS->Start(KAppName);
+ if(r)
+ {
+ delete pS;
+ delete pR;
+ User::Panic(_L("Start svr error"), r);
+ }
+
+ RThread::Rendezvous(KErrNone);
+ CActiveScheduler::Start();
+ delete pS;
+ delete pR;
+ return(KErrNone);
+ }
+
+/**Reads the command line and set the matching pattern to be - what is after '-p='*/
+void SetPattern(void)
+ {
+ _LIT8(KPattern,"-p=");
+ TBuf<64> c;
+ User::CommandLine(c);
+ #if defined(_UNICODE)
+ TPtr8 ptr = c.Collapse();
+ #else
+ TPtr8 ptr(c.Ptr(),c.Length(),c.MaxLEngth());
+ #endif
+
+ TInt patternStart = ptr.FindF(KPattern);
+ if (patternStart < 0)
+ {
+ Pattern.SetLength(0);
+ return;
+ }
+ patternStart+=3;
+
+ TPtrC8 pattern (ptr.Ptr()+patternStart,Min(ptr.Length()-patternStart, KPatternMaxSize) );
+ CLogToFileServer::iChunkStr.iPattern.Copy(pattern);
+ }
+
+/**The main program if we have to start logging
+ It creates the server and sends start-logging request.*/
+void MainL()
+ {
+ RThread server;
+ TRequestStatus status;
+ TInt r = 0;
+
+ SetPattern();
+ r=server.Create(_L("LogToFileServer"),serverThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
+ User::LeaveIfError(r);
+ server.Resume();
+ server.Rendezvous(status);
+ User::WaitForRequest(status);
+ User::LeaveIfError(status.Int());
+
+ User::LeaveIfError(RLogToFileSession::Start());
+
+ server.Logon(status);
+ User::WaitForRequest(status);
+ }
+
+/**Returns true if 'stop' is found in the command line*/
+TBool GetStop()
+ {
+ _LIT(KStop,"stop");
+ TBuf<64> c;
+ User::CommandLine(c);
+ if (c.FindF(KStop) >= 0)
+ return ETrue;
+ return EFalse;
+ }
+
+/**LogToFile.exe entry point*/
+TInt E32Main()
+ {
+ if (GetStop())
+ return RLogToFileSession::Stop();
+
+ CTrapCleanup::New();
+ TRAPD(r,MainL());
+ return r;
+ }