|
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: Class responsible to parse data files |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "../inc/CATDatParser.h" |
|
20 #include "../inc/CATProject.h" |
|
21 #include "../inc/CATModule2.h" |
|
22 #include "../inc/CATMemoryAddress.h" |
|
23 #include "../inc/catromsymbol.h" |
|
24 |
|
25 // ----------------------------------------------------------------------------- |
|
26 // CATDatParser::CATDatParser |
|
27 // Constructor only for testing! |
|
28 // (No module vector defined so no locating codelines / call stacks) |
|
29 // ----------------------------------------------------------------------------- |
|
30 CATDatParser::CATDatParser() |
|
31 { |
|
32 LOG_FUNC_ENTRY("CATDatParser::CATDatParser"); |
|
33 Construct(); |
|
34 } |
|
35 |
|
36 // ----------------------------------------------------------------------------- |
|
37 // CATDatParser::CATDatParser |
|
38 // Constructor |
|
39 // ----------------------------------------------------------------------------- |
|
40 CATDatParser::CATDatParser(vector<CATModule2*>* pModules ) |
|
41 { |
|
42 LOG_FUNC_ENTRY("CATDatParser::CATDatParser"); |
|
43 Construct(); |
|
44 m_pModules = pModules; |
|
45 } |
|
46 |
|
47 // ----------------------------------------------------------------------------- |
|
48 // CATDatParser::Construct |
|
49 // "Real" constructor |
|
50 // ----------------------------------------------------------------------------- |
|
51 void CATDatParser::Construct() |
|
52 { |
|
53 LOG_FUNC_ENTRY("CATDatParser::Construct"); |
|
54 |
|
55 m_iDataVersion = 1; // Default version of data. |
|
56 m_bDllLoadFound = false; |
|
57 m_bProcessStartFound = false; |
|
58 m_bSubtestOnGoing = false; |
|
59 |
|
60 m_DataSaver.InitXML(); |
|
61 |
|
62 m_eBuildType = -2; |
|
63 m_eProcess_state = not_started; |
|
64 m_eProjectBuildType = -1; |
|
65 |
|
66 m_iCurrentProcessId = 0; |
|
67 m_iLeakNumber = 0; |
|
68 m_iLogLevel = 3; |
|
69 m_iOffSet = 0; |
|
70 |
|
71 m_iPinPointedLeaks = 0; |
|
72 m_iPinPointedSubTestLeaks = 0; |
|
73 m_iSubtestStartHandleCount = 0; |
|
74 m_iSuccesfullRuns = 0; |
|
75 m_iTotalNumberOfLeaks = 0; |
|
76 m_iTotalRuns = 0; |
|
77 |
|
78 m_pRomSymbol = 0; |
|
79 m_pModules = 0; |
|
80 |
|
81 m_sCurrentProcessName = ""; |
|
82 m_sInputFile = ""; |
|
83 m_sInputFileTemp = ""; |
|
84 m_sOutputFile = ""; |
|
85 m_sProjectPlatform = ""; |
|
86 m_vRomSymbolFiles.clear(); |
|
87 m_vDllLoadModList.clear(); |
|
88 m_vDllLoadModListSubTest.clear(); |
|
89 m_vHandleLeaks.clear(); |
|
90 m_vMemoryAddress.clear(); |
|
91 } |
|
92 |
|
93 // ----------------------------------------------------------------------------- |
|
94 // CATDatParser::~CATDatParser |
|
95 // Destructor |
|
96 // ----------------------------------------------------------------------------- |
|
97 CATDatParser::~CATDatParser() |
|
98 { |
|
99 LOG_FUNC_ENTRY("CATDatParser::~CATDatParser"); |
|
100 |
|
101 if ( m_In.is_open() ) |
|
102 m_In.close(); |
|
103 // Delete temporary input file if any |
|
104 if ( !m_sInputFileTemp.empty() ) |
|
105 { |
|
106 if ( FileExists( m_sInputFileTemp.c_str() ) ) |
|
107 FileDelete( m_sInputFileTemp, false ); |
|
108 } |
|
109 // Clean memory addresses if any |
|
110 CleanMemoryAddresses(); |
|
111 // Delete rom symbol. |
|
112 if ( m_pRomSymbol ) |
|
113 { |
|
114 delete m_pRomSymbol; |
|
115 m_pRomSymbol = NULL; |
|
116 } |
|
117 } |
|
118 |
|
119 // ----------------------------------------------------------------------------- |
|
120 // CATDatParser::Analyze |
|
121 // Analyze given data file |
|
122 // ----------------------------------------------------------------------------- |
|
123 int CATDatParser::Analyze() |
|
124 { |
|
125 LOG_FUNC_ENTRY("CATDatParser::Analyze"); |
|
126 // Return if input file not set |
|
127 if ( m_sInputFile.empty() ) |
|
128 return AT_RETURN_CODE::INVALID_DATA_FILE; |
|
129 // If open close first |
|
130 if ( m_In.is_open() ) |
|
131 m_In.close(); |
|
132 // Open file |
|
133 m_In.open( m_sInputFile.c_str() ); |
|
134 if ( ! m_In.good() ) |
|
135 return AT_RETURN_CODE::INVALID_DATA_FILE; |
|
136 try { |
|
137 // If rom symbol file specified. |
|
138 if ( ! m_vRomSymbolFiles.empty() ) |
|
139 { |
|
140 // Create new rom symbol file "parser". |
|
141 m_pRomSymbol = new CATRomSymbol(); |
|
142 m_pRomSymbol->m_bShowProgressMessages = true; |
|
143 // Set symbol files. |
|
144 if ( ! m_pRomSymbol->SetSymbols( m_vRomSymbolFiles ) ) |
|
145 { |
|
146 cout << AT_MSG << "Rom/Rofs symbols error: " << m_pRomSymbol->GetError() << endl; |
|
147 // If file open fails we delete it and will not use it. |
|
148 delete m_pRomSymbol; |
|
149 m_pRomSymbol = NULL; |
|
150 cout << AT_MSG << "Analyze aborted." << endl; |
|
151 return AT_RETURN_CODE::SYMBOL_FILE_ERROR; |
|
152 } |
|
153 } |
|
154 // Return code |
|
155 int iRet = 0; |
|
156 // Clear variables |
|
157 ClearParsingVariables(); |
|
158 // If output defined disable printing |
|
159 if ( ! m_sOutputFile.empty() ) |
|
160 m_DataSaver.SetPrintFlag( false ); |
|
161 // Header |
|
162 Header(); |
|
163 // Parsing |
|
164 iRet = Parse(); |
|
165 // Footer |
|
166 if ( iRet == AT_RETURN_CODE::OK ) |
|
167 Footer(); |
|
168 // If output defined save xml |
|
169 if ( ! m_sOutputFile.empty() ) |
|
170 m_DataSaver.SaveLinesToFile( m_sOutputFile.c_str(), XML_DATA ); |
|
171 // Return |
|
172 return iRet; |
|
173 } catch ( int i ) |
|
174 { |
|
175 cout << AT_MSG << "Error, Analyze failed. : " << i << endl; |
|
176 return AT_RETURN_CODE::UNHANDLED_EXCEPTION; |
|
177 } |
|
178 } |
|
179 // ----------------------------------------------------------------------------- |
|
180 // CATDatParser::Header |
|
181 // Print header of report |
|
182 // ----------------------------------------------------------------------------- |
|
183 void CATDatParser::Header() |
|
184 { |
|
185 LOG_FUNC_ENTRY("CATDatParser::Header"); |
|
186 // Analyze report header |
|
187 m_DataSaver.AddString( "Atool.exe v." ); |
|
188 m_DataSaver.AddString( ATOOL_VERSION ); |
|
189 m_DataSaver.AddString( "\n" ); |
|
190 m_DataSaver.AddString( "Analyzing memory leaks..." ); |
|
191 m_DataSaver.AddLineToLast(); |
|
192 } |
|
193 |
|
194 // ----------------------------------------------------------------------------- |
|
195 // CATDatParser::Footer |
|
196 // Print footer of report |
|
197 // ----------------------------------------------------------------------------- |
|
198 void CATDatParser::Footer() |
|
199 { |
|
200 LOG_FUNC_ENTRY("CATDatParser::Footer"); |
|
201 m_DataSaver.AddString( "\nTotal Runs: " ); |
|
202 m_DataSaver.AddInteger( m_iTotalRuns ); |
|
203 m_DataSaver.AddLineToLast(); |
|
204 |
|
205 int iFailedRuns = m_iTotalRuns - m_iSuccesfullRuns; |
|
206 m_DataSaver.AddString( "Failed Runs: " ); |
|
207 m_DataSaver.AddInteger( iFailedRuns ); |
|
208 m_DataSaver.AddLineToLast(); |
|
209 |
|
210 char cTemp[128]; |
|
211 string sResult( itoa( m_iTotalRuns, cTemp, 10 ) ); |
|
212 sResult.append( ";" ); |
|
213 sResult.append( itoa( iFailedRuns, cTemp, 10 ) ); |
|
214 sResult.append( ";" ); |
|
215 |
|
216 m_DataSaver.SaveXML( sResult, RESULT ); |
|
217 } |
|
218 |
|
219 // ----------------------------------------------------------------------------- |
|
220 // CATDatParser::ClearParsingVariables |
|
221 // Clear/Reset all member variables related to parsing data file |
|
222 // ----------------------------------------------------------------------------- |
|
223 void CATDatParser::ClearParsingVariables() |
|
224 { |
|
225 LOG_FUNC_ENTRY("CATDatParser::ClearParsingVariables"); |
|
226 // Clear variables related to analyze |
|
227 m_eProcess_state = not_started; |
|
228 m_bProcessStartFound = false; |
|
229 m_bDllLoadFound = false; |
|
230 m_iTotalNumberOfLeaks = 0; |
|
231 m_iPinPointedLeaks = 0; |
|
232 m_iLeakNumber = 0; |
|
233 m_iTotalRuns = 0; |
|
234 m_iSuccesfullRuns = 0; |
|
235 m_bSubtestOnGoing = false; |
|
236 m_iSubtestStartHandleCount = 0; |
|
237 CleanMemoryAddresses(); |
|
238 } |
|
239 |
|
240 // ----------------------------------------------------------------------------- |
|
241 // CATDatParser::Parse |
|
242 // Parses data file. Note! header and footer of the report are done in |
|
243 // separate functions. |
|
244 // ----------------------------------------------------------------------------- |
|
245 int CATDatParser::Parse() |
|
246 { |
|
247 LOG_FUNC_ENTRY("CATDatParser::Parse"); |
|
248 // Read all lines |
|
249 char cLine[MAX_LINE_LENGTH]; |
|
250 do |
|
251 { |
|
252 string sLine; |
|
253 try { |
|
254 m_In.getline( cLine, MAX_LINE_LENGTH ); |
|
255 sLine = cLine ; |
|
256 } catch(...) |
|
257 { |
|
258 LOG_STRING( AT_MSG << "Unexpected error, reading data file." ); |
|
259 continue; |
|
260 } |
|
261 if( sLine.find( LABEL_DATA_FILE_VERSION ) != string::npos ) |
|
262 { |
|
263 // Check data file version |
|
264 if( sLine.find( AT_DATA_FILE_VERSION ) == string::npos ) |
|
265 { |
|
266 return AT_RETURN_CODE::WRONG_DATA_FILE_VERSION; |
|
267 } |
|
268 } |
|
269 else if( sLine.find( LABEL_PROCESS_START ) != string::npos ) |
|
270 { |
|
271 if ( ! ParseProcessStart( sLine ) ) |
|
272 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
273 } |
|
274 else if( sLine.find( LABEL_DLL_LOAD ) != string::npos ) |
|
275 { |
|
276 if ( ! ParseDllLoad( sLine ) ) |
|
277 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
278 } |
|
279 else if( sLine.find( LABEL_DLL_UNLOAD ) != string::npos ) |
|
280 { |
|
281 if ( ! ParseDllUnload( sLine ) ) |
|
282 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
283 } |
|
284 else if( sLine.find( LABEL_MEM_LEAK ) != string::npos) |
|
285 { |
|
286 if ( ! ParseMemLeak( sLine ) ) |
|
287 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
288 } |
|
289 else if( sLine.find( LABEL_PROCESS_END ) != string::npos ) |
|
290 { |
|
291 if ( ! ParseProcessEnd( sLine ) ) |
|
292 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
293 } |
|
294 else if( sLine.find( LABEL_ERROR_OCCURED ) != string::npos ) |
|
295 { |
|
296 if ( ! ParseErrorOccured( sLine ) ) |
|
297 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
298 } |
|
299 else if( sLine.find( LABEL_HANDLE_LEAK ) != string::npos ) |
|
300 { |
|
301 if ( ! ParseHandleLeak( sLine ) ) |
|
302 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
303 } |
|
304 else if( sLine.find( LABEL_TEST_START ) != string::npos ) |
|
305 { |
|
306 if ( ! ParseTestStart( sLine ) ) |
|
307 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
308 } |
|
309 else if( sLine.find( LABEL_TEST_END ) != string::npos ) |
|
310 { |
|
311 if ( ! ParseTestEnd( sLine ) ) |
|
312 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
313 } |
|
314 else if( sLine.find( LABEL_LOGGING_CANCELLED ) != string::npos ) |
|
315 { |
|
316 if ( ! ParseLoggingCancelled( sLine ) ) |
|
317 return AT_RETURN_CODE::ANALYZE_ERROR; |
|
318 } |
|
319 } |
|
320 while( m_In.good() ); |
|
321 // Message of failed run if process start was last line in data. |
|
322 if ( m_eProcess_state == ongoing ) |
|
323 { |
|
324 m_DataSaver.AddString( "Test run failed.\n" ); |
|
325 m_DataSaver.AddLineToLast(); |
|
326 } |
|
327 return AT_RETURN_CODE::OK; |
|
328 } |
|
329 |
|
330 // ----------------------------------------------------------------------------- |
|
331 // CATDatParser::ParseProcessStart |
|
332 // ----------------------------------------------------------------------------- |
|
333 bool CATDatParser::ParseProcessStart( string& sLine) |
|
334 { |
|
335 LOG_FUNC_ENTRY("CATDatParser::ParseProcessStart"); |
|
336 if ( m_eProcess_state == ongoing ) |
|
337 { |
|
338 m_DataSaver.AddString( "Test run failed.\n" ); |
|
339 m_DataSaver.AddLineToLast(); |
|
340 } |
|
341 m_eProcess_state = ongoing; |
|
342 m_bProcessStartFound = true; |
|
343 |
|
344 // Clear handle leaks |
|
345 m_vHandleLeaks.clear(); |
|
346 // Increment runs |
|
347 m_iTotalRuns++; |
|
348 // Clean leak count |
|
349 m_iTotalNumberOfLeaks = 0; |
|
350 // Clean pin pointed leaks count. |
|
351 m_iPinPointedLeaks = 0; |
|
352 // Clean leak number |
|
353 m_iLeakNumber = 0; |
|
354 |
|
355 // Clean loaded mods |
|
356 m_vDllLoadModList.clear(); |
|
357 m_vDllLoadModListSubTest.clear(); |
|
358 |
|
359 // Skip text PROCESS_START |
|
360 GetStringUntilNextSpace( sLine ); |
|
361 // Get process name |
|
362 m_sCurrentProcessName = GetStringUntilNextSpace( sLine ); |
|
363 // Get Pid |
|
364 string sPid = GetStringUntilNextSpace( sLine ); |
|
365 m_iCurrentProcessId = _httoi( sPid.c_str() ); |
|
366 |
|
367 // Header for process start |
|
368 m_DataSaver.AddString( "\n--------------------------------\n" ); |
|
369 m_DataSaver.AddString( "Test Run start (" ); |
|
370 m_DataSaver.AddString( m_sCurrentProcessName.c_str() ); |
|
371 m_DataSaver.AddString( "): " ); |
|
372 |
|
373 // Get start time |
|
374 string sTime = GetStringUntilNextSpace( sLine ); |
|
375 sTime = ConvertTimeToLocalTime( sTime ); |
|
376 m_DataSaver.AddString( sTime.c_str() ); |
|
377 |
|
378 // Create data for xml |
|
379 string sData( sTime ); |
|
380 sData.append( ";" ); |
|
381 |
|
382 // Build mode UDEB/UREL. |
|
383 string sBuildType = GetStringUntilNextSpace( sLine ); |
|
384 |
|
385 m_DataSaver.AddString( " Build target: " ); |
|
386 if( sBuildType.compare( "0" ) == 0 ) |
|
387 { |
|
388 m_eBuildType = CATProject::UREL; |
|
389 } |
|
390 else if( sBuildType.compare( "1" ) == 0 ) |
|
391 { |
|
392 m_eBuildType = CATProject::UDEB; |
|
393 } |
|
394 m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() ); |
|
395 |
|
396 // Version. |
|
397 string sVersion = GetStringUntilNextSpace( sLine ); |
|
398 unsigned int iVer = 0; |
|
399 if ( hexToDec( sVersion, iVer ) && iVer != 0 ) |
|
400 m_iDataVersion = iVer; |
|
401 |
|
402 // End line in data. |
|
403 m_DataSaver.AddLineToLast(); |
|
404 |
|
405 // xml |
|
406 sData.append( CATProject::GetBuildTypeString( m_eBuildType ) ); |
|
407 sData.append( ";" ); |
|
408 sData.append( m_sCurrentProcessName ); |
|
409 m_DataSaver.SaveXML( sData, RUN ); |
|
410 |
|
411 // If projects platform defined check that it is same in data. (future feature). |
|
412 if ( ! m_sProjectPlatform.empty() ) |
|
413 { |
|
414 // If platform info is added to data file do check here. |
|
415 } |
|
416 // If projects build type defined check that it is same in data. |
|
417 if ( m_eProjectBuildType != -1 ) |
|
418 { |
|
419 if ( m_eBuildType != m_eProjectBuildType ) |
|
420 { |
|
421 string sError(AT_MSG); |
|
422 sError.append( "Error, analyzed data has build type of " ); |
|
423 sError.append( CATProject::GetBuildTypeString( m_eBuildType ) ); |
|
424 sError.append( " and project has build type " ); |
|
425 sError.append( CATProject::GetBuildTypeString( m_eProjectBuildType ) ); |
|
426 sError.append( ". Pinpointed code lines are not valid." ); |
|
427 m_DataSaver.AddString( sError.c_str(), false ); |
|
428 m_DataSaver.AddLineToLast(); |
|
429 } |
|
430 } |
|
431 return true; |
|
432 } |
|
433 |
|
434 // ----------------------------------------------------------------------------- |
|
435 // CATDatParser::ParseProcessEnd |
|
436 // ----------------------------------------------------------------------------- |
|
437 bool CATDatParser::ParseProcessEnd( string& sLine ) |
|
438 { |
|
439 LOG_FUNC_ENTRY("CATDatParser::ParseProcessEnd"); |
|
440 GetStringUntilNextSpace( sLine ); |
|
441 |
|
442 // Get process id |
|
443 string sProcessID = GetStringUntilNextSpace( sLine ); |
|
444 unsigned long iProcessID = _httoi( sProcessID.c_str() ); |
|
445 |
|
446 // Get time |
|
447 string sTime = GetStringUntilNextSpace( sLine ); |
|
448 |
|
449 // Convert leak time |
|
450 sTime = ConvertTimeToLocalTime( sTime ); |
|
451 |
|
452 // Process started? |
|
453 if( iProcessID == m_iCurrentProcessId ) |
|
454 { |
|
455 m_iSuccesfullRuns++; |
|
456 m_DataSaver.AddLineToLast(); |
|
457 m_DataSaver.AddString( "Test Run end (" ); |
|
458 m_DataSaver.AddString( m_sCurrentProcessName.c_str() ); |
|
459 m_DataSaver.AddString( "): " ); |
|
460 m_DataSaver.AddString( sTime.c_str() ); |
|
461 m_DataSaver.AddLineToLast(); |
|
462 m_DataSaver.AddString( "Build target: " ); |
|
463 m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() ); |
|
464 m_DataSaver.AddLineToLast(); |
|
465 |
|
466 m_eProcess_state = stopped; |
|
467 // Number of leaks |
|
468 if ( m_iLogLevel == 1 || m_iLogLevel == 2 ) |
|
469 { |
|
470 if ( m_iPinPointedLeaks > 0 ) |
|
471 { |
|
472 m_DataSaver.AddInteger( m_iPinPointedLeaks ); |
|
473 m_DataSaver.AddString( " number of pinpointed memory leak(s)." ); |
|
474 m_DataSaver.AddLineToLast(); |
|
475 } |
|
476 m_DataSaver.AddInteger( m_iLeakNumber ); |
|
477 m_DataSaver.AddString( " total number of memory leak(s)." ); |
|
478 m_DataSaver.AddLineToLast(); |
|
479 } |
|
480 else |
|
481 { |
|
482 m_DataSaver.AddInteger( m_iTotalNumberOfLeaks ); |
|
483 m_DataSaver.AddString( " memory leak(s) found." ); |
|
484 m_DataSaver.AddLineToLast(); |
|
485 } |
|
486 |
|
487 // xml |
|
488 char cTemp[128]; |
|
489 m_DataSaver.SaveXML( itoa( m_iTotalNumberOfLeaks, cTemp, 10 ) , MEM_LEAKS ); |
|
490 |
|
491 // Print all modules which have leaks |
|
492 for( size_t i = 0 ; i < m_vDllLoadModList.size() ; i++ ) |
|
493 { |
|
494 if( m_vDllLoadModList.at(i).iLeaks > 0 ) |
|
495 { |
|
496 m_DataSaver.AddInteger( m_vDllLoadModList.at(i).iLeaks ); |
|
497 m_DataSaver.AddString( " memory leak(s) in module: " ); |
|
498 m_DataSaver.AddString( m_vDllLoadModList.at(i).sModuleName.c_str() ); |
|
499 m_DataSaver.AddLineToLast(); |
|
500 |
|
501 // xml |
|
502 string sModuleNameAndLeaks( m_vDllLoadModList[i].sModuleName ); |
|
503 sModuleNameAndLeaks.append(";"); |
|
504 sModuleNameAndLeaks.append( itoa( m_vDllLoadModList[i].iLeaks, cTemp, 10 ) ); |
|
505 m_DataSaver.SaveXML( sModuleNameAndLeaks , MEM_LEAK_MODULE ); |
|
506 } |
|
507 } |
|
508 |
|
509 if ( m_vHandleLeaks.size() > 0 ) |
|
510 { |
|
511 // We have handle leaks |
|
512 bool bHandLeaksFound = false; |
|
513 int iTotalNrOfLeaks = 0; |
|
514 // Print handle leaks |
|
515 for( size_t i = 0 ; i < m_vHandleLeaks.size() ; i++ ) |
|
516 { |
|
517 string sTempHandleLeak( m_vHandleLeaks[i] ); |
|
518 // Count. |
|
519 string sNrOfLeaks( GetStringUntilNextSpace(sTempHandleLeak) ); |
|
520 |
|
521 // Name. |
|
522 //string sHandleLeakModule( GetStringUntilNextSpace( sTempHandleLeak ) ); |
|
523 string sHandleLeakModule( "Unknown" ); |
|
524 |
|
525 unsigned long iNrOfLeaks = _httoi( sNrOfLeaks.c_str() ); |
|
526 iTotalNrOfLeaks += iNrOfLeaks; |
|
527 if( iNrOfLeaks ) |
|
528 { |
|
529 if( !bHandLeaksFound ) |
|
530 { |
|
531 m_DataSaver.SaveXML( sNrOfLeaks , HANDLE_LEAKS ); |
|
532 } |
|
533 bHandLeaksFound = true; |
|
534 m_DataSaver.AddInteger( iNrOfLeaks ); |
|
535 // Just print out how many leaks found. |
|
536 // Because its always unknown. |
|
537 m_DataSaver.AddString( " handle leak(s) found." ); |
|
538 m_DataSaver.AddLineToLast(); |
|
539 |
|
540 // xml |
|
541 string sXMLInfo( sHandleLeakModule ); |
|
542 sXMLInfo.append( ";" ); sXMLInfo.append( sNrOfLeaks ); |
|
543 m_DataSaver.SaveXML( sXMLInfo , HANDLE_LEAK_MODULE ); |
|
544 } |
|
545 } |
|
546 // Update number if handle leaks |
|
547 m_DataSaver.SaveXML( itoa( iTotalNrOfLeaks, cTemp, 10 ) , HANDLE_LEAKS ); |
|
548 if( !bHandLeaksFound ) |
|
549 { |
|
550 //m_DataSaver.AddLineToLast(); |
|
551 m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS ); |
|
552 m_DataSaver.AddLineToLast(); |
|
553 } |
|
554 } |
|
555 else |
|
556 { |
|
557 // No handle leaks |
|
558 m_DataSaver.AddLineToLast(); |
|
559 m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS ); |
|
560 m_DataSaver.AddLineToLast(); |
|
561 } |
|
562 |
|
563 // Process end to xml |
|
564 m_DataSaver.SaveXML( sTime, RUN_END ); |
|
565 // Reset current process |
|
566 m_iCurrentProcessId = 0; |
|
567 } |
|
568 |
|
569 // If no dll load or process start found |
|
570 if ( ! m_bProcessStartFound || !m_bDllLoadFound ) |
|
571 { |
|
572 m_DataSaver.AddLineToLast(); |
|
573 m_DataSaver.AddString( AT_ANALYZE_INSUFFICIENT_LOGGING_DATA ); |
|
574 m_DataSaver.AddLineToLast(); |
|
575 } |
|
576 |
|
577 return true; |
|
578 } |
|
579 |
|
580 // ----------------------------------------------------------------------------- |
|
581 // CATDatParser::ParseDllLoad |
|
582 // ----------------------------------------------------------------------------- |
|
583 bool CATDatParser::ParseDllLoad( string& sLine ) |
|
584 { |
|
585 LOG_FUNC_ENTRY("CATDatParser::ParseDllLoad"); |
|
586 //DLL_LOAD <DLL name> <Time stamp> <Memory start address> <Memory end address> |
|
587 m_bDllLoadFound = true; |
|
588 DLL_LOAD_INFO structDllInfo; |
|
589 structDllInfo.iStartAddress = 0; |
|
590 structDllInfo.iEndAddress = 0; |
|
591 structDllInfo.iLeaks = 0; |
|
592 |
|
593 // Skip "DLL_LOAD " |
|
594 GetStringUntilNextSpace( sLine ); |
|
595 |
|
596 // Get module name |
|
597 structDllInfo.sModuleName = GetStringUntilNextSpace( sLine ); |
|
598 ChangeToLower( structDllInfo.sModuleName ); |
|
599 |
|
600 // Create module from this if project platform emulator |
|
601 if ( _stricmp( "winscw", m_sProjectPlatform.c_str() ) == 0 ) |
|
602 CreateWinscwModule( structDllInfo.sModuleName ); |
|
603 |
|
604 // Get dll start memory string address from line |
|
605 // Convert string address to real memory address |
|
606 structDllInfo.iStartAddress = |
|
607 _httoi( GetStringUntilNextSpace( sLine ).c_str() ); |
|
608 |
|
609 // Get dll end memory string address from line |
|
610 // Convert string address to real memory address |
|
611 structDllInfo.iEndAddress = |
|
612 _httoi( |
|
613 GetStringUntilNextSpace( sLine ).c_str() ); |
|
614 |
|
615 if ( m_iDataVersion >= AT_DLL_TIMESTAMP_DATA_VERSION ) |
|
616 { |
|
617 // Pickup module loading time. |
|
618 string sLoadTime = GetStringUntilNextSpace( sLine ); |
|
619 unsigned long long ull; |
|
620 if ( hexToDec( sLoadTime, ull ) ) |
|
621 structDllInfo.iLoadTime = ull; |
|
622 } |
|
623 |
|
624 // Is module already loaded, if not add it to list. |
|
625 bool bFound = false; |
|
626 for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModList.begin(); |
|
627 it != m_vDllLoadModList.end() ; it++ ) |
|
628 { |
|
629 if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 ) |
|
630 { |
|
631 bFound = true; |
|
632 break; |
|
633 } |
|
634 } |
|
635 if( ! bFound ) |
|
636 m_vDllLoadModList.push_back( structDllInfo ); |
|
637 |
|
638 // Sub test module list. |
|
639 bFound = false; |
|
640 for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModListSubTest.begin(); |
|
641 it != m_vDllLoadModListSubTest.end() ; it++ ) |
|
642 { |
|
643 if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 ) |
|
644 { |
|
645 bFound = true; |
|
646 break; |
|
647 } |
|
648 } |
|
649 if( ! bFound ) |
|
650 m_vDllLoadModListSubTest.push_back( structDllInfo ); |
|
651 |
|
652 return true; |
|
653 } |
|
654 |
|
655 // ----------------------------------------------------------------------------- |
|
656 // CATDatParser::ParseDllUnload |
|
657 // ----------------------------------------------------------------------------- |
|
658 bool CATDatParser::ParseDllUnload( string& sLine ) |
|
659 { |
|
660 LOG_FUNC_ENTRY("CATDatParser::ParseDllUnload"); |
|
661 |
|
662 // Ignore unloads on older version because no timestamps. |
|
663 if ( m_iDataVersion < AT_DLL_TIMESTAMP_DATA_VERSION ) |
|
664 { |
|
665 return true; |
|
666 } |
|
667 |
|
668 // Skip "DLL_UNLOAD " |
|
669 GetStringUntilNextSpace( sLine ); |
|
670 |
|
671 // Get module name |
|
672 string sModuleName = GetStringUntilNextSpace( sLine ); |
|
673 ChangeToLower( sModuleName ); |
|
674 |
|
675 // skip adresses - not currently used |
|
676 GetStringUntilNextSpace( sLine ); |
|
677 GetStringUntilNextSpace( sLine ); |
|
678 |
|
679 // Unload time |
|
680 unsigned long long ull; |
|
681 string sUnload = GetStringUntilNextSpace( sLine ); |
|
682 if ( ! hexToDec( sUnload, ull ) ) |
|
683 return true; |
|
684 |
|
685 // Set module unload time. |
|
686 vector<DLL_LOAD_INFO>::iterator it; |
|
687 for( it = m_vDllLoadModList.begin() ; it != m_vDllLoadModList.end() ; it++ ) |
|
688 { |
|
689 if ( sModuleName.compare( it->sModuleName ) == 0 ) |
|
690 { |
|
691 (*it).iUnloadTime = ull; |
|
692 break; |
|
693 } |
|
694 } |
|
695 for( it = m_vDllLoadModListSubTest.begin() ; it != m_vDllLoadModListSubTest.end() ; it++ ) |
|
696 { |
|
697 if ( sModuleName.compare( it->sModuleName ) == 0 ) |
|
698 { |
|
699 (*it).iUnloadTime = ull; |
|
700 break; |
|
701 } |
|
702 } |
|
703 return true; |
|
704 } |
|
705 // ----------------------------------------------------------------------------- |
|
706 // CATDatParser::ParseLoggingCancelled |
|
707 // ----------------------------------------------------------------------------- |
|
708 bool CATDatParser::ParseLoggingCancelled( string& sLine ) |
|
709 { |
|
710 LOG_FUNC_ENTRY("CATDatParser::ParseLoggingCancelled"); |
|
711 // Skip text "LOGGING_CANCELLED" |
|
712 GetStringUntilNextSpace( sLine ); |
|
713 |
|
714 // Get time |
|
715 string sTime( GetStringUntilNextSpace( sLine ) ); |
|
716 sTime = ConvertTimeToLocalTime( sTime ); |
|
717 m_DataSaver.AddString( "Logging Cancelled." ); |
|
718 m_DataSaver.AddLineToLast(); |
|
719 return true; |
|
720 } |
|
721 |
|
722 // ----------------------------------------------------------------------------- |
|
723 // CATDatParser::ParseHandleLeak |
|
724 // ----------------------------------------------------------------------------- |
|
725 bool CATDatParser::ParseHandleLeak( string& sLine ) |
|
726 { |
|
727 LOG_FUNC_ENTRY("CATDatParser::ParseHandleLeak"); |
|
728 // Skip text "HANDLE_LEAK" |
|
729 GetStringUntilNextSpace( sLine ); |
|
730 m_vHandleLeaks.push_back( sLine ); |
|
731 return true; |
|
732 } |
|
733 |
|
734 // ----------------------------------------------------------------------------- |
|
735 // CATDatParser::ParseTestStart |
|
736 // ----------------------------------------------------------------------------- |
|
737 bool CATDatParser::ParseTestStart( string& sLine ) |
|
738 { |
|
739 LOG_FUNC_ENTRY("CATDatParser::ParseTestStart"); |
|
740 m_bSubtestOnGoing = true; |
|
741 m_iLeakNumber = 0; |
|
742 m_iPinPointedSubTestLeaks = 0; |
|
743 |
|
744 // Reset subtest leaked modules list |
|
745 for( size_t i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ ) |
|
746 { |
|
747 m_vDllLoadModListSubTest.at(i).iLeaks = 0; |
|
748 } |
|
749 |
|
750 // Skip text "TEST_START" |
|
751 GetStringUntilNextSpace( sLine ); |
|
752 // Time |
|
753 string sTime( GetStringUntilNextSpace( sLine ) ); |
|
754 sTime = ConvertTimeToLocalTime( sTime ); |
|
755 // Name |
|
756 string sSubTestName( GetStringUntilNextSpace( sLine ) ); |
|
757 m_DataSaver.AddLineToLast(); |
|
758 |
|
759 // Get handle count in subtest start |
|
760 string sSubTestStartHandleCount( GetStringUntilNextSpace( sLine ) ); |
|
761 m_iSubtestStartHandleCount = atoi( sSubTestStartHandleCount.c_str() ); |
|
762 |
|
763 // Add start to report |
|
764 m_DataSaver.AddString( "\nSub test (" ); |
|
765 m_DataSaver.AddString( sSubTestName.c_str() ); |
|
766 m_DataSaver.AddString( ") start: " ); |
|
767 m_DataSaver.AddString( sTime.c_str() ); |
|
768 |
|
769 // m_DataSaver.AddLineToLast(); |
|
770 |
|
771 // Add start to xml |
|
772 string sResult( sSubTestName ); |
|
773 sResult.append( ";" ); |
|
774 sResult.append( sTime ); |
|
775 sResult.append( ";" ); |
|
776 m_DataSaver.SaveXML( sResult, TEST_START ); |
|
777 return true; |
|
778 } |
|
779 |
|
780 // ----------------------------------------------------------------------------- |
|
781 // CATDatParser::ParseTestEnd |
|
782 // ----------------------------------------------------------------------------- |
|
783 bool CATDatParser::ParseTestEnd( string& sLine ) |
|
784 { |
|
785 LOG_FUNC_ENTRY("CATDatParser::ParseTestEnd"); |
|
786 // Skip text "TEST_END" |
|
787 GetStringUntilNextSpace( sLine ); |
|
788 |
|
789 // Time |
|
790 string sTime( GetStringUntilNextSpace( sLine ) ); |
|
791 sTime = ConvertTimeToLocalTime( sTime ); |
|
792 |
|
793 // Name |
|
794 string sSubTestName( GetStringUntilNextSpace( sLine ) ); |
|
795 m_DataSaver.AddLineToLast(); |
|
796 |
|
797 // Add test end info to report |
|
798 m_DataSaver.AddString( "Sub test (" ); |
|
799 m_DataSaver.AddString( sSubTestName.c_str() ); |
|
800 m_DataSaver.AddString( ") end: " ); |
|
801 m_DataSaver.AddString( sTime.c_str() ); |
|
802 m_DataSaver.AddLineToLast(); |
|
803 |
|
804 // Leak count to report in subtest |
|
805 if( m_iLeakNumber > 0 ) |
|
806 { |
|
807 if ( m_iLogLevel == 1 || m_iLogLevel == 2 ) |
|
808 { |
|
809 m_DataSaver.AddInteger( m_iPinPointedSubTestLeaks ); |
|
810 m_DataSaver.AddString( " number of pinpointed memory leaks." ); |
|
811 m_DataSaver.AddLineToLast(); |
|
812 m_DataSaver.AddInteger( m_iLeakNumber ); |
|
813 m_DataSaver.AddString( " memory leaks found." ); |
|
814 } |
|
815 else |
|
816 { |
|
817 m_DataSaver.AddInteger( m_iLeakNumber ); |
|
818 m_DataSaver.AddString( " memory leaks found." ); |
|
819 } |
|
820 } |
|
821 else |
|
822 { |
|
823 m_DataSaver.AddString( "No memory leaks found." ); |
|
824 } |
|
825 m_DataSaver.AddLineToLast(); |
|
826 |
|
827 // Use sTime to store info to xml |
|
828 sTime.append(";"); |
|
829 char cTemp[128]; |
|
830 // Print all modules whitch have leaks |
|
831 for( unsigned int i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ ) |
|
832 { |
|
833 if( m_vDllLoadModListSubTest.at(i).iLeaks > 0 ) |
|
834 { |
|
835 // Normal report |
|
836 m_DataSaver.AddInteger( m_vDllLoadModListSubTest[i].iLeaks ); |
|
837 m_DataSaver.AddString( " memory leaks in module: " ); |
|
838 m_DataSaver.AddString( m_vDllLoadModListSubTest.at(i).sModuleName.c_str() ); |
|
839 m_DataSaver.AddLineToLast(); |
|
840 // xml |
|
841 string sModuleNameAndLeaks( m_vDllLoadModListSubTest.at(i).sModuleName ); |
|
842 sModuleNameAndLeaks.append(";"); |
|
843 sModuleNameAndLeaks.append( itoa( m_vDllLoadModListSubTest.at(i).iLeaks, cTemp, 10 ) ); |
|
844 m_DataSaver.SaveXML( sModuleNameAndLeaks , SUBTEST_MEM_LEAK_MODULE ); |
|
845 } |
|
846 } |
|
847 // Handle count |
|
848 int iEndHandleCount = atoi( GetStringUntilNextSpace( sLine ).c_str() ); |
|
849 // Is there handle leaks in subtest? |
|
850 if( iEndHandleCount > m_iSubtestStartHandleCount ) |
|
851 { |
|
852 // Print normal report |
|
853 m_DataSaver.AddInteger( iEndHandleCount - m_iSubtestStartHandleCount ); |
|
854 m_DataSaver.AddString( " handle leaks in subtest: " ); |
|
855 m_DataSaver.AddString( sSubTestName.c_str() ); |
|
856 m_DataSaver.AddString( "." ); |
|
857 m_DataSaver.AddLineToLast(); |
|
858 |
|
859 // Print handle leaks to XML |
|
860 string sNrOfHandleLeaks( itoa( iEndHandleCount - m_iSubtestStartHandleCount, cTemp, 10 ) ); |
|
861 sNrOfHandleLeaks.append( ";" ); |
|
862 m_DataSaver.SaveXML( sNrOfHandleLeaks, SUBTEST_HANDLE_LEAKS ); |
|
863 } |
|
864 else |
|
865 { |
|
866 // No handle leaks |
|
867 m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS ); |
|
868 m_DataSaver.AddLineToLast(); |
|
869 } |
|
870 // Save xml |
|
871 m_DataSaver.SaveXML( sTime, TEST_END ); |
|
872 // Back to normal leaks |
|
873 m_bSubtestOnGoing = false; |
|
874 return true; |
|
875 } |
|
876 |
|
877 // ----------------------------------------------------------------------------- |
|
878 // CATDatParser::ParseErrorOccured |
|
879 // ----------------------------------------------------------------------------- |
|
880 bool CATDatParser::ParseErrorOccured( string& sLine ) |
|
881 { |
|
882 LOG_FUNC_ENTRY("CATDatParser::ParseErrorOccured"); |
|
883 string sTime,sError; |
|
884 |
|
885 // Skip text "ERROR_OCCURED:" |
|
886 GetStringUntilNextSpace( sLine ); |
|
887 |
|
888 // Get error |
|
889 sError = GetStringUntilNextSpace( sLine ); |
|
890 // Get and convert error time |
|
891 sTime = GetStringUntilNextSpace( sLine ); |
|
892 sTime = ConvertTimeToLocalTime( sTime ); |
|
893 |
|
894 // Print error line |
|
895 m_DataSaver.AddLineToLast(); |
|
896 m_DataSaver.AddString( "Error occured on: " ); |
|
897 m_DataSaver.AddString( sTime.c_str() ); |
|
898 m_DataSaver.AddString( ". " ); |
|
899 m_DataSaver.AddString( "Symbian error code: " ); |
|
900 m_DataSaver.AddString( sError.c_str() ); |
|
901 m_DataSaver.AddString( "." ); |
|
902 m_DataSaver.AddLineToLast(); |
|
903 |
|
904 return true; |
|
905 } |
|
906 |
|
907 // ----------------------------------------------------------------------------- |
|
908 // CATDatParser::ParseMemLeak |
|
909 // ----------------------------------------------------------------------------- |
|
910 bool CATDatParser::ParseMemLeak( string& sLine ) |
|
911 { |
|
912 LOG_FUNC_ENTRY("CATDatParser::ParseMemLeak"); |
|
913 // Increment leak count |
|
914 if ( ! m_bSubtestOnGoing ) |
|
915 m_iTotalNumberOfLeaks++; |
|
916 |
|
917 // Increase leak number |
|
918 m_iLeakNumber++; |
|
919 |
|
920 // Leak data variables |
|
921 string sModuleName; |
|
922 string sLeakSize; |
|
923 string sTime; |
|
924 unsigned long long iTime = 0; |
|
925 string sLeakAddress; |
|
926 |
|
927 // Skip text "MEM_LEAK" |
|
928 GetStringUntilNextSpace( sLine ); |
|
929 // Get leak address |
|
930 sLeakAddress = GetStringUntilNextSpace( sLine ); |
|
931 // Get time |
|
932 sTime = GetStringUntilNextSpace( sLine ); |
|
933 // Convert time to decimal |
|
934 hexToDec( sTime, iTime ); |
|
935 // Get memory reserve size |
|
936 sLeakSize = GetStringUntilNextSpace( sLine ); |
|
937 // Convert leak time |
|
938 sTime = ConvertTimeToLocalTime( sTime ); |
|
939 |
|
940 // Loop thru call stack and put memory addresses in vector |
|
941 CleanMemoryAddresses(); // Clean memory address vector |
|
942 CATMemoryAddress* pMemAddr = 0; |
|
943 vector<string> vStrings = ParseStringToVector( sLine, ' ' ); |
|
944 for( size_t i = 0; i < vStrings.size() ; i++ ) |
|
945 { |
|
946 pMemAddr = new CATMemoryAddress( vStrings.at(i), m_iOffSet ); |
|
947 // Set address time |
|
948 pMemAddr->SetTime( iTime ); |
|
949 // Set address module name |
|
950 if ( pMemAddr->FindSetModuleName( &m_vDllLoadModList ) ) |
|
951 { |
|
952 // Increment leaks in module once |
|
953 if ( sModuleName.empty() ) |
|
954 { |
|
955 if ( m_bSubtestOnGoing ) |
|
956 m_vDllLoadModListSubTest.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++; |
|
957 else |
|
958 m_vDllLoadModList.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++; |
|
959 // Set leak's module where it was located. |
|
960 sModuleName = pMemAddr->GetModuleName(); |
|
961 } |
|
962 } |
|
963 // Add it to vector |
|
964 m_vMemoryAddress.push_back( pMemAddr ); |
|
965 } |
|
966 // If logging level is 0 Skip printing / locating code lines for call stack items. |
|
967 if ( m_iLogLevel == 0 ) |
|
968 return true; |
|
969 if ( m_pModules && vStrings.size() > 0 ) |
|
970 { |
|
971 // Have we successfully located code line for memory address |
|
972 bool bSuccesfullAddressToLine = false; |
|
973 for( size_t x = 0; x < m_vMemoryAddress.size(); x++ ) |
|
974 { |
|
975 int iIndexInDll = m_vMemoryAddress.at( x )->GetDllLoadInfoIndex(); |
|
976 if ( iIndexInDll != -1 ) |
|
977 { |
|
978 // Dll module name from data file |
|
979 string sDllName = m_vDllLoadModList.at( iIndexInDll ).sModuleName; |
|
980 // Find module from project. These are read from makefiles. |
|
981 for ( size_t y = 0; y < m_pModules->size() ; y++ ) |
|
982 { |
|
983 // Module name from project data (makefiles) |
|
984 string sModuleName = m_pModules->at( y )->GetBinaryName(); |
|
985 // If we find module from project ones, use it to located code line for memory address |
|
986 // Note! dll names can be pretty messy i.e. DLL_LOAD 10281fc6.dll{000a0000}[10281fc6] 81d57b88 81e60a90 |
|
987 if ( sDllName.find( sModuleName ) != string::npos ) |
|
988 { |
|
989 m_pModules->at( y )->AddressToLine( m_vMemoryAddress.at( x ) ); |
|
990 if ( ! bSuccesfullAddressToLine ) |
|
991 { |
|
992 int iPPState = m_vMemoryAddress.at( x )->GetAddressToLineState(); |
|
993 if ( iPPState == CATMemoryAddress::EXACT || iPPState == CATMemoryAddress::FUNCTION ) |
|
994 { |
|
995 bSuccesfullAddressToLine = true; |
|
996 if ( m_bSubtestOnGoing ) |
|
997 m_iPinPointedSubTestLeaks++; |
|
998 else |
|
999 m_iPinPointedLeaks++; |
|
1000 } |
|
1001 } |
|
1002 } |
|
1003 } |
|
1004 } |
|
1005 } |
|
1006 // If rom/rofs specified we use it to try get binary and function names |
|
1007 // for addresses currently out of process range. |
|
1008 if ( m_pRomSymbol ) |
|
1009 { |
|
1010 for( size_t x = 0; x < m_vMemoryAddress.size(); x++ ) |
|
1011 { |
|
1012 if ( m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS |
|
1013 || m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_RANGE ) |
|
1014 { |
|
1015 m_pRomSymbol->AddressToLine( m_vMemoryAddress.at(x) ); |
|
1016 } |
|
1017 } |
|
1018 } |
|
1019 } |
|
1020 // Print leak |
|
1021 PrintMemLeak( sTime, sLeakSize, sLeakAddress, sModuleName); |
|
1022 return true; |
|
1023 } |
|
1024 |
|
1025 // ----------------------------------------------------------------------------- |
|
1026 // CATDatParser::PrintMemLeak |
|
1027 // ----------------------------------------------------------------------------- |
|
1028 void CATDatParser::PrintMemLeak(const string& sTime, |
|
1029 const string& sLeakSize, |
|
1030 const string& sLeakAddr, |
|
1031 const string& sModuleName) |
|
1032 { |
|
1033 LOG_FUNC_ENTRY("CATDatParser::PrintMemLeak"); |
|
1034 // Print header data of leak |
|
1035 m_DataSaver.AddString("\nMemory leak "); |
|
1036 m_DataSaver.AddInteger( m_iLeakNumber, true); |
|
1037 |
|
1038 // Leak size |
|
1039 m_DataSaver.AddString( " (" ); |
|
1040 m_DataSaver.AddInteger( _httoi( sLeakSize.c_str() ), true ); |
|
1041 m_DataSaver.AddString( " bytes) " ); |
|
1042 |
|
1043 // Leak address |
|
1044 m_DataSaver.AddString("(0x"); |
|
1045 m_DataSaver.AddString( sLeakAddr.c_str(), true ); |
|
1046 m_DataSaver.AddString( ") " ); |
|
1047 |
|
1048 // Time |
|
1049 m_DataSaver.AddString( sTime.c_str(), true ); |
|
1050 m_DataSaver.AddString( " " ); |
|
1051 |
|
1052 // Module name |
|
1053 m_DataSaver.AddString( sModuleName.c_str(), true ); |
|
1054 m_DataSaver.SaveCarbideDataHeader(); |
|
1055 |
|
1056 // Add header line |
|
1057 m_DataSaver.AddLineToLast(); |
|
1058 |
|
1059 // Print the call stack items |
|
1060 for( size_t i = 0 ; i < m_vMemoryAddress.size() ; i++ ) |
|
1061 { |
|
1062 // On log levels 1 & 2 we only print located code lines. |
|
1063 #ifndef ADDR2LINE |
|
1064 if( |
|
1065 ( m_iLogLevel == 1 || m_iLogLevel == 2 ) |
|
1066 && |
|
1067 ( m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT |
|
1068 && m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::FUNCTION ) |
|
1069 ) |
|
1070 { |
|
1071 // Skips to next |
|
1072 continue; |
|
1073 } |
|
1074 #endif |
|
1075 #ifdef ADDR2LINE |
|
1076 if( ( m_iLogLevel == 1 || m_iLogLevel == 2 ) |
|
1077 && m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT ) |
|
1078 { |
|
1079 // Skips to next |
|
1080 continue; |
|
1081 } |
|
1082 #endif |
|
1083 else if ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS ) |
|
1084 { |
|
1085 // Is memory address out of modules range |
|
1086 string sTemp; |
|
1087 sTemp.append( m_vMemoryAddress.at(i)->GetAddressString() ); |
|
1088 sTemp.append( " Address out of process memory."); |
|
1089 m_DataSaver.AddString( sTemp.c_str(), true ); |
|
1090 m_DataSaver.AddLineToLast(); |
|
1091 continue; |
|
1092 } |
|
1093 |
|
1094 // Print memory address |
|
1095 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetAddressString().c_str(), true ); |
|
1096 |
|
1097 // Space (only for console output) |
|
1098 m_DataSaver.AddString( " " ); |
|
1099 |
|
1100 m_DataSaver.AddCarbideData( |
|
1101 NumberToHexString( m_vMemoryAddress.at(i)->GetOffSetFromModuleStart() ) ); |
|
1102 |
|
1103 // Module name |
|
1104 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetModuleName().c_str(), true ); |
|
1105 |
|
1106 // Print call stack memory address details depending on state of memory address |
|
1107 switch( m_vMemoryAddress.at(i)->GetAddressToLineState() ) |
|
1108 { |
|
1109 // Address outside of known processes |
|
1110 case CATMemoryAddress::OUT_OF_PROCESS: |
|
1111 m_DataSaver.AddLineToLast(); |
|
1112 break; |
|
1113 // Address located outside of known modules symbols |
|
1114 case CATMemoryAddress::OUT_OF_RANGE: |
|
1115 m_DataSaver.AddString( " " ); |
|
1116 m_DataSaver.AddString( "???", true ); |
|
1117 m_DataSaver.AddLineToLast(); |
|
1118 break; |
|
1119 // Symbol state is currently used when using rom symbol file. |
|
1120 // From it we get module name & function name. |
|
1121 case CATMemoryAddress::SYMBOL: |
|
1122 m_DataSaver.AddString( " " ); |
|
1123 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true ); |
|
1124 if ( ! m_vMemoryAddress.at( i )->GetFileName().empty() ) |
|
1125 { |
|
1126 m_DataSaver.AddString( " (" ); |
|
1127 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true ); |
|
1128 m_DataSaver.AddString( ")" ); |
|
1129 } |
|
1130 m_DataSaver.AddLineToLast(); |
|
1131 break; |
|
1132 // Lst & Map implementation |
|
1133 #ifndef ADDR2LINE |
|
1134 case CATMemoryAddress::FUNCTION: |
|
1135 case CATMemoryAddress::EXACT: |
|
1136 m_DataSaver.AddString( " " ); |
|
1137 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true ); |
|
1138 // Small difference displaying details depending on build urel/udeb |
|
1139 if ( m_eBuildType == CATProject::UREL ) |
|
1140 { |
|
1141 // UREL |
|
1142 // Set build info to data saver |
|
1143 m_DataSaver.SetBuild( false ); |
|
1144 // urel = functionname: linenumber (filename) |
|
1145 m_DataSaver.AddString( ": " ); |
|
1146 if ( m_vMemoryAddress.at(i)->GetFunctionLineNumber() != -1 ) |
|
1147 m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true ); |
|
1148 else if ( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 ) |
|
1149 m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true ); |
|
1150 m_DataSaver.AddString( " (" ); |
|
1151 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true ); |
|
1152 m_DataSaver.AddString( ")" ); |
|
1153 m_DataSaver.AddLineToLast(); |
|
1154 } |
|
1155 else |
|
1156 { |
|
1157 // UDEB |
|
1158 // udeb = functionname: (filename:linenumber) |
|
1159 m_DataSaver.AddString( " (" ); |
|
1160 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true ); |
|
1161 m_DataSaver.AddString( ":" ); |
|
1162 if( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 ) |
|
1163 m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true ); |
|
1164 else |
|
1165 m_DataSaver.AddString( "???", true ); |
|
1166 m_DataSaver.AddString( ")" ); |
|
1167 m_DataSaver.AddLineToLast(); |
|
1168 } |
|
1169 break; |
|
1170 #endif |
|
1171 // addr2line implementation (new). |
|
1172 #ifdef ADDR2LINE |
|
1173 case CATMemoryAddress::FUNCTION: |
|
1174 m_DataSaver.AddString( " " ); |
|
1175 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true ); |
|
1176 m_DataSaver.AddString( " (" ); |
|
1177 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true ); |
|
1178 m_DataSaver.AddString( ":" ); |
|
1179 if( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 ) |
|
1180 m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true ); |
|
1181 else |
|
1182 m_DataSaver.AddString( "???", true ); |
|
1183 m_DataSaver.AddString( ")" ); |
|
1184 m_DataSaver.AddLineToLast(); |
|
1185 break; |
|
1186 case CATMemoryAddress::EXACT: |
|
1187 m_DataSaver.AddString( " " ); |
|
1188 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true ); |
|
1189 m_DataSaver.AddString( " (" ); |
|
1190 m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true ); |
|
1191 m_DataSaver.AddString( ":" ); |
|
1192 if( m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 ) |
|
1193 m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true ); |
|
1194 else |
|
1195 m_DataSaver.AddString( "???", true ); |
|
1196 m_DataSaver.AddString( ")" ); |
|
1197 m_DataSaver.AddLineToLast(); |
|
1198 break; |
|
1199 #endif |
|
1200 } // End switch |
|
1201 // On logging level 1 we only print one located code line |
|
1202 #ifndef ADDR2LINE |
|
1203 if ( m_iLogLevel == 1 && ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT || |
|
1204 m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::FUNCTION ) ) |
|
1205 break; |
|
1206 #endif |
|
1207 #ifdef ADDR2LINE |
|
1208 if ( m_iLogLevel == 1 && m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT ) |
|
1209 break; |
|
1210 #endif |
|
1211 } // End call stack items loop |
|
1212 } |
|
1213 |
|
1214 // ----------------------------------------------------------------------------- |
|
1215 // CATDatParser::SetInputFile |
|
1216 // ----------------------------------------------------------------------------- |
|
1217 void CATDatParser::SetInputFile(const string& sInputFile) |
|
1218 { |
|
1219 LOG_FUNC_ENTRY("CATDatParser::SetInputFile"); |
|
1220 m_sInputFile = sInputFile; |
|
1221 } |
|
1222 |
|
1223 // ----------------------------------------------------------------------------- |
|
1224 // CATDatParser::SetOutputFile |
|
1225 // ----------------------------------------------------------------------------- |
|
1226 void CATDatParser::SetOutputFile(const string& sOutpuFile) |
|
1227 { |
|
1228 LOG_FUNC_ENTRY("CATDatParser::SetOutputFile"); |
|
1229 m_sOutputFile = sOutpuFile; |
|
1230 } |
|
1231 |
|
1232 // ----------------------------------------------------------------------------- |
|
1233 // CATDatParser::SetRomSymbolFiles |
|
1234 // ----------------------------------------------------------------------------- |
|
1235 void CATDatParser::SetRomSymbolFiles(const vector<string>& vRomSymbolFiles) |
|
1236 { |
|
1237 LOG_FUNC_ENTRY("CATDatParser::SetRomSymbolFiles"); |
|
1238 m_vRomSymbolFiles = vRomSymbolFiles; |
|
1239 } |
|
1240 |
|
1241 // ----------------------------------------------------------------------------- |
|
1242 // CATDatParser::SetLogLevel |
|
1243 // ----------------------------------------------------------------------------- |
|
1244 void CATDatParser::SetLogLevel(int iLogLevel) |
|
1245 { |
|
1246 LOG_FUNC_ENTRY("CATDatParser::SetLogLevel"); |
|
1247 m_iLogLevel = iLogLevel; |
|
1248 } |
|
1249 |
|
1250 // ----------------------------------------------------------------------------- |
|
1251 // CATDatParser::GetLogLevel |
|
1252 // ----------------------------------------------------------------------------- |
|
1253 int CATDatParser::GetLogLevel() const |
|
1254 { |
|
1255 LOG_LOW_FUNC_ENTRY("CATDatParser::GetLogLevel"); |
|
1256 return m_iLogLevel; |
|
1257 } |
|
1258 |
|
1259 // ----------------------------------------------------------------------------- |
|
1260 // CATDatParser::CleanMemoryAddresses |
|
1261 // ----------------------------------------------------------------------------- |
|
1262 void CATDatParser::CleanMemoryAddresses() |
|
1263 { |
|
1264 LOG_LOW_FUNC_ENTRY("CATDatParser::CleanMemoryAddresses"); |
|
1265 // Cleanup memory addressses. |
|
1266 for( vector<CATMemoryAddress*>::iterator it = m_vMemoryAddress.begin(); it != m_vMemoryAddress.end(); it++ ) |
|
1267 { |
|
1268 delete *it; |
|
1269 } |
|
1270 m_vMemoryAddress.clear(); |
|
1271 } |
|
1272 |
|
1273 // ----------------------------------------------------------------------------- |
|
1274 // CATDatParser::ConvertTimeToLocalTime |
|
1275 // ----------------------------------------------------------------------------- |
|
1276 string CATDatParser::ConvertTimeToLocalTime( string sInputTime ) |
|
1277 { |
|
1278 LOG_LOW_FUNC_ENTRY("CATDatParser::ConvertTimeToLocalTime"); |
|
1279 //Is process end abnormal? |
|
1280 if( sInputTime.compare( LABEL_ABNORMAL ) == 0 ) |
|
1281 { |
|
1282 return string( AT_ANALYZE_ABNORMAL_EXIT ); |
|
1283 } |
|
1284 else |
|
1285 // Check that input time is at least 32-bit |
|
1286 if( sInputTime.length() <= 8 ) |
|
1287 { |
|
1288 sInputTime.clear(); |
|
1289 return sInputTime; |
|
1290 } |
|
1291 |
|
1292 string sTemp = sInputTime; |
|
1293 const char* pTemp = sTemp.c_str(); |
|
1294 |
|
1295 // Are all characters hex |
|
1296 for( unsigned int i = 0 ; i < sTemp.size() ; i++ ) |
|
1297 { |
|
1298 if( !IsHexCharacter( (pTemp + i) ) ) |
|
1299 { |
|
1300 return sInputTime; |
|
1301 } |
|
1302 } |
|
1303 |
|
1304 // Get LSB bits |
|
1305 string sLsb; |
|
1306 sLsb.append( sInputTime.substr( sInputTime.length()-8, sInputTime.length() ) ); |
|
1307 unsigned int iLsbTime = (unsigned int)_httoi( sLsb.c_str() ); |
|
1308 |
|
1309 // Get MSB bits |
|
1310 string sMsb; |
|
1311 sMsb.append( sInputTime.substr( 0, sInputTime.length()-8 ) ); |
|
1312 unsigned int iMsbTime = (unsigned int)_httoi( sMsb.c_str() ); |
|
1313 |
|
1314 // Get time in microsecods |
|
1315 long long sdf = iMsbTime * 0x100000000 + iLsbTime; |
|
1316 |
|
1317 // Get original time (starting at year 1970 ) |
|
1318 long long llOrigTime = sdf; |
|
1319 |
|
1320 // Get seconds |
|
1321 sdf = ( sdf )/1000000; |
|
1322 |
|
1323 // Check that sdf contains some time value |
|
1324 if( sdf <= 0) |
|
1325 { |
|
1326 // Error in time calculation |
|
1327 // Return empty string |
|
1328 sInputTime.clear(); |
|
1329 return sInputTime; |
|
1330 } |
|
1331 |
|
1332 // Original time after year 1970 in seconds |
|
1333 long long llOrignTimeInSeconds = sdf; |
|
1334 |
|
1335 // Calculate new time which does not include millisecods |
|
1336 long long llDiffTime = (llOrignTimeInSeconds * 1000000); |
|
1337 |
|
1338 // Calculate time difference in milliseconds |
|
1339 int llDiffTimeInMilliSecods = (int)( llOrigTime - llDiffTime )/1000; |
|
1340 |
|
1341 // Convert difference time to char |
|
1342 char cDiffInMilliSeconds[20]; |
|
1343 _itoa( llDiffTimeInMilliSecods, cDiffInMilliSeconds, 10 ); |
|
1344 |
|
1345 // Time info structure |
|
1346 struct tm *timeinfo; |
|
1347 |
|
1348 // Get local time |
|
1349 timeinfo = localtime ( (time_t*) &sdf ); |
|
1350 |
|
1351 // Create string and append memory leak time to it |
|
1352 string sTime; |
|
1353 sTime.append( asctime( timeinfo ) ); |
|
1354 |
|
1355 // Remove last char of locale time string which is \n |
|
1356 sTime.resize( (int)sTime.length()-1 ); |
|
1357 |
|
1358 // Get last space index |
|
1359 int iLastSpace = (int)sTime.find_last_of(" "); |
|
1360 |
|
1361 // If last space index is valid |
|
1362 if( iLastSpace <= (int)sTime.length() && iLastSpace > 0) |
|
1363 { |
|
1364 string sTempTime; |
|
1365 // Append first part of original time string |
|
1366 sTempTime.append( sTime.substr( 0, iLastSpace ) ); |
|
1367 |
|
1368 // Append millisecods |
|
1369 sTempTime.append( "." ); |
|
1370 sTempTime.append( cDiffInMilliSeconds ); |
|
1371 |
|
1372 // Append the rest of the original time string part |
|
1373 sTempTime.append( sTime.substr( iLastSpace, sTime.length())); |
|
1374 |
|
1375 // Clear original and append new time string which includes millisecods |
|
1376 sTime.clear(); |
|
1377 sTime.append( sTempTime ); |
|
1378 } |
|
1379 |
|
1380 // Return memory leak time |
|
1381 return sTime.c_str(); |
|
1382 } |
|
1383 |
|
1384 bool CATDatParser::CreateWinscwModule( const string& sBinaryName ) |
|
1385 { |
|
1386 LOG_FUNC_ENTRY( "CATDatParser::CreateWinscwModule" ); |
|
1387 // Is module already created? |
|
1388 for( vector<CATModule2*>::iterator it = m_pModules->begin(); it != m_pModules->end(); it++ ) |
|
1389 { |
|
1390 if ( _stricmp( sBinaryName.c_str(), (*it)->GetBinaryName().c_str() ) == 0 ) |
|
1391 return true; |
|
1392 } |
|
1393 // No create new one and set its values. |
|
1394 CATModule2* mod = new CATModule2(); |
|
1395 mod->SetTarget( RemovePathAndExt( sBinaryName, true ) ); |
|
1396 mod->SetRequestedTargetExt( GetExtension( sBinaryName ) ); |
|
1397 mod->SetReleasePath( string( "\\epoc32\\release" ) ); |
|
1398 if ( m_eBuildType == CATProject::UDEB ) |
|
1399 mod->SetFullVariantPath( string( "winscw\\udeb" ) ); |
|
1400 else |
|
1401 mod->SetFullVariantPath( string( "winscw\\urel" ) ); |
|
1402 mod->SetVariantPlatform( string( "winscw" ) ); |
|
1403 m_pModules->push_back( mod ); |
|
1404 return true; |
|
1405 } |
|
1406 |
|
1407 // ----------------------------------------------------------------------------- |
|
1408 // CATDatParser::FindModuleUsingAddress |
|
1409 // Function finds module using given address. |
|
1410 // ----------------------------------------------------------------------------- |
|
1411 int CATDatParser::FindModuleUsingAddress( unsigned long iAddress ) const |
|
1412 { |
|
1413 LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingAddress"); |
|
1414 int iRet = -1; |
|
1415 for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ ) |
|
1416 { |
|
1417 // Is address between start and end address? |
|
1418 if( iAddress > m_vDllLoadModList[i].iStartAddress && iAddress < m_vDllLoadModList[i].iEndAddress ) |
|
1419 { |
|
1420 iRet = i; |
|
1421 break; |
|
1422 } |
|
1423 } |
|
1424 return iRet; |
|
1425 } |
|
1426 |
|
1427 // ----------------------------------------------------------------------------- |
|
1428 // CATDatParser::FindModuleUsingPID |
|
1429 // Function finds module using module id. |
|
1430 // ----------------------------------------------------------------------------- |
|
1431 /* |
|
1432 int CATDatParser::FindModuleUsingPID( unsigned long iPID ) const |
|
1433 { |
|
1434 LOG_FUNC_ENTRY("CATDatParser::FindModuleUsingPID"); |
|
1435 |
|
1436 int iRet = -1; |
|
1437 |
|
1438 // Change module name characters to lowercase |
|
1439 for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ ) |
|
1440 { |
|
1441 if( m_vDllLoadModList[i].iPID == iPID ) |
|
1442 { |
|
1443 iRet = i; |
|
1444 break; |
|
1445 } |
|
1446 } |
|
1447 return iRet; |
|
1448 } |
|
1449 */ |
|
1450 // ----------------------------------------------------------------------------- |
|
1451 // CATDatParser::FindModuleUsingName |
|
1452 // Function finds module using module name. |
|
1453 // ----------------------------------------------------------------------------- |
|
1454 int CATDatParser::FindModuleUsingName( const char* pModName ) |
|
1455 { |
|
1456 LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingName"); |
|
1457 |
|
1458 // Mod name empty? |
|
1459 if( pModName == NULL || *pModName == 0 ) |
|
1460 return -1; |
|
1461 |
|
1462 int iRet = -1; |
|
1463 string sModName( pModName ); |
|
1464 // Change module name characters to lowercase |
|
1465 ChangeToLower( sModName ); |
|
1466 // Remove variant marks (dots) |
|
1467 RemoveAllAfterDotIfTwoDots( sModName); |
|
1468 for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ ) |
|
1469 { |
|
1470 string sTemp( m_vDllLoadModList[i].sModuleName ); |
|
1471 ChangeToLower( sTemp ); |
|
1472 // Remove variant marks (dots) |
|
1473 RemoveAllAfterDotIfTwoDots( sTemp ); |
|
1474 if( sTemp.find( sModName ) != string::npos ) |
|
1475 { |
|
1476 iRet = i; |
|
1477 break; |
|
1478 } |
|
1479 } |
|
1480 return iRet; |
|
1481 } |
|
1482 |
|
1483 // ----------------------------------------------------------------------------- |
|
1484 // CATDatParser::SetPrintFlag |
|
1485 // ----------------------------------------------------------------------------- |
|
1486 void CATDatParser::SetPringFlag( bool bPrintFlag ) |
|
1487 { |
|
1488 LOG_FUNC_ENTRY("CATDatParser::SetPringFlag"); |
|
1489 m_DataSaver.SetPrintFlag( bPrintFlag ); |
|
1490 } |
|
1491 // ----------------------------------------------------------------------------- |
|
1492 // CATDatParser::SetOffSet |
|
1493 // ----------------------------------------------------------------------------- |
|
1494 void CATDatParser::SetOffSet( int iOffSet ) |
|
1495 { |
|
1496 LOG_FUNC_ENTRY("CATDatParser::SetOffSet"); |
|
1497 m_iOffSet = iOffSet; |
|
1498 } |
|
1499 |
|
1500 // ----------------------------------------------------------------------------- |
|
1501 // CATDatParser::GetOffSet |
|
1502 // ----------------------------------------------------------------------------- |
|
1503 int CATDatParser::GetOffSet( ) const |
|
1504 { |
|
1505 LOG_LOW_FUNC_ENTRY("CATDatParser::GetOffSet"); |
|
1506 return m_iOffSet; |
|
1507 } |
|
1508 |
|
1509 // ----------------------------------------------------------------------------- |
|
1510 // Set project platform. |
|
1511 // ----------------------------------------------------------------------------- |
|
1512 void CATDatParser::SetProjectPlatform( const string& sPlatform ) |
|
1513 { |
|
1514 LOG_FUNC_ENTRY("CATDatParser::SetProjectPlatform"); |
|
1515 m_sProjectPlatform = sPlatform; |
|
1516 |
|
1517 // Check that platform not empty before determing platform from it. |
|
1518 if ( sPlatform.empty() ) |
|
1519 return; |
|
1520 |
|
1521 // Set functions offset in mapfiles correct (depending on platform). |
|
1522 if ( _stricmp( sPlatform.c_str(), "armv5" ) == 0 ) |
|
1523 { |
|
1524 m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_ARMV5; |
|
1525 } |
|
1526 else if ( _stricmp( sPlatform.c_str(), "winscw" ) == 0 ) |
|
1527 { |
|
1528 m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_WINSCW; |
|
1529 } |
|
1530 else if ( _stricmp( sPlatform.c_str(), "gcce" ) == 0 ) |
|
1531 { |
|
1532 m_iOffSet = FUNCTIONS_OFFSET_IN_GCCE; |
|
1533 } |
|
1534 else |
|
1535 { |
|
1536 LOG_STRING( AT_MSG << "Error, cannot set function's offset in map file, invalid platform: " << sPlatform ); |
|
1537 } |
|
1538 } |
|
1539 |
|
1540 // ----------------------------------------------------------------------------- |
|
1541 // Set projects build type. Use enumeration defined in CATProject. |
|
1542 // ----------------------------------------------------------------------------- |
|
1543 void CATDatParser::SetProjectBuildType( int eBuildType ) |
|
1544 { |
|
1545 LOG_FUNC_ENTRY("CATDatParser::SetProjectBuildType"); |
|
1546 m_eProjectBuildType = eBuildType; |
|
1547 } |
|
1548 |
|
1549 //EOF |