|
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 } |