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