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 for the class CATParseTraceFile. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "../inc/ATCommonDefines.h" |
|
20 #include "../inc/CATParseTraceFile.h" |
|
21 #include "../inc/catdatasaver.h" |
|
22 #include "../inc/CATDatParser.h" |
|
23 |
|
24 #include <time.h> |
|
25 |
|
26 #define MAIN_ID "PCSS" |
|
27 #define ALLOC_ID "ALLOC" // < V.1.6 allocation. |
|
28 #define ALLOCH_ID "ALLOCH" // Header of multi message allocation. |
|
29 #define ALLOCF_ID "ALLOCF" // Fragment of multi message allocation. |
|
30 #define FREE_ID "FREE" |
|
31 #define FREEH_ID "FREEH" // Header of multi message free. |
|
32 #define FREEF_ID "FREEF" // Fragment of multi message free. |
|
33 #define HANDLE_LEAK_ID "HANDLE_LEAK" |
|
34 |
|
35 const string ERROR_OCCURED = "ERROR_OCCURED"; // Error messages. |
|
36 const string INCORRECT_ATOOL_VERSION = "INCORRECT_ATOOL_VERSION"; |
|
37 /** |
|
38 * Invalid characters in trace file line content. |
|
39 * These will be filtered out before actuall parsing of line. |
|
40 10 = LF |
|
41 13 = CR |
|
42 124 = | |
|
43 */ |
|
44 const char cINVALID_TRACE_FILE_CHARS[] = { 10, 13, 124 }; |
|
45 |
|
46 // ----------------------------------------------------------------------------- |
|
47 // CATParseTraceFile::CATParseTraceFile |
|
48 // Constructor. |
|
49 // ----------------------------------------------------------------------------- |
|
50 CATParseTraceFile::CATParseTraceFile() |
|
51 { |
|
52 LOG_FUNC_ENTRY("CATParseTraceFile::CATParseTraceFile"); |
|
53 m_DataSaver.SetPrintFlag( false ); |
|
54 } |
|
55 |
|
56 // ----------------------------------------------------------------------------- |
|
57 // CATParseTraceFile::StartParse |
|
58 // Main function to start trace parsing. |
|
59 // ----------------------------------------------------------------------------- |
|
60 bool CATParseTraceFile::StartParse( const char* pFileName, const char* pOutputFileName ) |
|
61 { |
|
62 LOG_FUNC_ENTRY("CATParseTraceFile::StartParse"); |
|
63 |
|
64 // Return value, will be changed to true if process start found. |
|
65 bool bRet = false; |
|
66 |
|
67 // Check pointers |
|
68 if ( pFileName == NULL ) |
|
69 return bRet; |
|
70 |
|
71 if( pOutputFileName == NULL ) |
|
72 return bRet; |
|
73 |
|
74 if ( ! FileExists( pFileName ) ) |
|
75 { |
|
76 cout << AT_MSG << "Error, input file \"" |
|
77 << pFileName |
|
78 << "\" does not exist." << endl; |
|
79 return bRet; |
|
80 } |
|
81 |
|
82 // Open data file |
|
83 ifstream in( pFileName ); |
|
84 |
|
85 // Check file opened ok |
|
86 if ( !in.good() ) |
|
87 return false; |
|
88 |
|
89 // Get stream size |
|
90 size_t streamPos = in.tellg(); |
|
91 in.seekg( 0, ios::end); |
|
92 size_t streamEnd = in.tellg(); |
|
93 in.seekg( 0, ios::beg); |
|
94 |
|
95 //Origianl characters (not filtered). |
|
96 char cOriginalLineFromFile[MAX_LINE_LENGTH]; |
|
97 |
|
98 vector<CProcessData> vProcessList; |
|
99 int iProcessIDinList = -1; |
|
100 |
|
101 bool bFileVersionSaved = false; |
|
102 // Read lines |
|
103 while( streamPos < streamEnd ) |
|
104 { |
|
105 // Get one line. Don't use stream flags to determinate end of file |
|
106 // it can be found too early because trace can contain "anything". |
|
107 in.getline( cOriginalLineFromFile, MAX_LINE_LENGTH ); |
|
108 |
|
109 // Refresh position |
|
110 streamPos = in.tellg(); |
|
111 |
|
112 // Check has bad bit flag raised. (i.e. device problems reading data) |
|
113 if( in.bad() ) |
|
114 { |
|
115 cout << AT_MSG << "Integrity error reading the trace file, reading aborted." << endl; |
|
116 return false; |
|
117 } |
|
118 //Filtered characters. |
|
119 char cLineFromFile[MAX_LINE_LENGTH]; |
|
120 char* pFiltered = cLineFromFile; |
|
121 |
|
122 //Loop thru all characters in original line. |
|
123 for( size_t i = 0 ; cOriginalLineFromFile[i] != 0 ; i++ ) |
|
124 { |
|
125 //If character in line is not in invalid character array append it |
|
126 //to filtered line. |
|
127 if ( strchr( cINVALID_TRACE_FILE_CHARS, cOriginalLineFromFile[i] ) == 0 ) |
|
128 *pFiltered++ = cOriginalLineFromFile[i]; |
|
129 } |
|
130 *pFiltered++ = 0; //Add null termination to filtered line. |
|
131 |
|
132 if( !bFileVersionSaved && *cLineFromFile != 0 ) |
|
133 { |
|
134 bFileVersionSaved = true; |
|
135 m_DataSaver.AddString( AT_DATA_FILE_VERSION ); |
|
136 m_DataSaver.AddLineToLast(); |
|
137 } |
|
138 |
|
139 // Is there main ID? |
|
140 if( strstr( cLineFromFile, MAIN_ID ) != NULL ) |
|
141 { |
|
142 string sRestOfLine( cLineFromFile ); |
|
143 string sTemp; |
|
144 |
|
145 // Delete all characters before main ID |
|
146 sRestOfLine.erase( 0, sRestOfLine.find( MAIN_ID ) ); |
|
147 |
|
148 // Get main ID |
|
149 sTemp = GetStringUntilNextSpace( sRestOfLine ); |
|
150 |
|
151 // Is there more data in line? |
|
152 if( sRestOfLine.empty() ) |
|
153 { |
|
154 continue; |
|
155 } |
|
156 |
|
157 // Get next argument |
|
158 sTemp = GetStringUntilNextSpace( sRestOfLine ); |
|
159 // This might be process id or error message |
|
160 if ( sTemp.compare( ERROR_OCCURED ) == 0 ) |
|
161 { |
|
162 // Api mismatch between s60 side and atool.exe |
|
163 if ( sRestOfLine.find( INCORRECT_ATOOL_VERSION ) != string::npos ) |
|
164 { |
|
165 cout << "Test run failed because version conflict between device binaries\nand the atool.exe version used to build the application." << endl; |
|
166 size_t pS = sRestOfLine.find_first_of('['); |
|
167 size_t pE = sRestOfLine.find_first_of(']'); |
|
168 size_t pSL = sRestOfLine.find_last_of('['); |
|
169 size_t pEL = sRestOfLine.find_last_of(']'); |
|
170 if ( pS != string::npos && pE != string::npos && pSL != string::npos && pEL != string::npos ) |
|
171 { |
|
172 string deviceVer = sRestOfLine.substr( pS+1, pE-pS-1 ); |
|
173 string atoolVer = sRestOfLine.substr( pSL+1, pEL-pSL-1 ); |
|
174 cout << "\tdevice: " << deviceVer << endl |
|
175 << "\tatool.exe: " << atoolVer << endl; |
|
176 } |
|
177 } |
|
178 else |
|
179 cout << sRestOfLine << endl; |
|
180 continue; |
|
181 } |
|
182 unsigned long iProcessID = _httoi( sTemp.c_str() ); |
|
183 |
|
184 iProcessIDinList = -1; |
|
185 // Find process from list |
|
186 for( unsigned int i = 0 ; i < vProcessList.size() ; i++ ) |
|
187 { |
|
188 if( vProcessList[i].iProcessID == iProcessID ) |
|
189 { |
|
190 iProcessIDinList = i; |
|
191 break; |
|
192 } |
|
193 } |
|
194 // Is Process ID found from list? |
|
195 if( iProcessIDinList == -1 ) |
|
196 { |
|
197 CProcessData ProcessData; |
|
198 ProcessData.bProcessOnGoing = false; |
|
199 ProcessData.iProcessID = iProcessID; |
|
200 vProcessList.push_back( ProcessData ); |
|
201 iProcessIDinList = (int)vProcessList.size() - 1; |
|
202 } |
|
203 |
|
204 // Remove spaces from end of line |
|
205 while( sRestOfLine[sRestOfLine.size()-1] == ' ' ) |
|
206 { |
|
207 sRestOfLine.resize( sRestOfLine.size()-1 ); |
|
208 } |
|
209 |
|
210 string sWholeTempLine( sRestOfLine ); |
|
211 |
|
212 // Get command |
|
213 sTemp = GetStringUntilNextSpace( sRestOfLine ); |
|
214 |
|
215 // Use c style string for easy comparisong of command. |
|
216 const char* pCommand = sTemp.c_str(); |
|
217 |
|
218 // Process start. |
|
219 if( ! _stricmp( pCommand, LABEL_PROCESS_START ) ) |
|
220 { |
|
221 bRet = true; // Set return value true we found start. |
|
222 vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine ); |
|
223 vProcessList[iProcessIDinList].bProcessOnGoing = true; |
|
224 continue; |
|
225 } |
|
226 |
|
227 // Check is process ongoing if not skip other tags. |
|
228 if( vProcessList[iProcessIDinList].bProcessOnGoing == false ) |
|
229 continue; |
|
230 |
|
231 // "Old style" allocation (< v.1.6) |
|
232 if( ! _stricmp( pCommand, ALLOC_ID ) ) |
|
233 { |
|
234 // Add alloc |
|
235 vProcessList[iProcessIDinList].Alloc( sRestOfLine ); |
|
236 |
|
237 // Subtests running? |
|
238 vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
239 while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() ) |
|
240 { |
|
241 if( viSubTestIter->bRunning ) |
|
242 { |
|
243 // Save alloc also to sub test |
|
244 viSubTestIter->Alloc( sRestOfLine ); |
|
245 } |
|
246 viSubTestIter++; |
|
247 } |
|
248 } |
|
249 else if ( ! _stricmp( pCommand, ALLOCH_ID ) ) |
|
250 { |
|
251 // Add alloc |
|
252 vProcessList[iProcessIDinList].AllocH( sRestOfLine ); |
|
253 |
|
254 // Subtests running? |
|
255 vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
256 while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() ) |
|
257 { |
|
258 if( viSubTestIter->bRunning ) |
|
259 { |
|
260 // Save alloc also to sub test |
|
261 viSubTestIter->AllocH( sRestOfLine ); |
|
262 } |
|
263 viSubTestIter++; |
|
264 } |
|
265 } |
|
266 // Allocation fragment (call stack). |
|
267 else if ( ! _stricmp( pCommand, ALLOCF_ID ) ) |
|
268 { |
|
269 // Add alloc fragment |
|
270 vProcessList[iProcessIDinList].AllocF( sRestOfLine ); |
|
271 |
|
272 // Subtests running? |
|
273 vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
274 while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() ) |
|
275 { |
|
276 if( viSubTestIter->bRunning ) |
|
277 { |
|
278 // Save alloc fragment also to sub test |
|
279 viSubTestIter->AllocF( sRestOfLine ); |
|
280 } |
|
281 viSubTestIter++; |
|
282 } |
|
283 } |
|
284 // Command free |
|
285 else if( ! _stricmp( pCommand, FREE_ID ) ) |
|
286 { |
|
287 // Send free |
|
288 vProcessList[iProcessIDinList].Free( sRestOfLine ); |
|
289 |
|
290 // Subtests running? |
|
291 vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
292 while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() ) |
|
293 { |
|
294 if( viSubTestIter->bRunning ) |
|
295 { |
|
296 // Send free to subtest |
|
297 viSubTestIter->Free( sRestOfLine ); |
|
298 } |
|
299 viSubTestIter++; |
|
300 } |
|
301 } |
|
302 // Header free. |
|
303 else if( ! _stricmp( pCommand, FREEH_ID ) ) |
|
304 { |
|
305 // Send free |
|
306 vProcessList[iProcessIDinList].FreeH( sRestOfLine ); |
|
307 |
|
308 // Subtests running? |
|
309 vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
310 while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() ) |
|
311 { |
|
312 if( viSubTestIter->bRunning ) |
|
313 { |
|
314 // Send free to subtest |
|
315 viSubTestIter->FreeH( sRestOfLine ); |
|
316 } |
|
317 viSubTestIter++; |
|
318 } |
|
319 |
|
320 } |
|
321 else if( ! _stricmp( pCommand, FREEF_ID ) ) |
|
322 { |
|
323 // Not used currently. |
|
324 } |
|
325 // Command process end |
|
326 else if( ! _stricmp( pCommand, LABEL_PROCESS_END ) ) |
|
327 { |
|
328 // Set process has ended. |
|
329 vProcessList[iProcessIDinList].bProcessOnGoing = false; |
|
330 |
|
331 // Save leaks |
|
332 vector<string> vLeaks; |
|
333 vector<string>::iterator viLeaks; |
|
334 vProcessList[iProcessIDinList].GetLeakList( vLeaks ); |
|
335 for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ ) |
|
336 { |
|
337 sTemp.clear(); |
|
338 sTemp.append( LABEL_MEM_LEAK ); |
|
339 sTemp.append( " " ); |
|
340 sTemp.append( *viLeaks ); |
|
341 vProcessList[iProcessIDinList].vData.push_back( sTemp ); |
|
342 } |
|
343 vProcessList[iProcessIDinList].ClearAllocs(); |
|
344 |
|
345 vector<string>::iterator viHandleIter = vProcessList[iProcessIDinList].vHandleLeaks.begin(); |
|
346 // Print handle leaks |
|
347 while( viHandleIter != vProcessList[iProcessIDinList].vHandleLeaks.end() ) |
|
348 { |
|
349 sTemp.clear(); |
|
350 sTemp.append( viHandleIter->c_str() ); |
|
351 vProcessList[iProcessIDinList].vData.push_back( sTemp ); |
|
352 viHandleIter++; |
|
353 } |
|
354 // Clear handle leaks from list |
|
355 vProcessList[iProcessIDinList].vHandleLeaks.clear(); |
|
356 |
|
357 vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
358 // Print sub test leaks |
|
359 while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() ) |
|
360 { |
|
361 // Print sub test start |
|
362 string sLine( LABEL_TEST_START ); sLine.append( " " ); |
|
363 sLine.append( viSubTestIter->sStartTime ); sLine.append( " " ); |
|
364 sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " ); |
|
365 sLine.append( viSubTestIter->sSubTestStartHandleCount ); |
|
366 vProcessList[iProcessIDinList].vData.push_back( sLine ); |
|
367 sLine.clear(); |
|
368 |
|
369 // DLL Loads. |
|
370 for( vector<string>::iterator it = viSubTestIter->vData.begin(); |
|
371 it != viSubTestIter->vData.end(); it++ ) |
|
372 { |
|
373 vProcessList[iProcessIDinList].vData.push_back( (*it) ); |
|
374 } |
|
375 |
|
376 // Subtest leaks. |
|
377 vector<string> vSubLeaks; |
|
378 vector<string>::iterator viSubLeaks; |
|
379 viSubTestIter->GetLeakList( vSubLeaks ); |
|
380 for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ ) |
|
381 { |
|
382 sLine.append( LABEL_MEM_LEAK ); |
|
383 sLine.append( " " ); |
|
384 sLine.append( *viSubLeaks ); |
|
385 vProcessList[iProcessIDinList].vData.push_back( sLine ); |
|
386 sLine.clear(); |
|
387 } |
|
388 viSubTestIter->ClearAllocs(); |
|
389 |
|
390 if( !viSubTestIter->sEndTime.empty() ) |
|
391 { |
|
392 // Print sub test end |
|
393 sLine.append( LABEL_TEST_END ); sLine.append( " " ); |
|
394 sLine.append( viSubTestIter->sEndTime ); sLine.append( " " ); |
|
395 sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " ); |
|
396 sLine.append( viSubTestIter->sSubTestEndHandleCount ); |
|
397 vProcessList[iProcessIDinList].vData.push_back( sLine ); |
|
398 } |
|
399 viSubTestIter++; |
|
400 } |
|
401 |
|
402 // Clear sub tests from list |
|
403 vProcessList[iProcessIDinList].vSubTests.clear(); |
|
404 vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine ); |
|
405 } |
|
406 else if( ! _stricmp( pCommand, LABEL_HANDLE_LEAK ) ) |
|
407 { |
|
408 // Make whole line |
|
409 sTemp.append( " " ); |
|
410 sTemp.append( sRestOfLine ); |
|
411 vProcessList[iProcessIDinList].vHandleLeaks.push_back( sTemp ); |
|
412 } |
|
413 else if( ! _stricmp( pCommand, LABEL_DLL_LOAD ) ) |
|
414 { |
|
415 // Add module load to process data. |
|
416 vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine ); |
|
417 // Add module load to subtest data if test running. |
|
418 for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
419 it != vProcessList[iProcessIDinList].vSubTests.end(); it++ ) |
|
420 { |
|
421 if( it->bRunning ) |
|
422 it->vData.push_back( sWholeTempLine ); |
|
423 } |
|
424 |
|
425 } |
|
426 else if( ! _stricmp( pCommand, LABEL_DLL_UNLOAD ) ) |
|
427 { |
|
428 // Add module load to process data. |
|
429 vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine ); |
|
430 // Add module unload to subtest data if test running. |
|
431 for( vector<CSubTestData>::iterator it = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
432 it != vProcessList[iProcessIDinList].vSubTests.end(); it++ ) |
|
433 { |
|
434 if( it->bRunning ) |
|
435 it->vData.push_back( sWholeTempLine ); |
|
436 } |
|
437 } |
|
438 else if( sTemp.find( LABEL_LOGGING_CANCELLED ) != string::npos || |
|
439 sTemp.find( LABEL_PROCESS_END ) != string::npos || sTemp.find( LABEL_ERROR_OCCURED ) != string::npos || |
|
440 sTemp.find( LABEL_HANDLE_LEAK ) != string::npos ) |
|
441 { |
|
442 vProcessList[iProcessIDinList].vData.push_back( sWholeTempLine ); |
|
443 } |
|
444 else if( ! _stricmp( pCommand, LABEL_TEST_START ) ) |
|
445 { |
|
446 bRet = true; // Set return value true we found start. |
|
447 // Get sub test time |
|
448 string sSubTestTime = GetStringUntilNextSpace( sRestOfLine ); |
|
449 // Get sub test name |
|
450 string sSubTestName = GetStringUntilNextSpace( sRestOfLine ); |
|
451 // Get sub test start handle count |
|
452 string sSubTestStartHandleCount = GetStringUntilNextSpace( sRestOfLine ); |
|
453 |
|
454 CSubTestData SubTestData; |
|
455 SubTestData.bRunning = true; |
|
456 SubTestData.sStartTime = sSubTestTime; |
|
457 SubTestData.sSubTestName = sSubTestName; |
|
458 SubTestData.sSubTestStartHandleCount = sSubTestStartHandleCount.c_str(); |
|
459 |
|
460 vProcessList[iProcessIDinList].vSubTests.push_back( SubTestData ); |
|
461 } |
|
462 else if( ! _stricmp( pCommand, LABEL_TEST_END ) ) |
|
463 { |
|
464 // Get sub test time |
|
465 string sSubTestEnd = GetStringUntilNextSpace( sRestOfLine ); |
|
466 // Get sub test name |
|
467 string sSubTestName = GetStringUntilNextSpace( sRestOfLine ); |
|
468 // Get sub test end handle count |
|
469 string sSubTestEndHandleCount = GetStringUntilNextSpace( sRestOfLine ); |
|
470 |
|
471 // Find subtest |
|
472 vector<CSubTestData>::iterator viSubTestIter = vProcessList[iProcessIDinList].vSubTests.begin(); |
|
473 while( viSubTestIter != vProcessList[iProcessIDinList].vSubTests.end() ) |
|
474 { |
|
475 if( viSubTestIter->sSubTestName == sSubTestName && viSubTestIter->sEndTime.empty() ) |
|
476 { |
|
477 viSubTestIter->sEndTime = sSubTestEnd; |
|
478 viSubTestIter->bRunning = false; |
|
479 viSubTestIter->sSubTestEndHandleCount = sSubTestEndHandleCount.c_str(); |
|
480 } |
|
481 viSubTestIter++; |
|
482 } |
|
483 } |
|
484 } |
|
485 } |
|
486 |
|
487 // Print all saved data from processes |
|
488 for( unsigned int i = 0 ; i < vProcessList.size() ; i++ ) |
|
489 { |
|
490 // Print saved lines |
|
491 for( unsigned int iDataCounter = 0 ; iDataCounter < vProcessList[i].vData.size() ; iDataCounter++ ) |
|
492 { |
|
493 m_DataSaver.AddString( vProcessList[i].vData[iDataCounter].c_str() ); |
|
494 m_DataSaver.AddLineToLast(); |
|
495 } |
|
496 |
|
497 string sTemp; |
|
498 |
|
499 // Save leaks |
|
500 vector<string> vLeaks; |
|
501 vector<string>::iterator viLeaks; |
|
502 vProcessList[i].GetLeakList( vLeaks ); |
|
503 for ( viLeaks = vLeaks.begin(); viLeaks != vLeaks.end(); viLeaks++ ) |
|
504 { |
|
505 sTemp.clear(); |
|
506 sTemp.append( LABEL_MEM_LEAK ); |
|
507 sTemp.append( " " ); |
|
508 sTemp.append( *viLeaks ); |
|
509 m_DataSaver.AddString( sTemp.c_str() ); |
|
510 m_DataSaver.AddLineToLast(); |
|
511 } |
|
512 |
|
513 vector<string>::iterator viHandleIter = vProcessList[i].vHandleLeaks.begin(); |
|
514 // Print handle leaks, if there is data left, there was no process end. |
|
515 while( viHandleIter != vProcessList[i].vHandleLeaks.end() ) |
|
516 { |
|
517 sTemp.clear(); |
|
518 sTemp.append( viHandleIter->c_str() ); |
|
519 m_DataSaver.AddString( sTemp.c_str() ); |
|
520 m_DataSaver.AddLineToLast(); |
|
521 viHandleIter++; |
|
522 } |
|
523 vector<CSubTestData>::iterator viSubTestIter = vProcessList[i].vSubTests.begin(); |
|
524 // Print sub test data, if there is data left, there was no process end. |
|
525 while( viSubTestIter != vProcessList[i].vSubTests.end() ) |
|
526 { |
|
527 // Print sub test start |
|
528 string sLine( LABEL_TEST_START ); sLine.append( " " ); |
|
529 sLine.append( viSubTestIter->sStartTime ); sLine.append( " " ); |
|
530 sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " ); |
|
531 sLine.append( viSubTestIter->sSubTestStartHandleCount ); |
|
532 m_DataSaver.AddString( sLine.c_str() ); |
|
533 m_DataSaver.AddLineToLast(); |
|
534 sLine.clear(); |
|
535 |
|
536 // DLL Loads. |
|
537 for( vector<string>::iterator it = viSubTestIter->vData.begin(); |
|
538 it != viSubTestIter->vData.end(); it++ ) |
|
539 { |
|
540 m_DataSaver.AddString( (*it).c_str() ); |
|
541 m_DataSaver.AddLineToLast(); |
|
542 } |
|
543 |
|
544 // Subtest leaks. |
|
545 vector<string> vSubLeaks; |
|
546 vector<string>::iterator viSubLeaks; |
|
547 viSubTestIter->GetLeakList( vSubLeaks ); |
|
548 for ( viSubLeaks = vSubLeaks.begin(); viSubLeaks != vSubLeaks.end(); viSubLeaks++ ) |
|
549 { |
|
550 sLine.append( LABEL_MEM_LEAK ); |
|
551 sLine.append( " " ); |
|
552 sLine.append( *viSubLeaks ); |
|
553 m_DataSaver.AddString( sLine.c_str() ); |
|
554 m_DataSaver.AddLineToLast(); |
|
555 sLine.clear(); |
|
556 } |
|
557 |
|
558 // Print sub test end |
|
559 sLine.append( LABEL_TEST_END ); sLine.append( " " ); |
|
560 sLine.append( viSubTestIter->sEndTime ); sLine.append( " " ); |
|
561 sLine.append( viSubTestIter->sSubTestName ); sLine.append( " " ); |
|
562 sLine.append( viSubTestIter->sSubTestEndHandleCount ); |
|
563 m_DataSaver.AddString( sLine.c_str() ); |
|
564 m_DataSaver.AddLineToLast(); |
|
565 |
|
566 viSubTestIter++; |
|
567 } |
|
568 } |
|
569 // Save lines to file. |
|
570 m_DataSaver.SaveLinesToFile( pOutputFileName, TEXT_DATA ); |
|
571 // Close file. |
|
572 in.close(); |
|
573 return bRet; |
|
574 } |
|
575 |
|
576 // ----------------------------------------------------------------------------- |
|
577 // CATParseTraceFile::GetDataSaver |
|
578 // Gets data saver object. |
|
579 // ----------------------------------------------------------------------------- |
|
580 CATDataSaver* CATParseTraceFile::GetDataSaver(void) |
|
581 { |
|
582 LOG_LOW_FUNC_ENTRY("CATParseTraceFile::GetDataSaver"); |
|
583 return &m_DataSaver; |
|
584 } |
|
585 //EOF |
|