1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Definitions and constants for the class CATStorageServerSession |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <utf.h> |
|
22 #include <analyzetool/analyzetooltraceconstants.h> |
|
23 #include "atstorageserversession.h" |
|
24 #include "atstorageserver.h" |
|
25 #include "atstorageservercommon.h" |
|
26 #include "atmemoryentry.h" |
|
27 #include "atlog.h" |
|
28 #include "atdynprocessinfo.h" |
|
29 #include "atdriveinfo.h" |
|
30 |
|
31 // CONSTANTS |
|
32 |
|
33 // New file name start and end index. |
|
34 const TInt KNameIndexStart = 1; |
|
35 const TInt KNameIndexEnd = 100; |
|
36 |
|
37 // ==================== MEMBER FUNCTIONS for TAllocInfo ======================== |
|
38 |
|
39 // ----------------------------------------------------------------------------- |
|
40 // TAllocInfo::TAllocInfo |
|
41 // Implementation for the constructor of the class TAllocInfo |
|
42 // ----------------------------------------------------------------------------- |
|
43 // |
|
44 TAllocInfo::TAllocInfo( TUint32 aMemAddress, TInt aAllocSize ) : |
|
45 iMemAddress( aMemAddress ), |
|
46 iAllocSize( aAllocSize ) |
|
47 { |
|
48 } |
|
49 |
|
50 |
|
51 // ============== MEMBER FUNCTIONS for CATStorageServerSession ================= |
|
52 |
|
53 // ----------------------------------------------------------------------------- |
|
54 // CATStorageServerSession::CATStorageServerSession |
|
55 // C++ default constructor. It Does not contain any code that |
|
56 // might leave. |
|
57 // ----------------------------------------------------------------------------- |
|
58 // |
|
59 CATStorageServerSession::CATStorageServerSession( CATStorageServer& aStorageServer ) : |
|
60 iStorageServer( aStorageServer ), |
|
61 iError( 0 ), |
|
62 iLeakArray( KLeakArrayGranularity ), |
|
63 iProcessId( KNullProcessId ), |
|
64 iLoggingOngoing( EFalse ), |
|
65 iLogOption( KDefaultLoggingMode ), |
|
66 iCurAllocSize( 0 ), |
|
67 iMaxAllocs( 0 ), |
|
68 iMaxAllocSize( 0 ), |
|
69 iLogFile( KEmpty() ), |
|
70 iIsUdeb( 1 ) |
|
71 { |
|
72 LOGSTR1( "STSE CATStorageServerSession::CATStorageServerSession()" ); |
|
73 |
|
74 // Initialize iMicroSecondsAt1970 |
|
75 TTime time( KJanuaryFirst1970 ); |
|
76 iMicroSecondsAt1970 = time.Int64(); |
|
77 |
|
78 // Increment the server's session count by one (1) |
|
79 iStorageServer.IncSessionCount(); |
|
80 } |
|
81 |
|
82 // ----------------------------------------------------------------------------- |
|
83 // CATStorageServerSession::ConstructL |
|
84 // Symbian 2nd phase constructor can leave. |
|
85 // ----------------------------------------------------------------------------- |
|
86 // |
|
87 void CATStorageServerSession::ConstructL() |
|
88 { |
|
89 // Intentionally left empty |
|
90 } |
|
91 |
|
92 // ----------------------------------------------------------------------------- |
|
93 // CATStorageServerSession::NewL |
|
94 // Two-phased constructor. |
|
95 // ----------------------------------------------------------------------------- |
|
96 // |
|
97 CATStorageServerSession* CATStorageServerSession::NewL( CATStorageServer& aStorageServer ) |
|
98 { |
|
99 CATStorageServerSession* self = NewLC( aStorageServer ); |
|
100 CleanupStack::Pop( self ); |
|
101 |
|
102 return self; |
|
103 } |
|
104 |
|
105 // ----------------------------------------------------------------------------- |
|
106 // CATStorageServerSession::NewLC |
|
107 // Two-phased constructor. |
|
108 // ----------------------------------------------------------------------------- |
|
109 // |
|
110 CATStorageServerSession* CATStorageServerSession::NewLC( CATStorageServer& aStorageServer ) |
|
111 { |
|
112 CATStorageServerSession* self = new ( ELeave ) CATStorageServerSession( aStorageServer ); |
|
113 |
|
114 CleanupStack::PushL( self ); |
|
115 self->ConstructL(); |
|
116 return self; |
|
117 } |
|
118 |
|
119 // ----------------------------------------------------------------------------- |
|
120 // CATStorageServerSession::~CATStorageServerSession |
|
121 // Destructor |
|
122 // ----------------------------------------------------------------------------- |
|
123 CATStorageServerSession::~CATStorageServerSession() |
|
124 { |
|
125 LOGSTR1( "STSE CATStorageServerSession::~CATStorageServerSession()" ); |
|
126 |
|
127 // Empty the array and delete the referenced objects |
|
128 iLeakArray.ResetAndDestroy(); |
|
129 |
|
130 // Close the leak array |
|
131 iLeakArray.Close(); |
|
132 |
|
133 // Close the allocation info array |
|
134 iAllocInfoArray.Close(); |
|
135 |
|
136 // Check if process closed abnormal |
|
137 if ( iProcessId != KNullProcessId && |
|
138 iLoggingOngoing && iLogOption != EATLoggingOff && |
|
139 iError != KErrNoMemory ) |
|
140 { |
|
141 LogAbnormalEnd(); |
|
142 } |
|
143 |
|
144 // Close the file and the handle to the file server |
|
145 CloseFsAndFile(); |
|
146 |
|
147 // Remove the process with the current PID from the server's array of processes |
|
148 TRAP_IGNORE( iStorageServer.RemoveProcessL( iProcessId ) ); |
|
149 |
|
150 // Decrement the server's session count by one (1) |
|
151 iStorageServer.DecSessionCount(); |
|
152 } |
|
153 |
|
154 // ----------------------------------------------------------------------------- |
|
155 // CATStorageServerSession::ServiceL |
|
156 // This function is called by the client/server framework |
|
157 // ----------------------------------------------------------------------------- |
|
158 // |
|
159 void CATStorageServerSession::ServiceL( const RMessage2& aMessage ) |
|
160 { |
|
161 LOGSTR1( "STSE void CATStorageServerSession::ServiceL()" ); |
|
162 |
|
163 // If logging has been cancelled for this session, return immediately |
|
164 if( iLogOption == EATLoggingOff ) |
|
165 { |
|
166 aMessage.Complete( KErrCancel ); |
|
167 return; |
|
168 } |
|
169 |
|
170 switch ( aMessage.Function() ) |
|
171 { |
|
172 case CATStorageServer::EProcessStarted: |
|
173 { |
|
174 // If logging is not ongoing, set the log option |
|
175 if( !iLoggingOngoing ) |
|
176 { |
|
177 // Set the operation mode |
|
178 SetLogOption( aMessage ); |
|
179 } |
|
180 |
|
181 switch ( iLogOption ) |
|
182 { |
|
183 case EATLogToTrace: |
|
184 { |
|
185 iError = LogProcessStartTraceL( aMessage ); |
|
186 } |
|
187 break; |
|
188 |
|
189 case EATLogToFile: |
|
190 { |
|
191 iError = LogProcessStartedL( aMessage ); |
|
192 } |
|
193 break; |
|
194 |
|
195 default: |
|
196 { |
|
197 // Panic the client and set iError KErrCancel, because being |
|
198 // here implies that an illegal log option has been given. |
|
199 PanicClient( EAToolIllegalLogOption, aMessage ); |
|
200 iError = KErrCancel; |
|
201 } |
|
202 break; |
|
203 } |
|
204 } |
|
205 break; |
|
206 |
|
207 |
|
208 case CATStorageServer::EDllLoaded: |
|
209 { |
|
210 switch ( iLogOption ) |
|
211 { |
|
212 case EATLogToTrace: |
|
213 { |
|
214 iError = LogDllLoadTraceL( aMessage ); |
|
215 } |
|
216 break; |
|
217 |
|
218 case EATLogToFile: |
|
219 { |
|
220 iError = LogDllLoadedL( aMessage ); |
|
221 } |
|
222 break; |
|
223 |
|
224 default: |
|
225 { |
|
226 // Panic the client and set iError KErrCancel, because being |
|
227 // here implies that an illegal log option has been given. |
|
228 PanicClient( EAToolIllegalLogOption, aMessage ); |
|
229 iError = KErrCancel; |
|
230 } |
|
231 break; |
|
232 } |
|
233 } |
|
234 break; |
|
235 |
|
236 |
|
237 case CATStorageServer::EDllUnloaded: |
|
238 { |
|
239 switch ( iLogOption ) |
|
240 { |
|
241 case EATLogToTrace: |
|
242 { |
|
243 iError = LogDllUnloadTraceL( aMessage ); |
|
244 } |
|
245 break; |
|
246 |
|
247 case EATLogToFile: |
|
248 { |
|
249 iError = LogDllUnloadedL( aMessage ); |
|
250 } |
|
251 break; |
|
252 |
|
253 default: |
|
254 { |
|
255 // Panic the client and set iError KErrCancel, because being |
|
256 // here implies that an illegal log option has been given. |
|
257 PanicClient( EAToolIllegalLogOption, aMessage ); |
|
258 iError = KErrCancel; |
|
259 } |
|
260 break; |
|
261 } |
|
262 } |
|
263 break; |
|
264 |
|
265 |
|
266 case CATStorageServer::EMemoryAllocated: |
|
267 { |
|
268 switch ( iLogOption ) |
|
269 { |
|
270 case EATLogToTrace: |
|
271 { |
|
272 iError = LogMemoryAllocTraceL( aMessage ); |
|
273 } |
|
274 break; |
|
275 |
|
276 case EATLogToFile: |
|
277 { |
|
278 iError = LogMemoryAllocatedL( aMessage ); |
|
279 } |
|
280 break; |
|
281 |
|
282 default: |
|
283 { |
|
284 // Panic the client and set iError KErrCancel, because being |
|
285 // here implies that an illegal log option has been given. |
|
286 PanicClient( EAToolIllegalLogOption, aMessage ); |
|
287 iError = KErrCancel; |
|
288 } |
|
289 break; |
|
290 } |
|
291 } |
|
292 break; |
|
293 |
|
294 |
|
295 case CATStorageServer::EMemoryFreed: |
|
296 { |
|
297 switch ( iLogOption ) |
|
298 { |
|
299 case EATLogToTrace: |
|
300 { |
|
301 iError = LogMemoryFreedTraceL( aMessage ); |
|
302 } |
|
303 break; |
|
304 |
|
305 case EATLogToFile: |
|
306 { |
|
307 iError = LogMemoryFreedL( aMessage ); |
|
308 } |
|
309 break; |
|
310 |
|
311 default: |
|
312 { |
|
313 // Panic the client and set iError KErrCancel, because being |
|
314 // here implies that an illegal log option has been given. |
|
315 PanicClient( EAToolIllegalLogOption, aMessage ); |
|
316 iError = KErrCancel; |
|
317 } |
|
318 break; |
|
319 } |
|
320 } |
|
321 break; |
|
322 |
|
323 |
|
324 case CATStorageServer::EProcessEnded: |
|
325 { |
|
326 switch ( iLogOption ) |
|
327 { |
|
328 case EATLogToTrace: |
|
329 { |
|
330 iError = LogProcessEndTraceL( aMessage ); |
|
331 } |
|
332 break; |
|
333 |
|
334 case EATLogToFile: |
|
335 { |
|
336 iError = LogProcessEndedL( aMessage ); |
|
337 } |
|
338 break; |
|
339 |
|
340 default: |
|
341 { |
|
342 // Panic the client and set iError KErrCancel, because being |
|
343 // here implies that an illegal log option has been given. |
|
344 PanicClient( EAToolIllegalLogOption, aMessage ); |
|
345 iError = KErrCancel; |
|
346 } |
|
347 break; |
|
348 } |
|
349 } |
|
350 break; |
|
351 |
|
352 |
|
353 case CATStorageServer::EMemoryCheck: |
|
354 { |
|
355 switch ( iLogOption ) |
|
356 { |
|
357 case EATLogToTrace: |
|
358 { |
|
359 iError = CheckMemoryAddressTrace( aMessage ); |
|
360 } |
|
361 break; |
|
362 |
|
363 case EATLogToFile: |
|
364 { |
|
365 iError = CheckMemoryAddressL( aMessage ); |
|
366 } |
|
367 break; |
|
368 |
|
369 default: |
|
370 { |
|
371 // Panic the client and set iError KErrCancel, because being |
|
372 // here implies that an illegal log option has been given. |
|
373 PanicClient( EAToolIllegalLogOption, aMessage ); |
|
374 iError = KErrCancel; |
|
375 } |
|
376 break; |
|
377 } |
|
378 } |
|
379 break; |
|
380 |
|
381 |
|
382 case CATStorageServer::EGetProcesses: |
|
383 { |
|
384 iError = GetProcessesL( aMessage ); |
|
385 } |
|
386 break; |
|
387 |
|
388 |
|
389 case CATStorageServer::EGetDlls: |
|
390 { |
|
391 iError = GetDllsL( aMessage ); |
|
392 } |
|
393 break; |
|
394 |
|
395 case CATStorageServer::EGetLoggingMode: |
|
396 { |
|
397 iError = GetLoggingModeL( aMessage ); |
|
398 } |
|
399 break; |
|
400 |
|
401 case CATStorageServer::ESubtestStart: |
|
402 { |
|
403 iError = StartSubtestL( aMessage ); |
|
404 } |
|
405 break; |
|
406 |
|
407 case CATStorageServer::ESubtestStop: |
|
408 { |
|
409 iError = StopSubtestL( aMessage ); |
|
410 } |
|
411 break; |
|
412 |
|
413 case CATStorageServer::ESubtestStart2: |
|
414 { |
|
415 iError = StartSubtest2L( aMessage ); |
|
416 } |
|
417 break; |
|
418 |
|
419 case CATStorageServer::ESubtestStop2: |
|
420 { |
|
421 iError = StopSubtest2( aMessage ); |
|
422 } |
|
423 break; |
|
424 |
|
425 case CATStorageServer::EGetCurrentAllocs: |
|
426 { |
|
427 iError = GetCurrentAllocsL( aMessage ); |
|
428 } |
|
429 break; |
|
430 |
|
431 case CATStorageServer::EGetMaxAllocs: |
|
432 { |
|
433 iError = GetMaxAllocsL( aMessage ); |
|
434 } |
|
435 break; |
|
436 |
|
437 case CATStorageServer::ECancelLogging: |
|
438 { |
|
439 iError = CancelLoggingL( aMessage ); |
|
440 } |
|
441 break; |
|
442 |
|
443 case CATStorageServer::EGetUdeb: |
|
444 { |
|
445 iError = GetUdebL( aMessage ); |
|
446 } |
|
447 break; |
|
448 |
|
449 case CATStorageServer::EGetLoggingFile: |
|
450 { |
|
451 iError = GetLoggingFileL( aMessage ); |
|
452 } |
|
453 break; |
|
454 |
|
455 case CATStorageServer::EProcessUdeb: |
|
456 { |
|
457 SetUdeb( aMessage ); |
|
458 } |
|
459 break; |
|
460 |
|
461 case CATStorageServer::EIsMemoryAdded: |
|
462 { |
|
463 iError = IsMemoryAdded( aMessage ); |
|
464 LOGSTR2( "STSE > IsMemoryAdded err = %i", iError ); |
|
465 } |
|
466 break; |
|
467 |
|
468 default: |
|
469 { |
|
470 // Panic both the client and server, because being here implies |
|
471 // that there is an internal error in the client/server. |
|
472 PanicClient( EAToolBadRequest, aMessage ); |
|
473 StorageServerPanic( KCategoryServer, EAToolBadRequest ); |
|
474 } |
|
475 break; |
|
476 |
|
477 } |
|
478 |
|
479 // Complete the message, if it has not been already cancelled. |
|
480 if ( iError != KErrCancel ) |
|
481 { |
|
482 // Log the error code. Only KErrNoMemory errors are logged. |
|
483 if ( iLogOption == EATLogToFile && iError == KErrNoMemory ) |
|
484 { |
|
485 HandleError( iError ); |
|
486 } |
|
487 else if ( iLogOption == EATLogToTrace && iError == KErrNoMemory ) |
|
488 { |
|
489 HandleErrorTrace( iError ); |
|
490 } |
|
491 |
|
492 // Complete serving the message |
|
493 aMessage.Complete( iError ); |
|
494 } |
|
495 } |
|
496 |
|
497 // ----------------------------------------------------------------------------- |
|
498 // CATStorageServerSession::LogProcessStartedL() |
|
499 // Opens a logging file with the requested name and then writes information |
|
500 // on process start into the file. |
|
501 // ----------------------------------------------------------------------------- |
|
502 // |
|
503 TInt CATStorageServerSession::LogProcessStartedL( const RMessage2& aMessage ) |
|
504 { |
|
505 LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartedL()" ); |
|
506 |
|
507 // Panic the client and return, if this method has already been called for this |
|
508 // session object (and a logging file has been opened) |
|
509 if ( iLoggingOngoing ) |
|
510 { |
|
511 PanicClient( EAToolNotAllowed, aMessage ); |
|
512 return KErrCancel; |
|
513 } |
|
514 |
|
515 iError = KErrNone; |
|
516 |
|
517 LOGMEM; |
|
518 |
|
519 // READ THE FIRST ARGUMENT (descriptor) |
|
520 |
|
521 // Length of the first argument (index 0) |
|
522 TInt length = aMessage.GetDesLength( 0 ); |
|
523 |
|
524 LOGSTR2( "STSE length of the fileName: %i", length ); |
|
525 |
|
526 // Return if errors |
|
527 if ( length == KErrArgument || length == KErrBadDescriptor ) |
|
528 { |
|
529 return length; |
|
530 } |
|
531 |
|
532 // Construct a buffer for file name, and leave the pointer on Cleanup Stack |
|
533 HBufC* fileName = HBufC::NewLC( length ); |
|
534 TPtr fileNamePtr( fileName->Des() ); |
|
535 |
|
536 // Read the client side's descriptor at index 0 |
|
537 iError = aMessage.Read( 0, fileNamePtr ); |
|
538 |
|
539 if ( iError != KErrNone ) |
|
540 { |
|
541 CleanupStack::PopAndDestroy( fileName ); |
|
542 return iError; |
|
543 } |
|
544 |
|
545 // READ THE SECOND ARGUMENT (descriptor) |
|
546 |
|
547 // Length of the second argument (index 1) |
|
548 length = aMessage.GetDesLength( 1 ); |
|
549 |
|
550 LOGSTR2( "STSE length of the processName: %i", length ); |
|
551 |
|
552 // Return if errors |
|
553 if ( length == KErrArgument || length == KErrBadDescriptor ) |
|
554 { |
|
555 CleanupStack::PopAndDestroy( fileName ); |
|
556 return length; |
|
557 } |
|
558 |
|
559 HBufC8* processName = HBufC8::NewL( length ); |
|
560 TPtr8 bufPtr( processName->Des() ); |
|
561 |
|
562 // Read the client side's descriptor at index 1 |
|
563 iError = aMessage.Read( 1, bufPtr ); |
|
564 |
|
565 if ( iError != KErrNone ) |
|
566 { |
|
567 delete processName; |
|
568 CleanupStack::PopAndDestroy( fileName ); |
|
569 return iError; |
|
570 } |
|
571 |
|
572 // READ THE THIRD ARGUMENT (integer, a process ID) |
|
573 TInt processId = aMessage.Int2(); |
|
574 |
|
575 // Open a file server session and a file. The file |
|
576 // will be opened with the name received from the client |
|
577 iError = OpenFsAndFile( *fileName, *processName ); |
|
578 CleanupStack::PopAndDestroy( fileName ); |
|
579 // Return without logging, if an error occured |
|
580 if ( iError != KErrNone ) |
|
581 { |
|
582 // Delete the local objects |
|
583 delete processName; |
|
584 return iError; |
|
585 } |
|
586 |
|
587 // Get the home time for the configuration UI |
|
588 iTime.HomeTime(); |
|
589 |
|
590 // Add the process into the server's array of processes |
|
591 iError = iStorageServer.AddProcessL( *processName, |
|
592 processId, |
|
593 this, |
|
594 iTime.Int64() ); |
|
595 |
|
596 // Return without logging, if an error occured |
|
597 if ( iError ) |
|
598 { |
|
599 // Remove, if something was added regardless of the error |
|
600 // However, we must not remove an existing process |
|
601 if ( iError != KErrAlreadyExists ) |
|
602 { |
|
603 iStorageServer.RemoveProcessL( processId ); |
|
604 } |
|
605 return iError; |
|
606 } |
|
607 |
|
608 // Make a buffer that will be logged into the opened logging file |
|
609 TBuf8<KProcessStartBufLength> loggingBuf; |
|
610 loggingBuf.Format( KProcessStart, processName, processId ); |
|
611 |
|
612 delete processName; |
|
613 |
|
614 // Get the current universal time |
|
615 TInt64 timeFrom1970( GetTime() ); |
|
616 |
|
617 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
618 // format |
|
619 loggingBuf.AppendNum( timeFrom1970, EHex ); |
|
620 |
|
621 // Append udeb/urel information to the process start |
|
622 loggingBuf.Append( KSpace ); |
|
623 loggingBuf.AppendNum( iIsUdeb, EHex ); |
|
624 |
|
625 // Append trace version information |
|
626 loggingBuf.Append( KSpace ); |
|
627 loggingBuf.AppendNum( KATTraceVersion, EHex ); |
|
628 |
|
629 // Append a new line |
|
630 loggingBuf.Append( KNewLine ); |
|
631 |
|
632 // Write the buffer into the file |
|
633 iError = iFile.Write( loggingBuf ); |
|
634 |
|
635 // Return, if an error occured |
|
636 if ( iError ) |
|
637 { |
|
638 iStorageServer.RemoveProcessL( processId ); |
|
639 return iError; |
|
640 } |
|
641 |
|
642 LOGMEM; |
|
643 |
|
644 // Set the process ID value for this logging session |
|
645 iProcessId = processId; |
|
646 // Set logging session started |
|
647 iLoggingOngoing = ETrue; |
|
648 |
|
649 return iError; |
|
650 } |
|
651 |
|
652 // ----------------------------------------------------------------------------- |
|
653 // CATStorageServerSession::LogProcessStartTraceL() |
|
654 // ----------------------------------------------------------------------------- |
|
655 // |
|
656 TInt CATStorageServerSession::LogProcessStartTraceL( const RMessage2& aMessage ) |
|
657 { |
|
658 LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessStartTraceL()" ); |
|
659 |
|
660 // Panic the client and return, if this method has already been called for this |
|
661 // session object |
|
662 if ( iLoggingOngoing ) |
|
663 { |
|
664 PanicClient( EAToolNotAllowed, aMessage ); |
|
665 return KErrCancel; |
|
666 } |
|
667 |
|
668 iError = KErrNone; |
|
669 |
|
670 LOGMEM; |
|
671 |
|
672 // READ THE SECOND ARGUMENT (descriptor) |
|
673 // The first argument, file name, is ignored when logging thru trace |
|
674 |
|
675 // Length of the second argument (index 1) |
|
676 TInt length = aMessage.GetDesLength( 1 ); |
|
677 |
|
678 LOGSTR2( "STSE length of the processName: %i", length ); |
|
679 |
|
680 // Return if errors |
|
681 if ( length == KErrArgument || length == KErrBadDescriptor ) |
|
682 { |
|
683 return length; |
|
684 } |
|
685 |
|
686 HBufC8* processName = HBufC8::NewL( length ); |
|
687 TPtr8 bufPtr( processName->Des() ); |
|
688 |
|
689 // Read the client side's descriptor at index 1 |
|
690 iError = aMessage.Read( 1, bufPtr ); |
|
691 |
|
692 if ( iError != KErrNone ) |
|
693 { |
|
694 // Delete local objects and return |
|
695 delete processName; |
|
696 return iError; |
|
697 } |
|
698 |
|
699 // READ THE THIRD ARGUMENT (integer, a process ID) |
|
700 TInt processId = aMessage.Int2(); |
|
701 |
|
702 // Get the home time for the configuration UI |
|
703 iTime.HomeTime(); |
|
704 |
|
705 // Add the process into the server's array of processes |
|
706 iError = iStorageServer.AddProcessL( *processName, processId, this, |
|
707 iTime.Int64() ); |
|
708 |
|
709 // Return without logging, if an error occured |
|
710 if ( iError ) |
|
711 { |
|
712 // Remove, if something was added regardless of the error |
|
713 // However, we must not remove an existing process |
|
714 if ( iError != KErrAlreadyExists ) |
|
715 { |
|
716 iStorageServer.RemoveProcessL( processId ); |
|
717 } |
|
718 return iError; |
|
719 } |
|
720 |
|
721 // Make a buffer that will be logged |
|
722 TBuf8<KProcessStartBufLength> loggingBuf; |
|
723 |
|
724 loggingBuf.Format( KProcessStart, processName, processId ); |
|
725 |
|
726 delete processName; |
|
727 |
|
728 // Get the current universal time |
|
729 TInt64 timeFrom1970( GetTime() ); |
|
730 |
|
731 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
732 // format |
|
733 loggingBuf.AppendNum( timeFrom1970, EHex ); |
|
734 |
|
735 // Append udeb/urel information to the process start |
|
736 loggingBuf.Append( KSpace ); |
|
737 loggingBuf.AppendNum( iIsUdeb, EHex ); |
|
738 |
|
739 // Append version number |
|
740 loggingBuf.Append( KSpace ); |
|
741 loggingBuf.AppendNum( KATTraceVersion, EHex ); |
|
742 |
|
743 // Append a new line |
|
744 loggingBuf.Append( KNewLine ); |
|
745 |
|
746 // Log to trace |
|
747 TBuf<KProcessStartBufLength> traceBuf; |
|
748 traceBuf.Copy( loggingBuf ); |
|
749 RDebug::Print( KTraceMessage, processId ,&traceBuf ); |
|
750 |
|
751 LOGMEM; |
|
752 |
|
753 // Set the process ID value for this logging session |
|
754 iProcessId = processId; |
|
755 // Set logging session started |
|
756 iLoggingOngoing = ETrue; |
|
757 |
|
758 return KErrNone; |
|
759 } |
|
760 |
|
761 // ----------------------------------------------------------------------------- |
|
762 // CATStorageServerSession::LogDllLoadedL() |
|
763 // Logs to the file opened by the function LogProcessStartedL() |
|
764 // ----------------------------------------------------------------------------- |
|
765 // |
|
766 TInt CATStorageServerSession::LogDllLoadedL( const RMessage2& aMessage ) |
|
767 { |
|
768 LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadedL()" ); |
|
769 |
|
770 // Panic the client and return, if a logging session is not ongoing |
|
771 // ( can be started by calling the client's LogProcessStarted() ) |
|
772 if ( !iLoggingOngoing ) |
|
773 { |
|
774 PanicClient( EAToolNotAllowed, aMessage ); |
|
775 return KErrCancel; |
|
776 } |
|
777 |
|
778 iError = KErrNone; |
|
779 |
|
780 // Read the length of the first argument (index 0) |
|
781 TInt length = aMessage.GetDesLength( 0 ); |
|
782 |
|
783 // Return if errors |
|
784 if ( length == KErrArgument || length == KErrBadDescriptor ) |
|
785 { |
|
786 return length; |
|
787 } |
|
788 |
|
789 HBufC8* dllName = HBufC8::NewL( length ); |
|
790 TPtr8 bufPtr( dllName->Des() ); |
|
791 |
|
792 // Read the client side's descriptor (the argument 0) |
|
793 iError = aMessage.Read( 0, bufPtr ); |
|
794 |
|
795 if ( iError != KErrNone ) |
|
796 { |
|
797 delete dllName; |
|
798 return iError; |
|
799 } |
|
800 |
|
801 // Get the current universal time |
|
802 TInt64 timeFrom1970( GetTime() ); |
|
803 |
|
804 // Add this dll into the server's array |
|
805 TUint32 startAddress( aMessage.Int1() ); |
|
806 TUint32 endAddress( aMessage.Int2() ); |
|
807 iError = iStorageServer.AddDllL( iProcessId, |
|
808 TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) ); |
|
809 |
|
810 // Return without logging, if an error occured |
|
811 if ( iError ) |
|
812 { |
|
813 delete dllName; |
|
814 return iError; |
|
815 } |
|
816 |
|
817 // Make a buffer that will be logged into the opened logging file |
|
818 TBuf8<KDllLoadBufLength> loggingBuf; |
|
819 loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress ); |
|
820 |
|
821 delete dllName; |
|
822 |
|
823 // Write the buffer into a file and return the error code |
|
824 return iFile.Write( loggingBuf ); |
|
825 } |
|
826 |
|
827 // ----------------------------------------------------------------------------- |
|
828 // CATStorageServerSession::LogDllLoadTraceL() |
|
829 // ----------------------------------------------------------------------------- |
|
830 // |
|
831 TInt CATStorageServerSession::LogDllLoadTraceL( const RMessage2& aMessage ) |
|
832 { |
|
833 LOGSTR1( "STSE TInt CATStorageServerSession::LogDllLoadTraceL()" ); |
|
834 |
|
835 // Panic the client and return, if a logging session is not ongoing |
|
836 // ( can be started by calling the client's LogProcessStarted() ) |
|
837 if ( !iLoggingOngoing ) |
|
838 { |
|
839 PanicClient( EAToolNotAllowed, aMessage ); |
|
840 return KErrCancel; |
|
841 } |
|
842 |
|
843 iError = KErrNone; |
|
844 |
|
845 // Read the length of the first argument (index 0) |
|
846 TInt length = aMessage.GetDesLength( 0 ); |
|
847 |
|
848 // Return if errors |
|
849 if ( length == KErrArgument || length == KErrBadDescriptor ) |
|
850 { |
|
851 return length; |
|
852 } |
|
853 |
|
854 HBufC8* dllName = HBufC8::NewL( length ); |
|
855 TPtr8 bufPtr( dllName->Des() ); |
|
856 |
|
857 // Read the client side's descriptor (the argument 0) |
|
858 iError = aMessage.Read( 0, bufPtr ); |
|
859 |
|
860 if ( iError != KErrNone ) |
|
861 { |
|
862 delete dllName; |
|
863 return iError; |
|
864 } |
|
865 // Get the current universal time |
|
866 TInt64 timeFrom1970( GetTime() ); |
|
867 |
|
868 TUint32 startAddress( aMessage.Int1() ); |
|
869 TUint32 endAddress( aMessage.Int2() ); |
|
870 |
|
871 // Add this dll into the server's array |
|
872 iError = iStorageServer.AddDllL( iProcessId, |
|
873 TATDllInfo( startAddress, endAddress, timeFrom1970, *dllName ) ); |
|
874 |
|
875 // Return without logging, if an error occured |
|
876 if ( iError ) |
|
877 { |
|
878 delete dllName; |
|
879 return iError; |
|
880 } |
|
881 |
|
882 // Make a buffer that will be logged |
|
883 TBuf8<KDllLoadBufLength> loggingBuf; |
|
884 loggingBuf.Format( KDllLoad, dllName, timeFrom1970, startAddress, endAddress ); |
|
885 |
|
886 delete dllName; |
|
887 |
|
888 TBuf<KDllLoadBufLength> traceBuf; |
|
889 traceBuf.Copy( loggingBuf ); |
|
890 RDebug::Print( KTraceMessage, iProcessId ,&traceBuf ); |
|
891 return iError; |
|
892 } |
|
893 |
|
894 // ----------------------------------------------------------------------------- |
|
895 // CATStorageServerSession::LogDllUnloadedL() |
|
896 // Logs to the file opened by the function LogProcessStartedL() |
|
897 // ----------------------------------------------------------------------------- |
|
898 // |
|
899 TInt CATStorageServerSession::LogDllUnloadedL( const RMessage2& aMessage ) |
|
900 { |
|
901 LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadedL()" ); |
|
902 |
|
903 // Panic the client and return, if a logging session is not ongoing |
|
904 // ( can be started by calling the client's LogProcessStarted() ) |
|
905 if ( !iLoggingOngoing ) |
|
906 { |
|
907 PanicClient( EAToolNotAllowed, aMessage ); |
|
908 return KErrCancel; |
|
909 } |
|
910 |
|
911 iError = KErrNone; |
|
912 |
|
913 // Read the length of the first argument (index 0) |
|
914 TInt length = aMessage.GetDesLength( 0 ); |
|
915 |
|
916 LOGSTR2( "STSE length %i", length ); |
|
917 |
|
918 // Return if errors |
|
919 if ( length == KErrArgument || length == KErrBadDescriptor ) |
|
920 { |
|
921 return length; |
|
922 } |
|
923 |
|
924 HBufC8* dllName = HBufC8::NewL( length ); |
|
925 TPtr8 bufPtr( dllName->Des() ); |
|
926 |
|
927 // Read the client side's descriptor (the argument 0) |
|
928 iError = aMessage.Read( 0, bufPtr ); |
|
929 |
|
930 if ( iError != KErrNone ) |
|
931 { |
|
932 delete dllName; |
|
933 return iError; |
|
934 } |
|
935 |
|
936 TUint32 startAddress = aMessage.Int1(); |
|
937 TUint32 endAddress = aMessage.Int2(); |
|
938 |
|
939 // Get the current universal time |
|
940 TInt64 timeFrom1970( GetTime() ); |
|
941 |
|
942 // Make a buffer that will be logged into the opened logging file |
|
943 TBuf8<KDllUnloadBufLength> loggingBuf; |
|
944 loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress ); |
|
945 |
|
946 // Remove this dll from the server's array |
|
947 iError = iStorageServer.RemoveDllL( iProcessId, bufPtr ); |
|
948 |
|
949 delete dllName; |
|
950 |
|
951 // Return without logging, if an error occured |
|
952 if ( iError ) |
|
953 { |
|
954 return iError; |
|
955 } |
|
956 |
|
957 // Write the buffer into a file and return the error code |
|
958 return iFile.Write( loggingBuf ); |
|
959 } |
|
960 |
|
961 // ----------------------------------------------------------------------------- |
|
962 // CATStorageServerSession::LogDllUnloadTraceL() |
|
963 // ----------------------------------------------------------------------------- |
|
964 // |
|
965 TInt CATStorageServerSession::LogDllUnloadTraceL( const RMessage2& aMessage ) |
|
966 { |
|
967 LOGSTR1( "STSE TInt CATStorageServerSession::LogDllUnloadTraceL()" ); |
|
968 |
|
969 // Panic the client and return, if a logging session is not ongoing |
|
970 // ( can be started by calling the client's LogProcessStarted() ) |
|
971 if ( !iLoggingOngoing ) |
|
972 { |
|
973 PanicClient( EAToolNotAllowed, aMessage ); |
|
974 return KErrCancel; |
|
975 } |
|
976 |
|
977 iError = KErrNone; |
|
978 |
|
979 // Read the length of the first argument (index 0) |
|
980 TInt length = aMessage.GetDesLength( 0 ); |
|
981 |
|
982 LOGSTR2( "STSE length %i", length ); |
|
983 |
|
984 // Return if errors |
|
985 if ( length == KErrArgument || length == KErrBadDescriptor ) |
|
986 { |
|
987 return length; |
|
988 } |
|
989 |
|
990 HBufC8* dllName = HBufC8::NewL( length ); |
|
991 TPtr8 bufPtr( dllName->Des() ); |
|
992 |
|
993 // Read the client side's descriptor (the argument 0) |
|
994 iError = aMessage.Read( 0, bufPtr ); |
|
995 |
|
996 if ( iError != KErrNone ) |
|
997 { |
|
998 delete dllName; |
|
999 return iError; |
|
1000 } |
|
1001 |
|
1002 TUint32 startAddress = aMessage.Int1(); |
|
1003 TUint32 endAddress = aMessage.Int2(); |
|
1004 |
|
1005 // Get the current universal time |
|
1006 TInt64 timeFrom1970( GetTime() ); |
|
1007 |
|
1008 // Make a buffer that will be logged |
|
1009 TBuf8<KDllUnloadBufLength> loggingBuf; |
|
1010 loggingBuf.Format( KDllUnload, dllName, timeFrom1970, startAddress, endAddress ); |
|
1011 |
|
1012 // Remove this dll from the server's array |
|
1013 iError = iStorageServer.RemoveDllL( iProcessId, bufPtr ); |
|
1014 |
|
1015 delete dllName; |
|
1016 |
|
1017 // Return without logging, if an error occured |
|
1018 if ( iError ) |
|
1019 { |
|
1020 return iError; |
|
1021 } |
|
1022 |
|
1023 TBuf<KDllLoadBufLength> traceBuf; |
|
1024 traceBuf.Copy( loggingBuf ); |
|
1025 RDebug::Print( KTraceMessage, iProcessId ,&traceBuf ); |
|
1026 return iError; |
|
1027 } |
|
1028 |
|
1029 // ----------------------------------------------------------------------------- |
|
1030 // CATStorageServerSession::LogMemoryAllocatedL() |
|
1031 // Constructs a CATMemoryEntry object and appends it into iLeakArray. |
|
1032 // ----------------------------------------------------------------------------- |
|
1033 // |
|
1034 TInt CATStorageServerSession::LogMemoryAllocatedL( const RMessage2& aMessage ) |
|
1035 { |
|
1036 LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocatedL()" ); |
|
1037 |
|
1038 // Panic the client and return, if a logging session is not ongoing |
|
1039 // ( can be started by calling the client's LogProcessStarted() ) |
|
1040 if ( !iLoggingOngoing ) |
|
1041 { |
|
1042 PanicClient( EAToolNotAllowed, aMessage ); |
|
1043 return KErrCancel; |
|
1044 } |
|
1045 |
|
1046 // A pointer to a buffer of call stack's memory addresses |
|
1047 CBufFlat* stackBuf = NULL; |
|
1048 |
|
1049 iError = KErrNone; |
|
1050 |
|
1051 // Get the current universal time |
|
1052 TInt64 timeFrom1970( GetTime() ); |
|
1053 |
|
1054 // Read the first argument (index 0) |
|
1055 TUint32 memAddress = aMessage.Int0(); |
|
1056 if ( memAddress == 0 ) |
|
1057 { |
|
1058 return KErrNotSupported; |
|
1059 } |
|
1060 |
|
1061 // Read the length of the descriptor argument (index 1) that should include |
|
1062 // call stack memory addresses associated with this memory allocation |
|
1063 TInt bufferLength = aMessage.GetDesLength( 1 ); |
|
1064 |
|
1065 // Construct a buffer for aCallstack |
|
1066 stackBuf = CBufFlat::NewL( bufferLength ); |
|
1067 CleanupStack::PushL( stackBuf ); |
|
1068 |
|
1069 // Buffer position |
|
1070 TInt pos = 0; |
|
1071 |
|
1072 stackBuf->ExpandL( pos, bufferLength ); |
|
1073 |
|
1074 TPtr8 bufPtr = stackBuf->Ptr( pos ); |
|
1075 |
|
1076 // Read the descriptor argument into the buffer |
|
1077 aMessage.ReadL( 1, bufPtr ); |
|
1078 |
|
1079 // Read the third argument (index 2) that tells the size of this allocation |
|
1080 TInt size = aMessage.Int2(); |
|
1081 |
|
1082 // Construct a new CATMemoryEntry object. |
|
1083 // The ownership of the current stackBuf object is given to the "entry" object. |
|
1084 CATMemoryEntry* entry = |
|
1085 new (ELeave) CATMemoryEntry( memAddress, stackBuf, timeFrom1970, size ); |
|
1086 |
|
1087 // Pop stackBuf from CleanupStack and set it to NULL, because it is not used anymore. |
|
1088 CleanupStack::Pop( stackBuf ); |
|
1089 stackBuf = NULL; |
|
1090 |
|
1091 // Make sure that the same memory area is not tryed to be allocated a second time |
|
1092 TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match ); |
|
1093 |
|
1094 TInt index = iLeakArray.Find( entry, matcher ); |
|
1095 |
|
1096 if ( index == KErrNotFound ) |
|
1097 { |
|
1098 TLinearOrder<CATMemoryEntry> order( CATMemoryEntry::Compare ); |
|
1099 |
|
1100 // Insert the "entry" object into "iLeakArray". The ownership of |
|
1101 // the "entry" object is given to the array. |
|
1102 iError = iLeakArray.InsertInOrderAllowRepeats( entry, order ); |
|
1103 |
|
1104 // If an insertion to the array was not successful, delete the created |
|
1105 // entry manually and return. |
|
1106 if ( iError ) |
|
1107 { |
|
1108 delete entry; |
|
1109 return iError; |
|
1110 } |
|
1111 |
|
1112 // Make a TAllocInfo object, and give values for its members. |
|
1113 TAllocInfo allocInfo( memAddress, size ); |
|
1114 |
|
1115 // Insert the allocInfo object into iAllocInfoArray |
|
1116 iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo ); |
|
1117 |
|
1118 // If an insertion to the array was not successful, delete the created entry |
|
1119 // and remove its pointer from iLeakArray. |
|
1120 if ( iError ) |
|
1121 { |
|
1122 index = iLeakArray.Find( entry, matcher ); |
|
1123 // Delete the entry object and remove remove the pointer from the array |
|
1124 delete entry; |
|
1125 // The index should be in a legal range, because the earlier insertion of |
|
1126 // the entry was successful |
|
1127 iLeakArray.Remove( index ); |
|
1128 } |
|
1129 |
|
1130 // Otherwise update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables |
|
1131 |
|
1132 iCurAllocSize += size; |
|
1133 |
|
1134 // The count can never be negative => associate it to an unsigned int |
|
1135 TUint allocCount = iAllocInfoArray.Count(); |
|
1136 if ( allocCount > iMaxAllocs ) |
|
1137 { |
|
1138 iMaxAllocs = allocCount; |
|
1139 } |
|
1140 |
|
1141 if ( iCurAllocSize > iMaxAllocSize ) |
|
1142 { |
|
1143 iMaxAllocSize = iCurAllocSize; |
|
1144 } |
|
1145 |
|
1146 return iError; |
|
1147 } |
|
1148 |
|
1149 // This shouldn't happen, because the same memory area shouldn't be allocated |
|
1150 // more than once (without deallocating it first) |
|
1151 else |
|
1152 { |
|
1153 delete entry; |
|
1154 return KErrAlreadyExists; |
|
1155 } |
|
1156 } |
|
1157 |
|
1158 // ----------------------------------------------------------------------------- |
|
1159 // CATStorageServerSession::LogMemoryAllocTraceL() |
|
1160 // ----------------------------------------------------------------------------- |
|
1161 // |
|
1162 TInt CATStorageServerSession::LogMemoryAllocTraceL( const RMessage2& aMessage ) |
|
1163 { |
|
1164 LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL()" ); |
|
1165 |
|
1166 // Panic the client and return, if a logging session is not ongoing |
|
1167 // ( can be started by calling the client's LogProcessStarted() ) |
|
1168 if ( !iLoggingOngoing ) |
|
1169 { |
|
1170 PanicClient( EAToolNotAllowed, aMessage ); |
|
1171 return KErrCancel; |
|
1172 } |
|
1173 |
|
1174 // Read the first argument (index 0) |
|
1175 TUint32 memAddress = aMessage.Int0(); |
|
1176 if ( memAddress == 0 ) |
|
1177 { |
|
1178 return KErrNotSupported; |
|
1179 } |
|
1180 |
|
1181 // Read the third argument (index 2) that tells the size of this allocation |
|
1182 TInt size = aMessage.Int2(); |
|
1183 |
|
1184 // Append this allocation into the iAllocInfoArray array. This array is for |
|
1185 // providing the configuration UI with information on allocations |
|
1186 |
|
1187 // Make a TAllocInfo object, and give values for its members. |
|
1188 TAllocInfo allocInfo( memAddress, size ); |
|
1189 |
|
1190 // Insert the allocInfo object into iAllocInfoArray |
|
1191 iError = iAllocInfoArray.InsertInUnsignedKeyOrder( allocInfo ); |
|
1192 |
|
1193 // Log debug message if duplicated allocation. |
|
1194 if ( iError == KErrAlreadyExists ) |
|
1195 { |
|
1196 LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryAllocTraceL() Error, duplicate allocation :%i", memAddress ); |
|
1197 } |
|
1198 |
|
1199 // A pointer to a buffer of call stack's memory addresses |
|
1200 CBufFlat* stackBuf = NULL; |
|
1201 |
|
1202 // Get the current universal time |
|
1203 TInt64 timeFrom1970( GetTime() ); |
|
1204 |
|
1205 // Read the length of the descriptor argument (index 1) that should include |
|
1206 // call stack memory addresses associated with this memory allocation |
|
1207 TInt bufferLength = aMessage.GetDesLength( 1 ); |
|
1208 |
|
1209 // Construct a buffer for aCallstack |
|
1210 stackBuf = CBufFlat::NewL( bufferLength ); |
|
1211 CleanupStack::PushL( stackBuf ); |
|
1212 |
|
1213 // Buffer position |
|
1214 TInt pos( 0 ); |
|
1215 stackBuf->ExpandL( pos, bufferLength ); |
|
1216 |
|
1217 TPtr8 bufPtr = stackBuf->Ptr( pos ); |
|
1218 |
|
1219 // Read the descriptor argument (index 1) into the buffer |
|
1220 aMessage.ReadL( 1, bufPtr ); |
|
1221 |
|
1222 // Variable for the number of memory addresses in the call stack |
|
1223 TInt addrCount( 0 ); |
|
1224 TUint32 callStackAddr; |
|
1225 |
|
1226 // Read the first word of the buffer. This includes the number of |
|
1227 // memory addresses stored in the current stackBuf |
|
1228 stackBuf->Read( pos, &addrCount, KWordSize ); |
|
1229 |
|
1230 // Move the position one word onwards. |
|
1231 pos += KWordSize; |
|
1232 |
|
1233 // Create a 16-bit buffer, and a pointer descriptor for it |
|
1234 // ALLOCH <Memory address> <Time stamp> <Allocation size> <Call stack address count> |
|
1235 // <Call stack address> <Call stack address> ... |
|
1236 HBufC* traceBuf = HBufC::NewL( KMemAllocBufLength ); |
|
1237 TPtr tracePtr( traceBuf->Des() ); |
|
1238 |
|
1239 // Pop stackBuf from CleanupStack, since no leavable operations will be done |
|
1240 // anymore |
|
1241 CleanupStack::Pop( stackBuf ); |
|
1242 |
|
1243 // Append the tag implying a memory allocation line in the data file |
|
1244 tracePtr.Append( KMemoryAllocHeader ); |
|
1245 |
|
1246 // Append the start address of this allocation in the 32-bit (max 8 characters) |
|
1247 // hexadecimal text format. |
|
1248 tracePtr.AppendNum( memAddress, EHex ); |
|
1249 |
|
1250 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
1251 // format |
|
1252 tracePtr.Append( KSpaceTrace ); |
|
1253 tracePtr.AppendNum( timeFrom1970, EHex ); |
|
1254 |
|
1255 // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal |
|
1256 // text format. |
|
1257 tracePtr.Append( KSpaceTrace ); |
|
1258 tracePtr.AppendNum( size, EHex ); |
|
1259 |
|
1260 // Append call stack address count |
|
1261 tracePtr.Append( KSpaceTrace ); |
|
1262 tracePtr.AppendNum( addrCount, EHex ); |
|
1263 |
|
1264 // Calculate last item length |
|
1265 TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + |
|
1266 KSpaceLength + KNewlineLength ); |
|
1267 |
|
1268 TUint packetNumber( 1 ); |
|
1269 |
|
1270 // Go through all call stack's memory addresses associated with |
|
1271 // this memory allocation |
|
1272 for ( TInt j = 0; j < addrCount; j++ ) |
|
1273 { |
|
1274 // ALLOCF <Memory address> <Time stamp> <Packet number> |
|
1275 // <Call stack address> <Call stack address> ... |
|
1276 if ( tracePtr.Length() <= 0 ) |
|
1277 { |
|
1278 // Create alloc fragment message header |
|
1279 tracePtr.Append( KMemoryAllocFragment ); |
|
1280 tracePtr.AppendNum( memAddress, EHex ); |
|
1281 tracePtr.Append( KSpaceTrace ); |
|
1282 tracePtr.AppendNum( timeFrom1970, EHex ); |
|
1283 tracePtr.Append( KSpaceTrace ); |
|
1284 tracePtr.AppendNum( packetNumber, EHex ); |
|
1285 // Increase packet number |
|
1286 packetNumber++; |
|
1287 } |
|
1288 |
|
1289 // Read the next call stack's memory address stored in the buffer. |
|
1290 stackBuf->Read( pos, &callStackAddr, KWordSize ); |
|
1291 |
|
1292 // Append the read memory address as a hexadecimal number |
|
1293 tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr ); |
|
1294 |
|
1295 // Move the pos variable one word onwards. |
|
1296 pos += KWordSize; |
|
1297 |
|
1298 // Check if buffer max length exceed |
|
1299 if ( lastItemLength + tracePtr.Length() >= KMemAllocBufLength ) |
|
1300 { |
|
1301 tracePtr.Append( KNewLineTrace ); |
|
1302 // Log through debug channel |
|
1303 RDebug::Print( KTraceMessage, iProcessId, traceBuf ); |
|
1304 // Empty trace buffer |
|
1305 tracePtr.Delete( 0, tracePtr.MaxLength() ); |
|
1306 } |
|
1307 } |
|
1308 |
|
1309 // Send the last message if exists |
|
1310 if ( tracePtr.Length() > 0 ) |
|
1311 { |
|
1312 tracePtr.Append( KNewLineTrace ); |
|
1313 |
|
1314 // Log through debug channel |
|
1315 RDebug::Print( KTraceMessage, iProcessId, traceBuf ); |
|
1316 } |
|
1317 |
|
1318 delete traceBuf; |
|
1319 delete stackBuf; |
|
1320 |
|
1321 // Update the iCurAllocSize, iMaxAllocs and iMaxAllocSize variables |
|
1322 iCurAllocSize += size; |
|
1323 |
|
1324 // The count can never be negative => associate it to an unsigned int |
|
1325 TUint allocCount = iAllocInfoArray.Count(); |
|
1326 if ( allocCount > iMaxAllocs ) |
|
1327 { |
|
1328 iMaxAllocs = allocCount; |
|
1329 } |
|
1330 |
|
1331 if ( iCurAllocSize > iMaxAllocSize ) |
|
1332 { |
|
1333 iMaxAllocSize = iCurAllocSize; |
|
1334 } |
|
1335 |
|
1336 return KErrNone; |
|
1337 } |
|
1338 |
|
1339 // ----------------------------------------------------------------------------- |
|
1340 // CATStorageServerSession::LogMemoryFreedL() |
|
1341 // Removes a TATMemoryEntry object with the specified memory address from |
|
1342 // iLeakArray, if found. |
|
1343 // ----------------------------------------------------------------------------- |
|
1344 // |
|
1345 TInt CATStorageServerSession::LogMemoryFreedL( const RMessage2& aMessage ) |
|
1346 { |
|
1347 LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedL()" ); |
|
1348 |
|
1349 // Panic the client and return, if a logging session is not ongoing |
|
1350 // ( can be started by calling the client's LogProcessStarted() ) |
|
1351 if ( !iLoggingOngoing ) |
|
1352 { |
|
1353 PanicClient( EAToolNotAllowed, aMessage ); |
|
1354 return KErrCancel; |
|
1355 } |
|
1356 |
|
1357 // Get the memory address |
|
1358 TUint32 memAddress = aMessage.Int0(); |
|
1359 |
|
1360 // Remove this memory allocation from the leak array |
|
1361 TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match ); |
|
1362 CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 ); |
|
1363 TInt index = iLeakArray.Find( entry, matcher ); |
|
1364 delete entry; |
|
1365 |
|
1366 // Return, if the requested memory address was not found |
|
1367 // (had not been allocated) |
|
1368 if ( index == KErrNotFound ) |
|
1369 { |
|
1370 return index; |
|
1371 } |
|
1372 |
|
1373 // Delete the CATMemoryEntry object at "index" and remove from the array |
|
1374 delete iLeakArray[index]; |
|
1375 iLeakArray.Remove( index ); |
|
1376 |
|
1377 // Remove this memory allocation also from the allocation info array |
|
1378 // Make a TAllocInfo object for a "find" operation |
|
1379 TAllocInfo allocInfo( memAddress, 0 ); |
|
1380 index = iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ); |
|
1381 |
|
1382 // The index should not be KErrNotFound, because an object with this memory address |
|
1383 // was found in the iLeakArray array. If the index is out of range, something is |
|
1384 // badly wrong, so it would be alright to panic in that case. |
|
1385 if ( index == KErrNotFound ) |
|
1386 { |
|
1387 PanicClient( EAToolInternalError, aMessage ); |
|
1388 return KErrCancel; |
|
1389 } |
|
1390 |
|
1391 // Decrease the current alloc size and remove the requested allocation |
|
1392 // from iAllocInfoArray |
|
1393 iCurAllocSize -= iAllocInfoArray[index].iAllocSize; |
|
1394 iAllocInfoArray.Remove( index ); |
|
1395 |
|
1396 // If we are here, everything has gone alright |
|
1397 return KErrNone; |
|
1398 } |
|
1399 |
|
1400 // ----------------------------------------------------------------------------- |
|
1401 // CATStorageServerSession::IsMemoryAdded() |
|
1402 // Check a memory allocation (memory address) from an internal array. |
|
1403 // ----------------------------------------------------------------------------- |
|
1404 // |
|
1405 TInt CATStorageServerSession::IsMemoryAdded( const RMessage2& aMessage, |
|
1406 const TBool aRemoveAlloc ) |
|
1407 { |
|
1408 LOGSTR1( "STSE TInt CATStorageServerSession::IsMemoryAdded()" ); |
|
1409 |
|
1410 // Panic the client and return, if a logging session is not ongoing |
|
1411 // ( can be started by calling the client's LogProcessStarted() ) |
|
1412 if ( !iLoggingOngoing ) |
|
1413 { |
|
1414 PanicClient( EAToolNotAllowed, aMessage ); |
|
1415 return KErrCancel; |
|
1416 } |
|
1417 |
|
1418 // Read the first argument (index 0) |
|
1419 TUint32 memAddress = aMessage.Int0(); |
|
1420 |
|
1421 // Try to find this memory allocation from the allocation info array |
|
1422 |
|
1423 // Make a TAllocInfo object for a "find" operation |
|
1424 TAllocInfo allocInfo( memAddress, 0 ); |
|
1425 TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) ); |
|
1426 |
|
1427 if ( index == KErrNotFound ) |
|
1428 { |
|
1429 return index; |
|
1430 } |
|
1431 else if ( aRemoveAlloc ) |
|
1432 { |
|
1433 // Otherwise decrease the current alloc size and remove the requested allocation |
|
1434 // from iAllocInfoArray |
|
1435 iCurAllocSize -= iAllocInfoArray[index].iAllocSize; |
|
1436 iAllocInfoArray.Remove( index ); |
|
1437 } |
|
1438 |
|
1439 return KErrNone; |
|
1440 } |
|
1441 |
|
1442 // ----------------------------------------------------------------------------- |
|
1443 // CATStorageServerSession::LogMemoryFreedTraceL() |
|
1444 // ----------------------------------------------------------------------------- |
|
1445 // |
|
1446 TInt CATStorageServerSession::LogMemoryFreedTraceL( const RMessage2& aMessage ) |
|
1447 { |
|
1448 LOGSTR1( "STSE TInt CATStorageServerSession::LogMemoryFreedTraceL()" ); |
|
1449 |
|
1450 // Panic the client and return, if a logging session is not ongoing |
|
1451 // ( can be started by calling the client's LogProcessStarted() ) |
|
1452 if ( !iLoggingOngoing ) |
|
1453 { |
|
1454 PanicClient( EAToolNotAllowed, aMessage ); |
|
1455 return KErrCancel; |
|
1456 } |
|
1457 |
|
1458 // A pointer to a buffer of call stack's memory addresses |
|
1459 CBufFlat* stackBuf = NULL; |
|
1460 iError = KErrNone; |
|
1461 |
|
1462 // Read the first argument (index 0) |
|
1463 TUint32 memAddress = aMessage.Int0(); |
|
1464 |
|
1465 // Remove address from allocation table and its size from alloc size, |
|
1466 // if found from table. |
|
1467 TAllocInfo allocInfo( memAddress, 0 ); // Dummy info for search. |
|
1468 TInt index( iAllocInfoArray.FindInUnsignedKeyOrder( allocInfo ) ); |
|
1469 if ( index != KErrNotFound ) |
|
1470 { |
|
1471 // Decrease the current alloc size and remove the requested allocation |
|
1472 // from table. |
|
1473 iCurAllocSize -= iAllocInfoArray[index].iAllocSize; |
|
1474 iAllocInfoArray.Remove( index ); |
|
1475 } |
|
1476 else |
|
1477 { |
|
1478 LOGSTR2( "STSE TInt CATStorageServerSession::LogMemoryFreedTrace() Error, cannot find alloc for free: %i", memAddress ); |
|
1479 } |
|
1480 |
|
1481 // Read the length of the descriptor argument (index 1) that should include |
|
1482 // call stack memory addresses associated with this memory allocation |
|
1483 TInt bufferLength = aMessage.GetDesLength( 1 ); |
|
1484 |
|
1485 // Construct a buffer for aCallstack |
|
1486 stackBuf = CBufFlat::NewL( bufferLength ); |
|
1487 CleanupStack::PushL( stackBuf ); |
|
1488 |
|
1489 // Buffer position |
|
1490 TInt pos = 0; |
|
1491 |
|
1492 stackBuf->ExpandL( pos, bufferLength ); |
|
1493 |
|
1494 TPtr8 bufPtr = stackBuf->Ptr( pos ); |
|
1495 |
|
1496 // Read the descriptor argument (index 1) into the buffer |
|
1497 aMessage.ReadL( 1, bufPtr ); |
|
1498 |
|
1499 // Variable for the number of memory addresses in the call stack |
|
1500 TInt addrCount( 0 ); |
|
1501 TUint32 callStackAddr( 0 ); |
|
1502 |
|
1503 // Read the first word of the buffer. This includes the number of |
|
1504 // memory addresses stored in the current stackBuf |
|
1505 stackBuf->Read( pos, &addrCount, KWordSize ); |
|
1506 |
|
1507 // Move the position one word onwards. |
|
1508 pos += KWordSize; |
|
1509 |
|
1510 // Create a 16-bit buffer, and a pointer descriptor for it |
|
1511 HBufC* traceBuf = HBufC::NewL( KMemFreedBufLength ); |
|
1512 TPtr tracePtr( traceBuf->Des() ); |
|
1513 |
|
1514 // Pop stackBuf from CleanupStack, since no leavable operations will be done |
|
1515 // anymore |
|
1516 CleanupStack::Pop( stackBuf ); |
|
1517 |
|
1518 // Get the current universal time |
|
1519 TInt64 timeFrom1970( GetTime() ); |
|
1520 |
|
1521 // Memory deallocation header message. |
|
1522 // FREEH <Memory address> <Time stamp> <Call stack address count> <Call stack address> |
|
1523 // <Call stack address> ... |
|
1524 |
|
1525 // Append the tag implying a memory free line in the data file |
|
1526 tracePtr.Append( KMemoryFreedHeader ); |
|
1527 |
|
1528 // Append the start address of this allocation in the 32-bit (max 8 characters) |
|
1529 // hexadecimal text format. |
|
1530 tracePtr.AppendNum( memAddress, EHex ); |
|
1531 |
|
1532 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
1533 // format |
|
1534 tracePtr.Append( KSpaceTrace ); |
|
1535 tracePtr.AppendNum( timeFrom1970, EHex ); |
|
1536 |
|
1537 // Append call stack address count |
|
1538 tracePtr.Append( KSpaceTrace ); |
|
1539 tracePtr.AppendNum( addrCount, EHex ); |
|
1540 |
|
1541 // Packet number |
|
1542 TUint packetNumber( 1 ); |
|
1543 |
|
1544 // Calculate last item length |
|
1545 TInt lastItemLength( KTraceMessage().Length() + KHexa32Length + |
|
1546 KSpaceLength + KNewlineLength ); |
|
1547 |
|
1548 // Go through all call stack's memory addresses associated with |
|
1549 // this memory allocation |
|
1550 for ( TInt j = 0; j < addrCount; j++ ) |
|
1551 { |
|
1552 if ( tracePtr.Length() <= 0 ) |
|
1553 { |
|
1554 // Memory deallocation fragment message. |
|
1555 // FREEF <Memory address> <Time stamp> <Packet number> <Call stack address count> |
|
1556 // <Call stack address>... |
|
1557 // Create free fragment message header |
|
1558 tracePtr.Append( KMemoryFreedFragment ); |
|
1559 tracePtr.AppendNum( memAddress, EHex ); |
|
1560 tracePtr.Append( KSpaceTrace ); |
|
1561 tracePtr.AppendNum( timeFrom1970, EHex ); |
|
1562 tracePtr.Append( KSpaceTrace ); |
|
1563 tracePtr.AppendNum( packetNumber, EHex ); |
|
1564 // Increase packet number |
|
1565 packetNumber++; |
|
1566 } |
|
1567 |
|
1568 // Read the next call stack's memory address stored in the buffer. |
|
1569 stackBuf->Read( pos, &callStackAddr, KWordSize ); |
|
1570 |
|
1571 // Append the read memory address as a hexadecimal number |
|
1572 tracePtr.AppendFormat( KHexaNumberTrace, callStackAddr ); |
|
1573 |
|
1574 // Move the pos variable one word onwards. |
|
1575 pos += KWordSize; |
|
1576 |
|
1577 // Check if buffer max length exceed |
|
1578 if ( lastItemLength + tracePtr.Length() >= KMemFreedBufLength ) |
|
1579 { |
|
1580 tracePtr.Append( KNewLineTrace ); |
|
1581 // Log through debug channel |
|
1582 RDebug::Print( KTraceMessage, iProcessId, traceBuf ); |
|
1583 // Empty trace buffer |
|
1584 tracePtr.Delete( 0, tracePtr.MaxLength() ); |
|
1585 } |
|
1586 } |
|
1587 |
|
1588 // Send the last message if exists |
|
1589 if ( tracePtr.Length() > 0 ) |
|
1590 { |
|
1591 tracePtr.Append( KNewLineTrace ); |
|
1592 |
|
1593 // Log through debug channel |
|
1594 RDebug::Print( KTraceMessage, iProcessId, traceBuf ); |
|
1595 } |
|
1596 |
|
1597 delete traceBuf; |
|
1598 delete stackBuf; |
|
1599 // If we are here, everything has gone alright |
|
1600 return KErrNone; |
|
1601 } |
|
1602 |
|
1603 // ----------------------------------------------------------------------------- |
|
1604 // CATStorageServerSession::LogProcessEndedL() |
|
1605 // Prints memory leaks and information on process end into a file opened by the |
|
1606 // function LogProcessStartedL() |
|
1607 // ----------------------------------------------------------------------------- |
|
1608 // |
|
1609 TInt CATStorageServerSession::LogProcessEndedL( const RMessage2& aMessage ) |
|
1610 { |
|
1611 LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL()" ); |
|
1612 |
|
1613 // Panic the client and return, if a logging session is not ongoing |
|
1614 // ( can be started by calling the client's LogProcessStarted() ) |
|
1615 if ( !iLoggingOngoing ) |
|
1616 { |
|
1617 PanicClient( EAToolNotAllowed, aMessage ); |
|
1618 return KErrCancel; |
|
1619 } |
|
1620 |
|
1621 iError = KErrNone; |
|
1622 |
|
1623 // Read the sent process ID |
|
1624 TUint processId = aMessage.Int0(); |
|
1625 |
|
1626 // The process ID got from the client should equal iProcessId. |
|
1627 // If it does not, return KErrNotSupported |
|
1628 if ( processId != iProcessId ) |
|
1629 { |
|
1630 return KErrNotSupported; |
|
1631 } |
|
1632 |
|
1633 ////////////////////////////////////////////// |
|
1634 // Log memory leaks |
|
1635 ////////////////////////////////////////////// |
|
1636 |
|
1637 // Print the information on the memory allocations that were never freed |
|
1638 iError = PrintLeaksL( aMessage ); |
|
1639 |
|
1640 if ( iError != KErrNone ) |
|
1641 { |
|
1642 return iError; |
|
1643 } |
|
1644 |
|
1645 ////////////////////////////////////////////// |
|
1646 // Log handle leaks |
|
1647 ////////////////////////////////////////////// |
|
1648 |
|
1649 TUint handleLeakCount = aMessage.Int1(); |
|
1650 |
|
1651 if( handleLeakCount == 0 ) |
|
1652 { |
|
1653 LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndedL() No handle leaks to report" ); |
|
1654 } |
|
1655 else |
|
1656 { |
|
1657 // Make a buffer that will be logged |
|
1658 TBuf8<KHandleLeakBufLength> loggingBuf; |
|
1659 |
|
1660 // Set handle leak module name to unknown since it can not be defined. |
|
1661 // Write the handle leak count from aMessage. |
|
1662 loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount ); |
|
1663 |
|
1664 // Write the constructed string into the data file and return if error |
|
1665 iError = iFile.Write( loggingBuf ); |
|
1666 |
|
1667 if ( iError != KErrNone ) |
|
1668 { |
|
1669 return iError; |
|
1670 } |
|
1671 } |
|
1672 |
|
1673 ////////////////////////////////////////////// |
|
1674 // Log process end |
|
1675 ////////////////////////////////////////////// |
|
1676 |
|
1677 // Make a buffer that will be logged into the opened logging file |
|
1678 TBufC8<KProcessEndBufLength> processEndBuf; |
|
1679 |
|
1680 TPtr8 bufPtr = processEndBuf.Des(); |
|
1681 |
|
1682 bufPtr.AppendFormat( KProcessEnd, iProcessId ); |
|
1683 |
|
1684 // Get the current universal time |
|
1685 TInt64 timeFrom1970( GetTime() ); |
|
1686 |
|
1687 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
1688 // format |
|
1689 bufPtr.AppendNum( timeFrom1970, EHex ); |
|
1690 |
|
1691 // Append a new line |
|
1692 bufPtr.Append( KNewLine ); |
|
1693 |
|
1694 // Write the buffer into a file and return the error code |
|
1695 iError = iFile.Write( processEndBuf ); |
|
1696 |
|
1697 // Close the file and the handle to the file server |
|
1698 CloseFsAndFile(); |
|
1699 |
|
1700 // Remove the process from the server's array of processes |
|
1701 iError = iStorageServer.RemoveProcessL( processId ); |
|
1702 |
|
1703 // Reset iProcesssId and set the logging flag false |
|
1704 iProcessId = KNullProcessId; |
|
1705 iLoggingOngoing = EFalse; |
|
1706 |
|
1707 return iError; |
|
1708 } |
|
1709 |
|
1710 // ----------------------------------------------------------------------------- |
|
1711 // CATStorageServerSession::LogProcessEndTraceL() |
|
1712 // ----------------------------------------------------------------------------- |
|
1713 // |
|
1714 TInt CATStorageServerSession::LogProcessEndTraceL( const RMessage2& aMessage ) |
|
1715 { |
|
1716 LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL()" ); |
|
1717 |
|
1718 // Panic the client and return, if a logging session is not ongoing |
|
1719 // ( can be started by calling the client's LogProcessStarted() ) |
|
1720 if ( !iLoggingOngoing ) |
|
1721 { |
|
1722 PanicClient( EAToolNotAllowed, aMessage ); |
|
1723 return KErrCancel; |
|
1724 } |
|
1725 |
|
1726 iError = KErrNone; |
|
1727 |
|
1728 // Read the sent process ID |
|
1729 TUint processId = aMessage.Int0(); |
|
1730 |
|
1731 // The process ID got from the client should equal iProcessId. |
|
1732 // If it does not, return KErrNotSupported |
|
1733 if ( processId != iProcessId ) |
|
1734 { |
|
1735 return KErrNotSupported; |
|
1736 } |
|
1737 |
|
1738 ////////////////////////////////////////////// |
|
1739 // Log handle leaks |
|
1740 ////////////////////////////////////////////// |
|
1741 |
|
1742 TUint handleLeakCount = aMessage.Int1(); |
|
1743 |
|
1744 if( handleLeakCount == 0 ) |
|
1745 { |
|
1746 LOGSTR1( "STSE TInt CATStorageServerSession::LogProcessEndTraceL() No handle leaks to report" ); |
|
1747 } |
|
1748 else |
|
1749 { |
|
1750 // Make a buffer that will be logged |
|
1751 TBuf8<KHandleLeakBufLength> loggingBuf; |
|
1752 |
|
1753 // Make a 16-bit buffer that can be logged using RDebug |
|
1754 TBuf<KHandleLeakBufLength> traceBuf; |
|
1755 |
|
1756 // Set handle leak module name to unknown since it can not be defined. |
|
1757 // Write the handle leak count from aMessage. |
|
1758 loggingBuf.Format( KHandleLeak, &KUnknownModule, handleLeakCount ); |
|
1759 |
|
1760 traceBuf.Copy( loggingBuf ); |
|
1761 |
|
1762 // Log through debug channel |
|
1763 RDebug::Print( KTraceMessage, iProcessId , &traceBuf ); |
|
1764 } |
|
1765 |
|
1766 ////////////////////////////////////////////// |
|
1767 // Log process end |
|
1768 ////////////////////////////////////////////// |
|
1769 |
|
1770 // Make a buffer that will be logged |
|
1771 TBuf<KProcessEndBufLength> processEndBuf; |
|
1772 processEndBuf.AppendFormat( KProcessEndTrace, iProcessId ); |
|
1773 |
|
1774 // Get the current universal time |
|
1775 TInt64 timeFrom1970( GetTime() ); |
|
1776 |
|
1777 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
1778 // format |
|
1779 processEndBuf.AppendNum( timeFrom1970, EHex ); |
|
1780 |
|
1781 // Append a new line |
|
1782 processEndBuf.Append( KNewLineTrace ); |
|
1783 |
|
1784 // Log through debug channel |
|
1785 RDebug::Print( KTraceMessage, iProcessId, &processEndBuf ); |
|
1786 |
|
1787 // Remove the process from the server's array of processes |
|
1788 iError = iStorageServer.RemoveProcessL( iProcessId ); |
|
1789 |
|
1790 // Reset iProcesssId and set the logging flag false |
|
1791 iProcessId = KNullProcessId; |
|
1792 iLoggingOngoing = EFalse; |
|
1793 |
|
1794 return iError; |
|
1795 } |
|
1796 |
|
1797 // ----------------------------------------------------------------------------- |
|
1798 // CATStorageServerSession::CheckMemoryAddressL() |
|
1799 // Checks if given memory address can be found |
|
1800 // ----------------------------------------------------------------------------- |
|
1801 // |
|
1802 TInt CATStorageServerSession::CheckMemoryAddressL( const RMessage2& aMessage ) |
|
1803 { |
|
1804 LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressL()" ); |
|
1805 |
|
1806 // Panic the client and return, if a logging session is not ongoing |
|
1807 // ( can be started by calling the client's LogProcessStarted() ) |
|
1808 if ( !iLoggingOngoing ) |
|
1809 { |
|
1810 PanicClient( EAToolNotAllowed, aMessage ); |
|
1811 return KErrCancel; |
|
1812 } |
|
1813 |
|
1814 iError = KErrNone; |
|
1815 |
|
1816 // Check if memory address can be found in iLeakArray |
|
1817 TUint32 memAddress = aMessage.Int0(); |
|
1818 TIdentityRelation<CATMemoryEntry> matcher( CATMemoryEntry::Match ); |
|
1819 CATMemoryEntry* entry = new (ELeave) CATMemoryEntry( memAddress, NULL, 0, 0 ); |
|
1820 |
|
1821 // Get the index or an error code |
|
1822 iError = iLeakArray.Find( entry, matcher ); |
|
1823 delete entry; |
|
1824 |
|
1825 return iError; |
|
1826 } |
|
1827 |
|
1828 // ----------------------------------------------------------------------------- |
|
1829 // CATStorageServerSession::CheckMemoryAddressTrace() |
|
1830 // Checks if some memory address can be found |
|
1831 // ----------------------------------------------------------------------------- |
|
1832 // |
|
1833 TInt CATStorageServerSession::CheckMemoryAddressTrace( const RMessage2& aMessage ) |
|
1834 { |
|
1835 LOGSTR1( "STSE TInt CATStorageServerSession::CheckMemoryAddressTrace()" ); |
|
1836 |
|
1837 // Panic the client and return, if a logging session is not ongoing |
|
1838 // ( can be started by calling the client's LogProcessStarted() ) |
|
1839 if ( !iLoggingOngoing ) |
|
1840 { |
|
1841 PanicClient( EAToolNotAllowed, aMessage ); |
|
1842 return KErrCancel; |
|
1843 } |
|
1844 |
|
1845 // Always return KErrNone in this mode |
|
1846 return KErrNone; |
|
1847 } |
|
1848 |
|
1849 // ----------------------------------------------------------------------------- |
|
1850 // CATStorageServerSession::GetProcessesL() |
|
1851 // Checks if some memory address can be found |
|
1852 // ----------------------------------------------------------------------------- |
|
1853 // |
|
1854 TInt CATStorageServerSession::GetProcessesL( const RMessage2& aMessage ) |
|
1855 { |
|
1856 LOGSTR1( "STSE TInt CATStorageServerSession::GetProcessesL()" ); |
|
1857 |
|
1858 iError = KErrNone; |
|
1859 |
|
1860 TInt processInfoSize = sizeof( TATProcessInfo ); |
|
1861 |
|
1862 CBufFlat* processInfoBuf; |
|
1863 |
|
1864 // Buffer position |
|
1865 TInt pos( 0 ); |
|
1866 |
|
1867 // Calculate the length of the buffer to be constructed for processes |
|
1868 // One word will be reserved for the length of the array. |
|
1869 TInt bufferLength = KWordSize + KATMaxProcesses * processInfoSize; |
|
1870 |
|
1871 // Construct processInfoBuf and expand it before the beginning (index 0) |
|
1872 processInfoBuf = CBufFlat::NewL( bufferLength ); |
|
1873 CleanupStack::PushL( processInfoBuf ); |
|
1874 processInfoBuf->ExpandL( pos, bufferLength ); |
|
1875 |
|
1876 RArray<TATProcessInfo> processArray = iStorageServer.ProcessInfoArray(); |
|
1877 |
|
1878 // Variable for the number of TATProcessInfo objects in processArray |
|
1879 TInt count = processArray.Count(); |
|
1880 |
|
1881 // The count cannot be greater than KATMaxProcesses, because the client |
|
1882 // has reserved a buffer of this size to be filled by the server |
|
1883 if ( count > KATMaxProcesses ) |
|
1884 { |
|
1885 count = KATMaxProcesses; |
|
1886 } |
|
1887 |
|
1888 // Write the count (4 bytes) into the beginning of processInfoBuf |
|
1889 processInfoBuf->Write( pos, &count, KWordSize ); |
|
1890 |
|
1891 // Move the position one word onwards. |
|
1892 pos += KWordSize; |
|
1893 |
|
1894 // Write all the process info objects into the buffer |
|
1895 for ( TInt i = 0; i < count; i++ ) |
|
1896 { |
|
1897 TATProcessInfo& processInfo = processArray[i]; |
|
1898 |
|
1899 // Write the current process info into the buffer |
|
1900 processInfoBuf->Write( pos, &processInfo, processInfoSize ); |
|
1901 |
|
1902 // Move the pos variable onwards. |
|
1903 pos += processInfoSize; |
|
1904 } |
|
1905 |
|
1906 // Make a pointer descriptor pointing to the start of processInfoBuf |
|
1907 TPtr8 bufPtr( processInfoBuf->Ptr(0) ); |
|
1908 |
|
1909 // Write the buffer into aMessage at index 0 for the client |
|
1910 aMessage.WriteL( 0, bufPtr ); |
|
1911 |
|
1912 CleanupStack::PopAndDestroy( processInfoBuf ); |
|
1913 |
|
1914 return iError; |
|
1915 } |
|
1916 |
|
1917 // ----------------------------------------------------------------------------- |
|
1918 // CATStorageServerSession::GetDllsL() |
|
1919 // Checks if some memory address can be found |
|
1920 // ----------------------------------------------------------------------------- |
|
1921 // |
|
1922 TInt CATStorageServerSession::GetDllsL( const RMessage2& aMessage ) |
|
1923 { |
|
1924 LOGSTR1( "STSE TInt CATStorageServerSession::GetDllsL()" ); |
|
1925 |
|
1926 // Read the process ID at index 0 |
|
1927 TUint processId = aMessage.Int0(); |
|
1928 |
|
1929 // Size of a DLL descriptor |
|
1930 TInt sizeOfDllDesc = sizeof( TBuf8<KMaxLibraryName> ); |
|
1931 |
|
1932 // Buffer position |
|
1933 TInt pos( 0 ); |
|
1934 |
|
1935 // Calculate the length of the buffer to be constructed for DLL names. |
|
1936 // One word will be reserved for the length of the array. |
|
1937 TInt bufferLength = KWordSize + KATMaxDlls * sizeOfDllDesc; |
|
1938 |
|
1939 CBufFlat* dllBuf; |
|
1940 // Construct dllBuf and expand it before the beginning (index 0) |
|
1941 dllBuf = CBufFlat::NewL( bufferLength ); |
|
1942 CleanupStack::PushL( dllBuf ); |
|
1943 dllBuf->ExpandL( pos, bufferLength ); |
|
1944 |
|
1945 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
1946 iStorageServer.DynProcessInfoArray(); |
|
1947 |
|
1948 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
1949 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
1950 |
|
1951 // Find the index of a CATDynProcessInfo object with the given process ID |
|
1952 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
1953 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
1954 delete dynProcessInfo; |
|
1955 dynProcessInfo = NULL; |
|
1956 |
|
1957 // Return, if a process with the requested process ID was not found |
|
1958 if ( index == KErrNotFound ) |
|
1959 { |
|
1960 CleanupStack::PopAndDestroy( dllBuf ); |
|
1961 return index; |
|
1962 } |
|
1963 |
|
1964 // Get the wanted dynamic process info |
|
1965 dynProcessInfo = dynProcessArray[index]; |
|
1966 |
|
1967 // Fetch a reference to the desired DLL array |
|
1968 RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls; |
|
1969 |
|
1970 // Take the count of names in the array |
|
1971 TInt count = dllArray.Count(); |
|
1972 |
|
1973 // The count cannot be greater than KATMaxDlls, because the client |
|
1974 // has reserved a buffer of this size to be filled by the server |
|
1975 if ( count > KATMaxDlls ) |
|
1976 { |
|
1977 count = KATMaxDlls; |
|
1978 } |
|
1979 |
|
1980 // Write the count (4 bytes) into the beginning of dllBuf |
|
1981 dllBuf->Write( pos, &count, KWordSize ); |
|
1982 |
|
1983 // Move the position one word onwards. |
|
1984 pos += KWordSize; |
|
1985 |
|
1986 // Go through all DLL names objects sent to the server |
|
1987 for ( TInt i = 0; i < count; i++ ) |
|
1988 { |
|
1989 TBuf8<KMaxLibraryName>& dllName = dllArray[i].iName; |
|
1990 |
|
1991 // Write the current DLL name into the buffer |
|
1992 dllBuf->Write( pos, &dllName, sizeOfDllDesc ); |
|
1993 |
|
1994 // Move the pos variable onwards. |
|
1995 pos += sizeOfDllDesc; |
|
1996 } |
|
1997 |
|
1998 // Make a pointer descriptor pointing to the start of dllBuf |
|
1999 TPtr8 bufPtr( dllBuf->Ptr(0) ); |
|
2000 |
|
2001 // Write the whole buffer into aMessage at index 1 for the client |
|
2002 aMessage.WriteL( 1, bufPtr ); |
|
2003 |
|
2004 CleanupStack::PopAndDestroy( dllBuf ); |
|
2005 |
|
2006 // The dynProcessInfo object will not be deleted, because it is still owned by the |
|
2007 // server object's dynamic process info array. |
|
2008 dynProcessInfo = NULL; |
|
2009 |
|
2010 return KErrNone; |
|
2011 } |
|
2012 |
|
2013 // ----------------------------------------------------------------------------- |
|
2014 // CATStorageServerSession::GetLoggingModeL() |
|
2015 // ----------------------------------------------------------------------------- |
|
2016 // |
|
2017 TInt CATStorageServerSession::GetLoggingModeL( const RMessage2& aMessage ) |
|
2018 { |
|
2019 LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingModeL()" ); |
|
2020 |
|
2021 iError = KErrNone; |
|
2022 |
|
2023 // Read the process ID at index 0 |
|
2024 TUint processId = aMessage.Int0(); |
|
2025 |
|
2026 // Buffer position |
|
2027 TInt pos( 0 ); |
|
2028 |
|
2029 // The length of the buffer to be constructed for logging mode |
|
2030 TInt bufferLength = KWordSize; |
|
2031 |
|
2032 // Get the dynamic process info array |
|
2033 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
2034 iStorageServer.DynProcessInfoArray(); |
|
2035 |
|
2036 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
2037 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
2038 |
|
2039 // Find the index of a CATDynProcessInfo object with the given process ID |
|
2040 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
2041 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
2042 delete dynProcessInfo; |
|
2043 dynProcessInfo = NULL; |
|
2044 |
|
2045 // Return, if a process with the requested process ID was not found |
|
2046 if ( index == KErrNotFound ) |
|
2047 { |
|
2048 return index; |
|
2049 } |
|
2050 |
|
2051 // Otherwise get the wanted dynamic process info |
|
2052 dynProcessInfo = dynProcessArray[index]; |
|
2053 |
|
2054 // Get the desired process's associated session object |
|
2055 CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
2056 CBufFlat* loggingModeBuf; |
|
2057 // Construct allocInfoBuf and expand it before the beginning (index 0) |
|
2058 loggingModeBuf = CBufFlat::NewL( bufferLength ); |
|
2059 CleanupStack::PushL( loggingModeBuf ); |
|
2060 loggingModeBuf->ExpandL( 0, bufferLength ); |
|
2061 |
|
2062 // Write the current logging mode of the requested process into the buffer. |
|
2063 loggingModeBuf->Write( pos, &sessionObject->iLogOption, KWordSize ); |
|
2064 |
|
2065 // Make a pointer descriptor that points to the data of allocInfoBuf |
|
2066 TPtr8 bufPtr( loggingModeBuf->Ptr(0) ); |
|
2067 |
|
2068 // Write the whole buffer into aMessage at index 1 for the client |
|
2069 aMessage.WriteL( 1, bufPtr ); |
|
2070 |
|
2071 CleanupStack::PopAndDestroy( loggingModeBuf ); |
|
2072 |
|
2073 return iError; |
|
2074 } |
|
2075 |
|
2076 // ----------------------------------------------------------------------------- |
|
2077 // CATStorageServerSession::StartSubtestL() |
|
2078 // ----------------------------------------------------------------------------- |
|
2079 // |
|
2080 TInt CATStorageServerSession::StartSubtestL( const RMessage2& aMessage ) |
|
2081 { |
|
2082 LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtestL()" ); |
|
2083 |
|
2084 iError = KErrNone; |
|
2085 |
|
2086 // Read the process ID at index 0 |
|
2087 TUint processId = aMessage.Int0(); |
|
2088 |
|
2089 // Read the sub test ID at index 1 |
|
2090 TBuf8<KATMaxSubtestIdLength> subTestName; |
|
2091 iError = aMessage.Read( 1, subTestName ); |
|
2092 |
|
2093 // Return if reading was not successful |
|
2094 if ( iError != KErrNone ) |
|
2095 { |
|
2096 return iError; |
|
2097 } |
|
2098 |
|
2099 // Create another (non-8-bit) descriptor for logging to trace |
|
2100 // and copy the contents |
|
2101 TBuf<KATMaxSubtestIdLength> subTestNameTrace; |
|
2102 subTestNameTrace.Copy( subTestName ); |
|
2103 |
|
2104 // Read the handle count at index 2 |
|
2105 TInt handleCount = aMessage.Int2(); |
|
2106 |
|
2107 // FIND THE REQUESTED PROCESS |
|
2108 |
|
2109 // Get the dynamic process array |
|
2110 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
2111 iStorageServer.DynProcessInfoArray(); |
|
2112 |
|
2113 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
2114 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
2115 |
|
2116 // Find the index of a CATDynProcessInfo object with the given process ID |
|
2117 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
2118 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
2119 delete dynProcessInfo; |
|
2120 dynProcessInfo = NULL; |
|
2121 |
|
2122 // Return, if a process with the requested process ID was not found |
|
2123 if ( index == KErrNotFound ) |
|
2124 { |
|
2125 return index; |
|
2126 } |
|
2127 |
|
2128 // Get the wanted dynamic process info |
|
2129 dynProcessInfo = dynProcessArray[index]; |
|
2130 |
|
2131 // Get the desired process's associated session object |
|
2132 const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
2133 |
|
2134 // Make a buffer for logging thru trace |
|
2135 TBuf<KTestStartBufLength> loggingBuf; |
|
2136 |
|
2137 // Copy the line tag into the buffer |
|
2138 loggingBuf.Copy( KSubtestStart ); |
|
2139 |
|
2140 // Get the current universal time |
|
2141 TInt64 timeFrom1970( GetTime() ); |
|
2142 |
|
2143 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
2144 // format |
|
2145 loggingBuf.AppendNum( timeFrom1970, EHex ); |
|
2146 |
|
2147 // Append a space |
|
2148 loggingBuf.Append( KSpaceTrace ); |
|
2149 |
|
2150 // Append the sub test ID |
|
2151 loggingBuf.Append( subTestNameTrace ); |
|
2152 |
|
2153 // Append a space |
|
2154 loggingBuf.Append( KSpaceTrace ); |
|
2155 |
|
2156 // Append current handle leak count |
|
2157 loggingBuf.AppendNum( handleCount ); |
|
2158 |
|
2159 // Append a new line |
|
2160 loggingBuf.Append( KNewLineTrace ); |
|
2161 |
|
2162 // Log the string through trace |
|
2163 iError = sessionObject->LogThroughTrace( loggingBuf ); |
|
2164 |
|
2165 // ******************* |
|
2166 // Send loaded DLL's |
|
2167 // ******************* |
|
2168 |
|
2169 // Fetch a reference to the desired DLL array |
|
2170 RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls; |
|
2171 |
|
2172 // Take the count of dll info items |
|
2173 TInt count( dllArray.Count() ); |
|
2174 LOGSTR2( "STSE > dllArray.Count( %i )", count ); |
|
2175 |
|
2176 // Create buffers |
|
2177 TBuf<KDllLoadBufLength> traceBuf; |
|
2178 TBuf8<KDllLoadBufLength> dllBuf; |
|
2179 |
|
2180 for ( TInt x = 0; x < count; x++ ) |
|
2181 { |
|
2182 dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime, |
|
2183 dllArray[x].iStartAddress, dllArray[x].iEndAddress ); |
|
2184 traceBuf.Copy( dllBuf ); |
|
2185 |
|
2186 // Log the string through trace |
|
2187 iError = sessionObject->LogThroughTrace( traceBuf ); |
|
2188 if ( iError != KErrNone ) |
|
2189 { |
|
2190 LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError ); |
|
2191 } |
|
2192 } |
|
2193 sessionObject = NULL; |
|
2194 |
|
2195 return iError; |
|
2196 } |
|
2197 |
|
2198 // ----------------------------------------------------------------------------- |
|
2199 // CATStorageServerSession::StopSubtestL() |
|
2200 // ----------------------------------------------------------------------------- |
|
2201 // |
|
2202 TInt CATStorageServerSession::StopSubtestL( const RMessage2& aMessage ) |
|
2203 { |
|
2204 LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtestL()" ); |
|
2205 |
|
2206 iError = KErrNone; |
|
2207 |
|
2208 // Read the process ID at index 0 |
|
2209 TUint processId = aMessage.Int0(); |
|
2210 |
|
2211 // Read the sub test ID at index 1 |
|
2212 TBuf8<KATMaxSubtestIdLength> subTestName; |
|
2213 iError = aMessage.Read( 1, subTestName ); |
|
2214 |
|
2215 // Return if reading was not successful |
|
2216 if ( iError != KErrNone ) |
|
2217 { |
|
2218 return iError; |
|
2219 } |
|
2220 |
|
2221 // Create another (non-8-bit) descriptor for logging to trace, |
|
2222 // and copy the contents |
|
2223 TBuf<KATMaxSubtestIdLength> subTestNameTrace; |
|
2224 subTestNameTrace.Copy( subTestName ); |
|
2225 |
|
2226 // Read the handle count at index 2 |
|
2227 TInt handleCount = aMessage.Int2(); |
|
2228 |
|
2229 // FIND THE REQUESTED PROCESS |
|
2230 |
|
2231 // Get the dynamic process array |
|
2232 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
2233 iStorageServer.DynProcessInfoArray(); |
|
2234 |
|
2235 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
2236 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
2237 |
|
2238 // Find the index of a CATDynProcessInfo object with the given process ID |
|
2239 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
2240 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
2241 delete dynProcessInfo; |
|
2242 dynProcessInfo = NULL; |
|
2243 |
|
2244 // Return, if a process with the requested process ID was not found |
|
2245 if ( index == KErrNotFound ) |
|
2246 { |
|
2247 return index; |
|
2248 } |
|
2249 |
|
2250 // Get the wanted dynamic process info |
|
2251 dynProcessInfo = dynProcessArray[index]; |
|
2252 |
|
2253 // Get the desired process's associated session object |
|
2254 const CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
2255 |
|
2256 // Make a buffer for logging thru trace |
|
2257 TBuf<KTestEndBufLength> loggingBuf; |
|
2258 |
|
2259 // Copy the line tag into the buffer |
|
2260 loggingBuf.Copy( KSubtestEnd ); |
|
2261 |
|
2262 // Get the current universal time |
|
2263 TInt64 timeFrom1970( GetTime() ); |
|
2264 |
|
2265 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
2266 // format |
|
2267 loggingBuf.AppendNum( timeFrom1970, EHex ); |
|
2268 |
|
2269 // Append a space |
|
2270 loggingBuf.Append( KSpaceTrace ); |
|
2271 |
|
2272 // Append the sub test ID |
|
2273 loggingBuf.Append( subTestNameTrace ); |
|
2274 |
|
2275 // Append a space |
|
2276 loggingBuf.Append( KSpaceTrace ); |
|
2277 |
|
2278 // Append current handle leak count |
|
2279 loggingBuf.AppendNum( handleCount ); |
|
2280 |
|
2281 // Append a new line |
|
2282 loggingBuf.Append( KNewLineTrace ); |
|
2283 |
|
2284 // Log the string through trace |
|
2285 iError = sessionObject->LogThroughTrace( loggingBuf ); |
|
2286 |
|
2287 sessionObject = NULL; |
|
2288 |
|
2289 return iError; |
|
2290 } |
|
2291 |
|
2292 // ----------------------------------------------------------------------------- |
|
2293 // CATStorageServerSession::StartSubtest2L() |
|
2294 // ----------------------------------------------------------------------------- |
|
2295 // |
|
2296 TInt CATStorageServerSession::StartSubtest2L( const RMessage2& aMessage ) |
|
2297 { |
|
2298 LOGSTR1( "STSE TInt CATStorageServerSession::StartSubtest2L()" ); |
|
2299 |
|
2300 iError = KErrNone; |
|
2301 |
|
2302 // Read the sub test ID at index 0 |
|
2303 TBuf8<KATMaxSubtestIdLength> subTestName; |
|
2304 iError = aMessage.Read( 0, subTestName ); |
|
2305 |
|
2306 // Return if reading was not successful |
|
2307 if ( iError != KErrNone ) |
|
2308 { |
|
2309 return iError; |
|
2310 } |
|
2311 |
|
2312 // Create another (non-8-bit) descriptor for logging to trace |
|
2313 // and copy the contents |
|
2314 TBuf<KATMaxSubtestIdLength> subTestNameTrace; |
|
2315 subTestNameTrace.Copy( subTestName ); |
|
2316 |
|
2317 // Make a buffer for logging thru trace |
|
2318 TBuf<KTestStartBufLength> loggingBuf; |
|
2319 |
|
2320 // Copy the line tag into the buffer |
|
2321 loggingBuf.Copy( KSubtestStart ); |
|
2322 |
|
2323 // Get the current universal time |
|
2324 TInt64 timeFrom1970( GetTime() ); |
|
2325 |
|
2326 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
2327 // format |
|
2328 loggingBuf.AppendNum( timeFrom1970, EHex ); |
|
2329 |
|
2330 // Append a space |
|
2331 loggingBuf.Append( KSpaceTrace ); |
|
2332 |
|
2333 // Append the sub test ID |
|
2334 loggingBuf.Append( subTestNameTrace ); |
|
2335 |
|
2336 // Append a new line |
|
2337 loggingBuf.Append( KNewLineTrace ); |
|
2338 |
|
2339 // Log the string through trace |
|
2340 iError = LogThroughTrace( loggingBuf ); |
|
2341 |
|
2342 // ******************* |
|
2343 // Send loaded DLL's |
|
2344 // ******************* |
|
2345 |
|
2346 // Get the dynamic process array |
|
2347 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
2348 iStorageServer.DynProcessInfoArray(); |
|
2349 |
|
2350 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
2351 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( iProcessId ); |
|
2352 |
|
2353 // Find the index of a CATDynProcessInfo object with the given process ID |
|
2354 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
2355 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
2356 delete dynProcessInfo; |
|
2357 dynProcessInfo = NULL; |
|
2358 |
|
2359 // Return, if a process with the requested process ID was not found |
|
2360 if ( index == KErrNotFound ) |
|
2361 { |
|
2362 return index; |
|
2363 } |
|
2364 |
|
2365 // Get the wanted dynamic process info |
|
2366 dynProcessInfo = dynProcessArray[index]; |
|
2367 |
|
2368 // Fetch a reference to the desired DLL array |
|
2369 RArray<TATDllInfo>& dllArray = dynProcessInfo->iDlls; |
|
2370 |
|
2371 // Take the count of dll info items |
|
2372 TInt count( dllArray.Count() ); |
|
2373 LOGSTR2( "STSE > dllArray.Count( %i )", count ); |
|
2374 |
|
2375 // Create buffers |
|
2376 TBuf<KDllLoadBufLength> traceBuf; |
|
2377 TBuf8<KDllLoadBufLength> dllBuf; |
|
2378 |
|
2379 for ( TInt x = 0; x < count; x++ ) |
|
2380 { |
|
2381 dllBuf.Format( KDllLoad, &dllArray[x].iName, dllArray[x].iLoadTime, |
|
2382 dllArray[x].iStartAddress, dllArray[x].iEndAddress ); |
|
2383 traceBuf.Copy( dllBuf ); |
|
2384 |
|
2385 // Log the string through trace |
|
2386 iError = LogThroughTrace( traceBuf ); |
|
2387 if ( iError != KErrNone ) |
|
2388 { |
|
2389 LOGSTR2( "STSE > LogThroughTrace() err( %i )", iError ); |
|
2390 } |
|
2391 } |
|
2392 |
|
2393 return iError; |
|
2394 } |
|
2395 |
|
2396 // ----------------------------------------------------------------------------- |
|
2397 // CATStorageServerSession::StopSubtest2() |
|
2398 // ----------------------------------------------------------------------------- |
|
2399 // |
|
2400 TInt CATStorageServerSession::StopSubtest2( const RMessage2& aMessage ) |
|
2401 { |
|
2402 LOGSTR1( "STSE TInt CATStorageServerSession::StopSubtest2()" ); |
|
2403 |
|
2404 iError = KErrNone; |
|
2405 |
|
2406 // Read the sub test ID at index 0 |
|
2407 TBuf8<KATMaxSubtestIdLength> subTestName; |
|
2408 iError = aMessage.Read( 0, subTestName ); |
|
2409 |
|
2410 // Return if reading was not successful |
|
2411 if ( iError != KErrNone ) |
|
2412 { |
|
2413 return iError; |
|
2414 } |
|
2415 |
|
2416 // Create another (non-8-bit) descriptor for logging to trace, |
|
2417 // and copy the contents |
|
2418 TBuf<KATMaxSubtestIdLength> subTestNameTrace; |
|
2419 subTestNameTrace.Copy( subTestName ); |
|
2420 |
|
2421 // Make a buffer for logging thru trace |
|
2422 TBuf<KTestEndBufLength> loggingBuf; |
|
2423 |
|
2424 // Copy the line tag into the buffer |
|
2425 loggingBuf.Copy( KSubtestEnd ); |
|
2426 |
|
2427 // Get the current universal time |
|
2428 TInt64 timeFrom1970( GetTime() ); |
|
2429 |
|
2430 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
2431 // format |
|
2432 loggingBuf.AppendNum( timeFrom1970, EHex ); |
|
2433 |
|
2434 // Append a space |
|
2435 loggingBuf.Append( KSpaceTrace ); |
|
2436 |
|
2437 // Append the sub test ID |
|
2438 loggingBuf.Append( subTestNameTrace ); |
|
2439 |
|
2440 // Append a new line |
|
2441 loggingBuf.Append( KNewLineTrace ); |
|
2442 |
|
2443 // Log the string through trace |
|
2444 iError = LogThroughTrace( loggingBuf ); |
|
2445 |
|
2446 return iError; |
|
2447 } |
|
2448 |
|
2449 // ----------------------------------------------------------------------------- |
|
2450 // CATStorageServerSession::GetCurrentAllocsL() |
|
2451 // ----------------------------------------------------------------------------- |
|
2452 // |
|
2453 TInt CATStorageServerSession::GetCurrentAllocsL( const RMessage2& aMessage ) |
|
2454 { |
|
2455 LOGSTR1( "STSE TInt CATStorageServerSession::GetCurrentAllocsL()" ); |
|
2456 |
|
2457 iError = KErrNone; |
|
2458 |
|
2459 // Read the process ID at index 0 |
|
2460 TUint processId = aMessage.Int0(); |
|
2461 TUint32 allocNumber( 0 ); |
|
2462 TUint32 allocSize( 0 ); |
|
2463 |
|
2464 // Buffer position |
|
2465 TInt pos( 0 ); |
|
2466 |
|
2467 // The length of the buffer to be constructed for allocation number and size |
|
2468 TInt bufferLength = KWordSize + KWordSize; |
|
2469 |
|
2470 // Get the dynamic process info array |
|
2471 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
2472 iStorageServer.DynProcessInfoArray(); |
|
2473 |
|
2474 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
2475 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
2476 |
|
2477 // Find the index of a CATDynProcessInfo object with the given process ID |
|
2478 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
2479 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
2480 delete dynProcessInfo; |
|
2481 dynProcessInfo = NULL; |
|
2482 |
|
2483 // Return, if a process with the requested process ID was not found |
|
2484 if ( index == KErrNotFound ) |
|
2485 { |
|
2486 return index; |
|
2487 } |
|
2488 |
|
2489 // Otherwise get the wanted dynamic process info |
|
2490 dynProcessInfo = dynProcessArray[index]; |
|
2491 |
|
2492 // Get the desired process's associated session object |
|
2493 CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
2494 |
|
2495 // Get the alloc info array of that session object |
|
2496 RArray<TAllocInfo> allocInfo = sessionObject->AllocInfoArray(); |
|
2497 |
|
2498 // Get the values for current allocations number and size |
|
2499 allocNumber = allocInfo.Count(); |
|
2500 |
|
2501 // Calculate the total size of the current allocations |
|
2502 for ( TUint32 i = 0; i < allocNumber; i++ ) |
|
2503 { |
|
2504 allocSize += allocInfo[i].iAllocSize; |
|
2505 } |
|
2506 |
|
2507 LOGSTR2( "STSE allocSize: %u", allocSize ); |
|
2508 LOGSTR2( "STSE iCurAllocSize: %u", iCurAllocSize ); |
|
2509 |
|
2510 CBufFlat* allocInfoBuf; |
|
2511 // Construct allocInfoBuf and expand it before the beginning (index 0) |
|
2512 allocInfoBuf = CBufFlat::NewL( bufferLength ); |
|
2513 CleanupStack::PushL( allocInfoBuf ); |
|
2514 allocInfoBuf->ExpandL( 0, bufferLength ); |
|
2515 |
|
2516 // Write the current number of allocations of the requested process into the buffer. |
|
2517 allocInfoBuf->Write( pos, &allocNumber, KWordSize ); |
|
2518 |
|
2519 // Move the position one word onwards |
|
2520 pos += KWordSize; |
|
2521 |
|
2522 // Write the current total size of the allocations of the requested process into the |
|
2523 // buffer. |
|
2524 allocInfoBuf->Write( pos, &allocSize, KWordSize ); |
|
2525 |
|
2526 // Make a pointer descriptor that points to the data of allocInfoBuf |
|
2527 TPtr8 bufPtr( allocInfoBuf->Ptr(0) ); |
|
2528 |
|
2529 // Write the whole buffer into aMessage at index 1 for the client |
|
2530 aMessage.WriteL( 1, bufPtr ); |
|
2531 |
|
2532 CleanupStack::PopAndDestroy( allocInfoBuf ); |
|
2533 |
|
2534 return iError; |
|
2535 } |
|
2536 |
|
2537 // ----------------------------------------------------------------------------- |
|
2538 // CATStorageServerSession::GetMaxAllocsL() |
|
2539 // ----------------------------------------------------------------------------- |
|
2540 // |
|
2541 TInt CATStorageServerSession::GetMaxAllocsL( const RMessage2& aMessage ) |
|
2542 { |
|
2543 LOGSTR1( "STSE TInt CATStorageServerSession::GetMaxAllocsL()" ); |
|
2544 |
|
2545 iError = KErrNone; |
|
2546 |
|
2547 // Read the process ID at index 0 |
|
2548 TUint processId = aMessage.Int0(); |
|
2549 TUint32 allocNumber( 0 ); |
|
2550 TUint32 allocSize( 0 ); |
|
2551 |
|
2552 // Buffer position |
|
2553 TInt pos( 0 ); |
|
2554 |
|
2555 // The length of the buffer to be constructed for allocation number and size |
|
2556 TInt bufferLength = KWordSize + KWordSize; |
|
2557 |
|
2558 // Get the dynamic process info array |
|
2559 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
2560 iStorageServer.DynProcessInfoArray(); |
|
2561 |
|
2562 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
2563 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
2564 |
|
2565 // Find the index of a CATDynProcessInfo object with the given process ID |
|
2566 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
2567 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
2568 delete dynProcessInfo; |
|
2569 dynProcessInfo = NULL; |
|
2570 |
|
2571 // Return, if a process with the requested process ID was not found |
|
2572 if ( index == KErrNotFound ) |
|
2573 { |
|
2574 return index; |
|
2575 } |
|
2576 |
|
2577 // Otherwise get the wanted dynamic process info |
|
2578 dynProcessInfo = dynProcessArray[index]; |
|
2579 |
|
2580 // Get the desired process's associated session object |
|
2581 CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
2582 |
|
2583 // Get values for the maximum allocations number and size |
|
2584 allocNumber = sessionObject->iMaxAllocs; |
|
2585 allocSize = sessionObject->iMaxAllocSize; |
|
2586 |
|
2587 CBufFlat* allocInfoBuf; |
|
2588 // Construct allocInfoBuf and expand it before the beginning (index 0) |
|
2589 allocInfoBuf = CBufFlat::NewL( bufferLength ); |
|
2590 CleanupStack::PushL( allocInfoBuf ); |
|
2591 allocInfoBuf->ExpandL( 0, bufferLength ); |
|
2592 |
|
2593 // Write the maximum number of allocations of the requested process into the buffer. |
|
2594 allocInfoBuf->Write( pos, &allocNumber, KWordSize ); |
|
2595 |
|
2596 // Move the position one word onwards |
|
2597 pos += KWordSize; |
|
2598 |
|
2599 // Write the maximum total size of the allocations of the requested process into the |
|
2600 // buffer. |
|
2601 allocInfoBuf->Write( pos, &allocSize, KWordSize ); |
|
2602 |
|
2603 // Make a pointer descriptor that points to the data of allocInfoBuf |
|
2604 TPtr8 bufPtr( allocInfoBuf->Ptr(0) ); |
|
2605 |
|
2606 // Write the whole buffer into aMessage at index 1 for the client |
|
2607 aMessage.WriteL( 1, bufPtr ); |
|
2608 |
|
2609 CleanupStack::PopAndDestroy( allocInfoBuf ); |
|
2610 |
|
2611 return iError; |
|
2612 } |
|
2613 |
|
2614 // ----------------------------------------------------------------------------- |
|
2615 // CATStorageServerSession::CancelLoggingL() |
|
2616 // ----------------------------------------------------------------------------- |
|
2617 // |
|
2618 TInt CATStorageServerSession::CancelLoggingL( const RMessage2& aMessage ) |
|
2619 { |
|
2620 LOGSTR1( "STSE TInt CATStorageServerSession::CancelLoggingL()" ); |
|
2621 |
|
2622 iError = KErrNone; |
|
2623 |
|
2624 // Read the process ID at index 0 |
|
2625 TUint processId = aMessage.Int0(); |
|
2626 |
|
2627 // FIND THE REQUESTED PROCESS |
|
2628 |
|
2629 // Get the dynamic process array |
|
2630 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
2631 iStorageServer.DynProcessInfoArray(); |
|
2632 |
|
2633 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
2634 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
2635 |
|
2636 // Find the index of a CATDynProcessInfo object with the given process ID |
|
2637 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
2638 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
2639 delete dynProcessInfo; |
|
2640 dynProcessInfo = NULL; |
|
2641 |
|
2642 // Return, if a process with the requested process ID was not found |
|
2643 if ( index == KErrNotFound ) |
|
2644 { |
|
2645 return index; |
|
2646 } |
|
2647 |
|
2648 // Otherwise get the wanted dynamic process info |
|
2649 dynProcessInfo = dynProcessArray[index]; |
|
2650 |
|
2651 // Get the session object of the requested process |
|
2652 CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
2653 |
|
2654 // Get the current universal time |
|
2655 TInt64 timeFrom1970( GetTime() ); |
|
2656 |
|
2657 // Make a buffer for logging "logging cancelled" |
|
2658 TBuf8<KCancelBufLength> loggingBuf; |
|
2659 |
|
2660 // Copy the "logging cancelled" tag into the buffer with the current time |
|
2661 loggingBuf.AppendFormat( KLoggingCancelled, timeFrom1970 ); |
|
2662 |
|
2663 // Log the buffer eather to a file or to debug channel depending on the current |
|
2664 // logging mode |
|
2665 |
|
2666 if ( sessionObject->iLoggingOngoing && |
|
2667 sessionObject->iLogOption == EATLogToFile ) |
|
2668 { |
|
2669 // Write the buffer into the file |
|
2670 sessionObject->iFile.Write( loggingBuf ); |
|
2671 } |
|
2672 |
|
2673 else if ( sessionObject->iLoggingOngoing && |
|
2674 sessionObject->iLogOption == EATLogToTrace ) |
|
2675 { |
|
2676 // Make a buffer for logging to trace |
|
2677 TBuf<KCancelBufLength> traceBuf; |
|
2678 traceBuf.Copy( loggingBuf ); |
|
2679 |
|
2680 // Write the buffer into the debug channel |
|
2681 RDebug::Print( KTraceMessage, processId ,&traceBuf ); |
|
2682 } |
|
2683 |
|
2684 // Switch off logging of the requested process |
|
2685 sessionObject->iLogOption = EATLoggingOff; |
|
2686 |
|
2687 return KErrNone; |
|
2688 } |
|
2689 |
|
2690 // ----------------------------------------------------------------------------- |
|
2691 // CATStorageServerSession::HandleError |
|
2692 // Internally used for handling error situations. |
|
2693 // ----------------------------------------------------------------------------- |
|
2694 // |
|
2695 void CATStorageServerSession::HandleError( TInt aError ) |
|
2696 { |
|
2697 LOGSTR1( "STSE void CATStorageServerSession::HandleError()" ); |
|
2698 |
|
2699 // Get the current universal time |
|
2700 TInt64 timeFrom1970( GetTime() ); |
|
2701 |
|
2702 // Make a buffer that will be logged into the opened logging file |
|
2703 TBufC8<KErrOccuredBufLength> loggingBuf; |
|
2704 |
|
2705 TPtr8 bufPtr( loggingBuf.Des() ); |
|
2706 |
|
2707 // Write the error code to the buffer |
|
2708 bufPtr.Format( KErrorOccured, aError ); |
|
2709 |
|
2710 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
2711 // format |
|
2712 bufPtr.AppendNum( timeFrom1970, EHex ); |
|
2713 |
|
2714 // Append a new line |
|
2715 bufPtr.Append( KNewLine ); |
|
2716 |
|
2717 // Write the buffer into a file (if possible in the current condition) |
|
2718 iFile.Write( loggingBuf ); |
|
2719 } |
|
2720 |
|
2721 // ----------------------------------------------------------------------------- |
|
2722 // CATStorageServerSession::HandleErrorTrace() |
|
2723 // Internally used for handling error situations. |
|
2724 // ----------------------------------------------------------------------------- |
|
2725 // |
|
2726 void CATStorageServerSession::HandleErrorTrace( TInt aError ) |
|
2727 { |
|
2728 LOGSTR1( "STSE void CATStorageServerSession::HandleErrorTrace()" ); |
|
2729 |
|
2730 // Get the current universal time |
|
2731 TInt64 timeFrom1970( GetTime() ); |
|
2732 |
|
2733 // Make a buffer that will be logged |
|
2734 TBuf<KErrOccuredBufLength> traceBuf; |
|
2735 |
|
2736 // Write the error code to the buffer |
|
2737 traceBuf.Format( KErrorOccuredTrace, aError ); |
|
2738 |
|
2739 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
2740 // format |
|
2741 traceBuf.AppendNum( timeFrom1970, EHex ); |
|
2742 |
|
2743 // Append a new line |
|
2744 traceBuf.Append( KNewLineTrace ); |
|
2745 |
|
2746 RDebug::Print( KTraceMessage, iProcessId , &traceBuf ); |
|
2747 } |
|
2748 |
|
2749 // ----------------------------------------------------------------------------- |
|
2750 // CATStorageServerSession::OpenFsAndFile |
|
2751 // Internally used for opening a handle to the file server and a file |
|
2752 // ----------------------------------------------------------------------------- |
|
2753 // |
|
2754 TInt CATStorageServerSession::OpenFsAndFile( const TDesC& aFileName, |
|
2755 const TDesC8& aProcessName ) |
|
2756 { |
|
2757 LOGSTR1( "STSE TInt CATStorageServerSession::OpenFsAndFile()" ); |
|
2758 |
|
2759 // Connect file server, return if error occured |
|
2760 iError = iFileServer.Connect(); |
|
2761 if ( iError ) |
|
2762 { |
|
2763 iFileServer.Close(); |
|
2764 return iError; |
|
2765 } |
|
2766 |
|
2767 // Open a file |
|
2768 TBuf<KMaxFileName> fileNameBuf; |
|
2769 iError = TATDriveInfo::CreatePath( fileNameBuf, aFileName, iFileServer ); |
|
2770 |
|
2771 // Return, if an error occured, and it |
|
2772 // is not KErrAlreadyExists |
|
2773 if ( iError && iError != KErrAlreadyExists ) |
|
2774 { |
|
2775 iFileServer.Close(); |
|
2776 return iError; |
|
2777 } |
|
2778 |
|
2779 // Save the file name for this session |
|
2780 CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf ); |
|
2781 |
|
2782 // Try to open file |
|
2783 CheckIfFileAlreadyExist( fileNameBuf ); |
|
2784 |
|
2785 // If a data file with the requested name already existed, and was opened |
|
2786 // successfully, check the version of the file. If the line telling the version of |
|
2787 // the file is not the expected, replace the file |
|
2788 // If cannot open the file(error is KErrInUse), generate new filename and |
|
2789 // then try to create new file. |
|
2790 if ( iError == KErrNone ) |
|
2791 { |
|
2792 CheckFileVersion( fileNameBuf ); |
|
2793 } |
|
2794 else if ( iError == KErrInUse ) |
|
2795 { |
|
2796 GenerateNewFileName( fileNameBuf, aProcessName ); |
|
2797 |
|
2798 // Save the file name for this session |
|
2799 CnvUtfConverter::ConvertFromUnicodeToUtf8( iLogFile, fileNameBuf ); |
|
2800 } |
|
2801 LOGSTR2( "STSE > iError(%i)", iError ); |
|
2802 |
|
2803 // If the file does not exist, create it. Write also the version number of |
|
2804 // the file at the beginning of the new file |
|
2805 if ( iError == KErrNotFound ) |
|
2806 { |
|
2807 iError = iFile.Create( iFileServer, fileNameBuf, EFileWrite ); |
|
2808 |
|
2809 if ( !iError ) |
|
2810 { |
|
2811 iError = iFile.Write( KDataFileVersion ); |
|
2812 } |
|
2813 } |
|
2814 |
|
2815 if ( iError ) |
|
2816 { |
|
2817 iFile.Close(); |
|
2818 iFileServer.Close(); |
|
2819 return iError; |
|
2820 } |
|
2821 |
|
2822 // Seek the end of the file and set the current file position there |
|
2823 TInt offset = 0; |
|
2824 iError = iFile.Seek( ESeekEnd, offset ); |
|
2825 |
|
2826 return iError; |
|
2827 } |
|
2828 |
|
2829 // ----------------------------------------------------------------------------- |
|
2830 // CATStorageServerSession::GenerateNewFileName |
|
2831 // Called internally when need generate new file name. |
|
2832 // ----------------------------------------------------------------------------- |
|
2833 // |
|
2834 void CATStorageServerSession::GenerateNewFileName( TDes& aFileName, |
|
2835 const TDesC8& aProcessName ) |
|
2836 { |
|
2837 LOGSTR1( "STSE void CATStorageServerSession::GenerateNewFileName()" ); |
|
2838 |
|
2839 // Extension |
|
2840 TBuf<KExtensionLength> extension; |
|
2841 |
|
2842 // Parse file extension |
|
2843 ParseExtension( aFileName, extension ); |
|
2844 |
|
2845 // Try to find UID3 from current process name |
|
2846 TInt uidErr( KErrBadName ); |
|
2847 TBuf<KMaxFileName> unicodeFile; |
|
2848 |
|
2849 // Converts text encoded using the Unicode transformation format UTF-8 |
|
2850 // into the Unicode UCS-2 character set. |
|
2851 CnvUtfConverter::ConvertToUnicodeFromUtf8( unicodeFile, aProcessName ); |
|
2852 LOGSTR2( "STSE > unicodeFile(%S)", &unicodeFile ); |
|
2853 |
|
2854 // Find square brackets |
|
2855 TInt sPos( unicodeFile.Find( KOpenSquareBracket ) ); |
|
2856 TInt ePos( unicodeFile.Find( KCloseSquareBracket ) ); |
|
2857 LOGSTR3( "STSE > sPos(%i), ePos(%i)", sPos, ePos ); |
|
2858 |
|
2859 if ( sPos != KErrNotFound && ePos != KErrNotFound ) |
|
2860 { |
|
2861 TBuf<KProcessUidLength> processUid; |
|
2862 TInt pEnd( ePos - sPos - KOpenSquareBracket().Length() ); |
|
2863 LOGSTR2( "STSE > pEnd(%i)", pEnd ); |
|
2864 |
|
2865 // Copy UID value |
|
2866 if ( pEnd > 0 ) |
|
2867 { |
|
2868 processUid.Copy( unicodeFile.Mid( |
|
2869 sPos + KOpenSquareBracket().Length(), pEnd ) ); |
|
2870 LOGSTR2( "STSE > processUid(%S)", &processUid ); |
|
2871 } |
|
2872 |
|
2873 if ( aFileName.Find( processUid ) == KErrNotFound ) |
|
2874 { |
|
2875 // UID not exist, create new filename |
|
2876 // Append uid to filename (<file name>_<uid>.<extension>) |
|
2877 aFileName.Append( KUnderLine ); |
|
2878 aFileName.Append( processUid ); |
|
2879 aFileName.Append( extension ); |
|
2880 // Try to open file |
|
2881 CheckIfFileAlreadyExist( aFileName ); |
|
2882 |
|
2883 if ( iError == KErrNone ) |
|
2884 { |
|
2885 uidErr = KErrNone; |
|
2886 CheckFileVersion( aFileName ); |
|
2887 } |
|
2888 } |
|
2889 } |
|
2890 |
|
2891 if ( uidErr == KErrBadName && iError != KErrNotFound ) |
|
2892 { |
|
2893 // Need re-create file name, add end off file _xx (xx=01, 02...) |
|
2894 LOGSTR2( "STSE > Re-create file name, aFileName(%S)", &aFileName ); |
|
2895 |
|
2896 // Parse file extension if exists. |
|
2897 ParseExtension( aFileName, extension ); |
|
2898 |
|
2899 // Temp file name |
|
2900 TBuf<KMaxFileName> tempName; |
|
2901 |
|
2902 for ( TInt i = KNameIndexStart; i < KNameIndexEnd; i++ ) |
|
2903 { |
|
2904 tempName.Delete( 0, tempName.MaxLength() ); |
|
2905 tempName.Format( KFormat, &aFileName, &KUnderLine, i, &extension ); |
|
2906 LOGSTR2( "STSE > tempName(%S)", &tempName ); |
|
2907 // Try to open file |
|
2908 CheckIfFileAlreadyExist( tempName ); |
|
2909 |
|
2910 if ( iError == KErrNone || iError == KErrNotFound ) |
|
2911 { |
|
2912 aFileName.Copy( tempName ); |
|
2913 break; |
|
2914 } |
|
2915 } |
|
2916 } |
|
2917 } |
|
2918 |
|
2919 // ----------------------------------------------------------------------------- |
|
2920 // CATStorageServerSession::ParseExtension |
|
2921 // Method is used to parse file name extension. |
|
2922 // ----------------------------------------------------------------------------- |
|
2923 // |
|
2924 void CATStorageServerSession::ParseExtension( |
|
2925 TDes& aFileName, TDes& aExtension ) |
|
2926 { |
|
2927 LOGSTR2( "STSE void CATStorageServerSession::ParseExtension(%S)", |
|
2928 &aFileName ); |
|
2929 |
|
2930 // Parse current file name |
|
2931 TParse parse; |
|
2932 // Set up the TParse object |
|
2933 parse.Set( aFileName, NULL, NULL ); |
|
2934 |
|
2935 // Tests whether an extension is present. |
|
2936 if ( parse.ExtPresent() ) |
|
2937 { |
|
2938 // Gets the extension |
|
2939 aExtension.Copy( parse.Ext() ); |
|
2940 // Remove extension from file name |
|
2941 TInt pos( aFileName.Find( aExtension ) ); |
|
2942 aFileName.Delete( pos, aFileName.Length() ); |
|
2943 LOGSTR3( "STSE > aFileName(%S), aExtension(%S)", |
|
2944 &aFileName, &aExtension ); |
|
2945 } |
|
2946 } |
|
2947 |
|
2948 // ----------------------------------------------------------------------------- |
|
2949 // CATStorageServerSession::CheckIfFileAlreadyExist |
|
2950 // Method is used to check that file exists and is valid. |
|
2951 // ----------------------------------------------------------------------------- |
|
2952 // |
|
2953 void CATStorageServerSession::CheckIfFileAlreadyExist( |
|
2954 const TDes& aFileName ) |
|
2955 { |
|
2956 LOGSTR2( "STSE void CATStorageServerSession::CheckIfFileAlreadyExist(%S)", |
|
2957 &aFileName ); |
|
2958 |
|
2959 iError = iFile.Open( iFileServer, aFileName, EFileWrite ); |
|
2960 LOGSTR2( "STSE > iError(%i)", iError ); |
|
2961 } |
|
2962 |
|
2963 // ----------------------------------------------------------------------------- |
|
2964 // CATStorageServerSession::CheckFileVersion |
|
2965 // Method is used to check file version. |
|
2966 // ----------------------------------------------------------------------------- |
|
2967 // |
|
2968 void CATStorageServerSession::CheckFileVersion( |
|
2969 const TDes& aFileName ) |
|
2970 { |
|
2971 LOGSTR2( "STSE void CATStorageServerSession::CheckFileVersion(%S)", |
|
2972 &aFileName ); |
|
2973 |
|
2974 TBuf8<KVersionStringLength> versionString; |
|
2975 |
|
2976 // Read version information from the beginning of the file (offset 0) |
|
2977 iFile.Read( 0, versionString, KVersionStringLength ); |
|
2978 |
|
2979 // Delete the existing file, if the version string read from the file does not |
|
2980 // match with KDataFileVersion. |
|
2981 if ( versionString.Compare( KDataFileVersion ) != 0 ) |
|
2982 { |
|
2983 // Close the existing, opened file, and delete it |
|
2984 iFile.Close(); |
|
2985 iError = iFileServer.Delete( aFileName ); |
|
2986 |
|
2987 // If the deletion was successful, set iError = KErrNotFound, so a new |
|
2988 // file will be created in the next few lines |
|
2989 if ( iError == KErrNone ) |
|
2990 { |
|
2991 iError = KErrNotFound; |
|
2992 } |
|
2993 } |
|
2994 } |
|
2995 |
|
2996 // ----------------------------------------------------------------------------- |
|
2997 // CATStorageServerSession::CloseFsAndFile |
|
2998 // Internally used for closing a handle to the file server and a file |
|
2999 // ----------------------------------------------------------------------------- |
|
3000 // |
|
3001 void CATStorageServerSession::CloseFsAndFile() |
|
3002 { |
|
3003 LOGSTR1( "STSE void CATStorageServerSession::CloseFsAndFile()" ); |
|
3004 |
|
3005 // Close the file |
|
3006 iFile.Close(); |
|
3007 |
|
3008 // Close the server session and return the error code |
|
3009 iFileServer.Close(); |
|
3010 } |
|
3011 |
|
3012 // ----------------------------------------------------------------------------- |
|
3013 // CATStorageServerSession::PrintLeaksL() |
|
3014 // Called internally when a process is closed. Prints possible memory leaks |
|
3015 // ----------------------------------------------------------------------------- |
|
3016 // |
|
3017 TInt CATStorageServerSession::PrintLeaksL( const RMessage2& aMessage ) |
|
3018 { |
|
3019 LOGSTR1( "STSE TInt CATStorageServerSession::PrintLeaksL()" ); |
|
3020 |
|
3021 // Panic both the client and the server, if this method is called in a wrong |
|
3022 // state (logging should be ongoing, and the system should be logging into a file, |
|
3023 // not into debug channel) |
|
3024 if ( !iLoggingOngoing || iLogOption != EATLogToFile ) |
|
3025 { |
|
3026 PanicClient( EAToolInternalError, aMessage ); |
|
3027 StorageServerPanic( KCategoryServer, EAToolInternalError ); |
|
3028 } |
|
3029 |
|
3030 LOGMEM; |
|
3031 |
|
3032 // A pointer to a buffer of call stack's memory addresses |
|
3033 CBufFlat* stackBuf = NULL; |
|
3034 |
|
3035 iError = KErrNone; |
|
3036 |
|
3037 TUint32 callStackAddr; |
|
3038 |
|
3039 // Number of leaks |
|
3040 TInt leakCount = iLeakArray.Count(); |
|
3041 |
|
3042 // Variable for the number of memory addresses in the call stack |
|
3043 TInt addrCount( 0 ); |
|
3044 |
|
3045 // Buffer position |
|
3046 TInt pos( 0 ); |
|
3047 |
|
3048 // Go through all the leaks |
|
3049 for ( TInt i = 0; i < leakCount; i++ ) |
|
3050 { |
|
3051 pos = 0; |
|
3052 |
|
3053 // Get the call stack buffer of the the leak i. |
|
3054 stackBuf = const_cast<CBufFlat*>( iLeakArray[i]->iCallstackBuf ); |
|
3055 |
|
3056 // Read the first word of the buffer. This includes the number of |
|
3057 // memory addresses stored in the current stackBuf |
|
3058 stackBuf->Read( pos, &addrCount, KWordSize ); |
|
3059 |
|
3060 // Move the position one word onwards. |
|
3061 pos += KWordSize; |
|
3062 |
|
3063 // Construct a buffer for the string to be written into the logging file |
|
3064 // because of this memory leak. MEM_LEAK: <Memory address> <Time stamp> |
|
3065 // <Allocation size> <Call stack address> <Call stack address> ... |
|
3066 HBufC8* leakString = |
|
3067 HBufC8::NewL( KMemleakLength + |
|
3068 KHexa32Length + |
|
3069 KSpaceLength + KHexa64Length + |
|
3070 KSpaceLength + KHexa32Length + |
|
3071 ( addrCount * (KSpaceLength + KHexa32Length) ) + |
|
3072 KNewlineLength |
|
3073 ); |
|
3074 |
|
3075 // Make a pointer descriptor that points to leakString |
|
3076 TPtr8 leakStringPtr( leakString->Des() ); |
|
3077 |
|
3078 // Append the tag implying a memory leak line in the data file |
|
3079 leakStringPtr.Append( KMemoryLeak ); |
|
3080 |
|
3081 // Append the address of the memory leak |
|
3082 TUint32 memAddress = iLeakArray[i]->iMemAddress; |
|
3083 leakStringPtr.AppendNum( memAddress, EHex ); |
|
3084 |
|
3085 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
3086 // format |
|
3087 leakStringPtr.Append( KSpace ); |
|
3088 TInt64 allocTime = iLeakArray[i]->iAllocTime; |
|
3089 leakStringPtr.AppendNum( allocTime, EHex ); |
|
3090 |
|
3091 // Append the size of the allocation in the 32-bit (max 8 characters) hexadecimal |
|
3092 // text format. |
|
3093 leakStringPtr.Append( KSpace ); |
|
3094 TInt allocSize = iLeakArray[i]->iAllocSize; |
|
3095 leakStringPtr.AppendNum( allocSize, EHex ); |
|
3096 |
|
3097 // Go through all call stack's memory addresses associated with |
|
3098 // the current memory leak |
|
3099 for ( TInt j = 0; j < addrCount; j++ ) |
|
3100 { |
|
3101 // Read the next call stack's memory address stored in the buffer. |
|
3102 stackBuf->Read( pos, &callStackAddr, KWordSize ); |
|
3103 |
|
3104 // Append the read memory address as a hexadecimal number |
|
3105 leakStringPtr.AppendFormat( KHexaNumber, callStackAddr ); |
|
3106 |
|
3107 // Move the pos variable one word onwards. |
|
3108 pos += KWordSize; |
|
3109 } |
|
3110 |
|
3111 leakStringPtr.Append( KNewLine ); |
|
3112 |
|
3113 // Set stackBuf to NULL, because it is not used anymore. |
|
3114 stackBuf = NULL; |
|
3115 |
|
3116 // Write the constructed string into the data file and return if error |
|
3117 iError = iFile.Write( *leakString ); |
|
3118 |
|
3119 delete leakString; |
|
3120 |
|
3121 if ( iError != KErrNone ) |
|
3122 { |
|
3123 return iError; |
|
3124 } |
|
3125 |
|
3126 } // The outer for |
|
3127 |
|
3128 LOGSTR1( "STSE End of CATStorageServerSession::PrintLeaks()" ); |
|
3129 LOGMEM; |
|
3130 |
|
3131 // Empty the leak array and delete the referenced objects |
|
3132 iLeakArray.ResetAndDestroy(); |
|
3133 |
|
3134 return KErrNone; |
|
3135 } |
|
3136 |
|
3137 // ----------------------------------------------------------------------------- |
|
3138 // CATStorageServerSession::SetLogOption() |
|
3139 // For setting the logging mode. |
|
3140 // ----------------------------------------------------------------------------- |
|
3141 // |
|
3142 void CATStorageServerSession::SetLogOption( const RMessage2& aMessage ) |
|
3143 { |
|
3144 LOGSTR1( "STSE void CATStorageServerSession::SetLogOption()" ); |
|
3145 |
|
3146 // Panic both the client and the server, if this method is called in a wrong |
|
3147 // state (logging must not be ongoing when changing the mode of operation). |
|
3148 // So, the mode cannot be changed "on the fly". |
|
3149 if ( iLoggingOngoing ) |
|
3150 { |
|
3151 PanicClient( EAToolInternalError, aMessage ); |
|
3152 StorageServerPanic( KCategoryServer, EAToolInternalError ); |
|
3153 } |
|
3154 |
|
3155 iLogOption = static_cast<TATLogOption>( aMessage.Int3() ); |
|
3156 |
|
3157 // The default is EATLogToFile |
|
3158 if ( iLogOption == EATUseDefault ) |
|
3159 { |
|
3160 iLogOption = KDefaultLoggingMode; |
|
3161 } |
|
3162 } |
|
3163 |
|
3164 // ----------------------------------------------------------------------------- |
|
3165 // CATStorageServerSession::LogThroughTrace() |
|
3166 // ----------------------------------------------------------------------------- |
|
3167 // |
|
3168 TInt CATStorageServerSession::LogThroughTrace( const TDesC& aLogString ) const |
|
3169 { |
|
3170 LOGSTR1( "STSE TInt CATStorageServerSession::LogThroughTrace()" ); |
|
3171 |
|
3172 // Return KErrNotSupported, if a logging session is not currently ongoing, or |
|
3173 // the logging mode is not EATLogToTrace |
|
3174 if ( !iLoggingOngoing || iLogOption != EATLogToTrace) |
|
3175 { |
|
3176 return KErrNotSupported; |
|
3177 } |
|
3178 |
|
3179 RDebug::Print( KTraceMessage, iProcessId, &aLogString ); |
|
3180 |
|
3181 return KErrNone; |
|
3182 } |
|
3183 |
|
3184 // ----------------------------------------------------------------------------- |
|
3185 // CATStorageServerSession::AllocInfoArray |
|
3186 // ----------------------------------------------------------------------------- |
|
3187 // |
|
3188 RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray() |
|
3189 { |
|
3190 LOGSTR1( "STSE RArray<TAllocInfo>& CATStorageServerSession::AllocInfoArray()" ); |
|
3191 |
|
3192 return iAllocInfoArray; |
|
3193 } |
|
3194 |
|
3195 // ----------------------------------------------------------------------------- |
|
3196 // CATStorageServerSession::PanicClient |
|
3197 // Creates a panic in the associated client's code. |
|
3198 // ----------------------------------------------------------------------------- |
|
3199 // |
|
3200 void CATStorageServerSession::PanicClient( TInt aPanic, const RMessage2& aMessage ) |
|
3201 { |
|
3202 LOGSTR1( "STSE void CATStorageServerSession::PanicClient()" ); |
|
3203 |
|
3204 aMessage.Panic( KCategoryClient, aPanic ); |
|
3205 } |
|
3206 |
|
3207 // ----------------------------------------------------------------------------- |
|
3208 // CATStorageServerSession::GetLoggingFileL() |
|
3209 // ----------------------------------------------------------------------------- |
|
3210 // |
|
3211 TInt CATStorageServerSession::GetLoggingFileL( const RMessage2& aMessage ) |
|
3212 { |
|
3213 LOGSTR1( "STSE TInt CATStorageServerSession::GetLoggingFileL()" ); |
|
3214 |
|
3215 iError = KErrNone; |
|
3216 |
|
3217 // Read the process ID at index 0 |
|
3218 TUint processId = aMessage.Int0(); |
|
3219 |
|
3220 // Get the dynamic process info array |
|
3221 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
3222 iStorageServer.DynProcessInfoArray(); |
|
3223 |
|
3224 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
3225 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
3226 |
|
3227 // Find the index of a CATDynProcessInfo object with the given process ID |
|
3228 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
3229 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
3230 delete dynProcessInfo; |
|
3231 dynProcessInfo = NULL; |
|
3232 |
|
3233 // Return, if a process with the requested process ID was not found |
|
3234 if ( index == KErrNotFound ) |
|
3235 { |
|
3236 return index; |
|
3237 } |
|
3238 |
|
3239 // Otherwise get the wanted dynamic process info |
|
3240 dynProcessInfo = dynProcessArray[index]; |
|
3241 |
|
3242 // Get the desired process's associated session object |
|
3243 CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
3244 |
|
3245 // Write the whole buffer into aMessage at index 1 for the client |
|
3246 aMessage.WriteL( 1, sessionObject->iLogFile ); |
|
3247 |
|
3248 return iError; |
|
3249 } |
|
3250 |
|
3251 // ----------------------------------------------------------------------------- |
|
3252 // CATStorageServerSession::GetUdebL() |
|
3253 // ----------------------------------------------------------------------------- |
|
3254 // |
|
3255 TInt CATStorageServerSession::GetUdebL( const RMessage2& aMessage ) |
|
3256 { |
|
3257 LOGSTR1( "STSE TInt CATStorageServerSession::GetUdebL()" ); |
|
3258 |
|
3259 iError = KErrNone; |
|
3260 |
|
3261 // Read the process ID at index 0 |
|
3262 TUint processId = aMessage.Int0(); |
|
3263 |
|
3264 // Get the dynamic process info array |
|
3265 RPointerArray<CATDynProcessInfo> dynProcessArray = |
|
3266 iStorageServer.DynProcessInfoArray(); |
|
3267 |
|
3268 // Construct a CATDynProcessInfo object with the given process ID for searching |
|
3269 CATDynProcessInfo* dynProcessInfo = new (ELeave) CATDynProcessInfo( processId ); |
|
3270 |
|
3271 // Find the index of a CATDynProcessInfo object with the given process ID |
|
3272 TLinearOrder<CATDynProcessInfo> order( CATDynProcessInfo::Compare ); |
|
3273 TInt index = dynProcessArray.FindInOrder( dynProcessInfo, order ); |
|
3274 delete dynProcessInfo; |
|
3275 dynProcessInfo = NULL; |
|
3276 |
|
3277 // Return, if a process with the requested process ID was not found |
|
3278 if ( index == KErrNotFound ) |
|
3279 { |
|
3280 return index; |
|
3281 } |
|
3282 |
|
3283 // Otherwise get the wanted dynamic process info |
|
3284 dynProcessInfo = dynProcessArray[index]; |
|
3285 |
|
3286 // Get the desired process's associated session object |
|
3287 CATStorageServerSession* sessionObject = dynProcessInfo->iSessionObject; |
|
3288 |
|
3289 TBuf8<KMaxVersionName> isUdeb; |
|
3290 if ( sessionObject->iIsUdeb == 1 ) |
|
3291 { |
|
3292 isUdeb.Copy( KUdeb() ); |
|
3293 } |
|
3294 else if ( sessionObject->iIsUdeb == 0 ) |
|
3295 { |
|
3296 isUdeb.Copy( KUrel() ); |
|
3297 } |
|
3298 else |
|
3299 { |
|
3300 return KErrNotFound; |
|
3301 } |
|
3302 // Write the whole buffer into aMessage at index 1 for the client |
|
3303 aMessage.WriteL( 1, isUdeb ); |
|
3304 |
|
3305 return iError; |
|
3306 } |
|
3307 |
|
3308 // ----------------------------------------------------------------------------- |
|
3309 // CATStorageServerSession::SetUdeb() |
|
3310 // ----------------------------------------------------------------------------- |
|
3311 // |
|
3312 void CATStorageServerSession::SetUdeb( const RMessage2& aMessage ) |
|
3313 { |
|
3314 LOGSTR1( "STSE void CATStorageServerSession::SetUdeb()" ); |
|
3315 |
|
3316 iIsUdeb = aMessage.Int0(); |
|
3317 } |
|
3318 |
|
3319 // ----------------------------------------------------------------------------- |
|
3320 // CATStorageServerSession::LogAbnormalEnd() |
|
3321 // ----------------------------------------------------------------------------- |
|
3322 // |
|
3323 void CATStorageServerSession::LogAbnormalEnd() |
|
3324 { |
|
3325 LOGSTR1( "STSE void CATStorageServerSession::LogAbnormalEnd()" ); |
|
3326 |
|
3327 // Get the current universal time |
|
3328 TInt64 timeFrom1970( GetTime() ); |
|
3329 |
|
3330 switch ( iLogOption ) |
|
3331 { |
|
3332 case EATLogToTrace: |
|
3333 { |
|
3334 // Make a buffer that will be logged |
|
3335 TBuf<KEndAbnormalBufLength> traceBuf; |
|
3336 |
|
3337 // Write the process id to the buffer |
|
3338 traceBuf.Format( KProcessEndAbnormalTrace, iProcessId ); |
|
3339 |
|
3340 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
3341 // format |
|
3342 traceBuf.AppendNum( timeFrom1970, EHex ); |
|
3343 |
|
3344 // Append a new line |
|
3345 traceBuf.Append( KNewLineTrace ); |
|
3346 |
|
3347 // Write the buffer into the debug channel |
|
3348 RDebug::Print( KTraceMessage, iProcessId, &traceBuf ); |
|
3349 } |
|
3350 break; |
|
3351 |
|
3352 case EATLogToFile: |
|
3353 { |
|
3354 // Make a buffer that will be logged |
|
3355 TBuf8<KEndAbnormalBufLength> loggingBuf; |
|
3356 |
|
3357 // Write the process id to the buffer |
|
3358 loggingBuf.Format( KProcessEndAbnormal, iProcessId ); |
|
3359 |
|
3360 // Append the current time in the 64-bit (max 16 characters) hexadecimal text |
|
3361 // format |
|
3362 loggingBuf.AppendNum( timeFrom1970, EHex ); |
|
3363 |
|
3364 // Append a new line |
|
3365 loggingBuf.Append( KNewLine ); |
|
3366 |
|
3367 // Write the buffer into a file (if possible in the current condition) |
|
3368 iFile.Write( loggingBuf ); |
|
3369 } |
|
3370 break; |
|
3371 |
|
3372 default: |
|
3373 break; |
|
3374 } |
|
3375 } |
|
3376 |
|
3377 // ----------------------------------------------------------------------------- |
|
3378 // CATStorageServerSession::GetTime() |
|
3379 // Get the current universal time |
|
3380 // ----------------------------------------------------------------------------- |
|
3381 // |
|
3382 TInt64 CATStorageServerSession::GetTime() |
|
3383 { |
|
3384 LOGSTR1( "STSE void CATStorageServerSession::GetTime()" ); |
|
3385 |
|
3386 // Get the current universal time |
|
3387 iTime.UniversalTime(); |
|
3388 |
|
3389 // Change the time format that tells the number of microseconds from January First, |
|
3390 // 0 AD nominal Gregorian, into a format that tells the number of microseconds from |
|
3391 // January First, 1970 AD nominal Gregorian. This is a more generic format and |
|
3392 // can be directly exploited by the PC code parsing the data file that this |
|
3393 // server generates. |
|
3394 return ( iTime.Int64() - iMicroSecondsAt1970 ); |
|
3395 } |
|
3396 |
|
3397 // End of File |
|