diff -r 3ff3fecb12fe -r 6a82cd05fb1e memana/analyzetoolclient/commandlineengine/internal/src/CATDatParser.cpp --- a/memana/analyzetoolclient/commandlineengine/internal/src/CATDatParser.cpp Thu Feb 11 15:52:57 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1575 +0,0 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: Class responsible to parse data files -* -*/ - - -#include "../inc/CATDatParser.h" -#include "../inc/CATProject.h" -#include "../inc/CATModule2.h" -#include "../inc/CATMemoryAddress.h" -#include "../inc/catromsymbol.h" - -// ----------------------------------------------------------------------------- -// CATDatParser::CATDatParser -// Constructor only for testing! -// (No module vector defined so no locating codelines / call stacks) -// ----------------------------------------------------------------------------- -CATDatParser::CATDatParser() -{ - LOG_FUNC_ENTRY("CATDatParser::CATDatParser"); - Construct(); -} - -// ----------------------------------------------------------------------------- -// CATDatParser::CATDatParser -// Constructor -// ----------------------------------------------------------------------------- -CATDatParser::CATDatParser(vector* pModules ) -{ - LOG_FUNC_ENTRY("CATDatParser::CATDatParser"); - Construct(); - m_pModules = pModules; -} - -// ----------------------------------------------------------------------------- -// CATDatParser::Construct -// "Real" constructor -// ----------------------------------------------------------------------------- -void CATDatParser::Construct() -{ - LOG_FUNC_ENTRY("CATDatParser::Construct"); - - m_iDataVersion = 1; // Default version of data. - m_bDllLoadFound = false; - m_bProcessStartFound = false; - m_bSubtestOnGoing = false; - - m_DataSaver.InitXML(); - - m_eBuildType = -2; - m_eProcess_state = not_started; - m_eProjectBuildType = -1; - - m_iCurrentProcessId = 0; - m_iLeakNumber = 0; - m_iLogLevel = 3; - m_iOffSet = 0; - - m_iPinPointedLeaks = 0; - m_iPinPointedSubTestLeaks = 0; - m_iSubtestStartHandleCount = 0; - m_iSuccesfullRuns = 0; - m_iTotalNumberOfLeaks = 0; - m_iTotalRuns = 0; - - m_pRomSymbol = 0; - m_pModules = 0; - - m_sCurrentProcessName = ""; - m_sInputFile = ""; - m_sInputFileTemp = ""; - m_sOutputFile = ""; - m_sProjectPlatform = ""; - m_vRomSymbolFiles.clear(); - m_vDllLoadModList.clear(); - m_vDllLoadModListSubTest.clear(); - m_vHandleLeaks.clear(); - m_vMemoryAddress.clear(); -} - -// ----------------------------------------------------------------------------- -// CATDatParser::~CATDatParser -// Destructor -// ----------------------------------------------------------------------------- -CATDatParser::~CATDatParser() -{ - LOG_FUNC_ENTRY("CATDatParser::~CATDatParser"); - - if ( m_In.is_open() ) - m_In.close(); - // Delete temporary input file if any - if ( !m_sInputFileTemp.empty() ) - { - if ( FileExists( m_sInputFileTemp.c_str() ) ) - FileDelete( m_sInputFileTemp, false ); - } - // Clean memory addresses if any - CleanMemoryAddresses(); - // Delete rom symbol. - if ( m_pRomSymbol ) - { - delete m_pRomSymbol; - m_pRomSymbol = NULL; - } -} - -// ----------------------------------------------------------------------------- -// CATDatParser::Analyze -// Analyze given data file -// ----------------------------------------------------------------------------- -int CATDatParser::Analyze() -{ - LOG_FUNC_ENTRY("CATDatParser::Analyze"); - // Return if input file not set - if ( m_sInputFile.empty() ) - return AT_RETURN_CODE::INVALID_DATA_FILE; - // If open close first - if ( m_In.is_open() ) - m_In.close(); - // Open file - m_In.open( m_sInputFile.c_str() ); - if ( ! m_In.good() ) - return AT_RETURN_CODE::INVALID_DATA_FILE; - try { - // If rom symbol file specified. - if ( ! m_vRomSymbolFiles.empty() ) - { - // Create new rom symbol file "parser". - m_pRomSymbol = new CATRomSymbol(); - m_pRomSymbol->m_bShowProgressMessages = true; - // Set symbol files. - if ( ! m_pRomSymbol->SetSymbols( m_vRomSymbolFiles ) ) - { - cout << AT_MSG << "Rom/Rofs symbols error: " << m_pRomSymbol->GetError() << endl; - // If file open fails we delete it and will not use it. - delete m_pRomSymbol; - m_pRomSymbol = NULL; - cout << AT_MSG << "Analyze aborted." << endl; - return AT_RETURN_CODE::SYMBOL_FILE_ERROR; - } - } - // Return code - int iRet = 0; - // Clear variables - ClearParsingVariables(); - // If output defined disable printing - if ( ! m_sOutputFile.empty() ) - m_DataSaver.SetPrintFlag( false ); - // Header - Header(); - // Parsing - iRet = Parse(); - // Footer - if ( iRet == AT_RETURN_CODE::OK ) - Footer(); - // If output defined save xml - if ( ! m_sOutputFile.empty() ) - m_DataSaver.SaveLinesToFile( m_sOutputFile.c_str(), XML_DATA ); - // Return - return iRet; - } catch ( int i ) - { - cout << AT_MSG << "Error, Analyze failed. : " << i << endl; - return AT_RETURN_CODE::UNHANDLED_EXCEPTION; - } -} -// ----------------------------------------------------------------------------- -// CATDatParser::Header -// Print header of report -// ----------------------------------------------------------------------------- -void CATDatParser::Header() -{ - LOG_FUNC_ENTRY("CATDatParser::Header"); - // Analyze report header - m_DataSaver.AddString( "Atool.exe v." ); - m_DataSaver.AddString( ATOOL_VERSION ); - m_DataSaver.AddString( "\n" ); - m_DataSaver.AddString( "Analyzing memory leaks..." ); - m_DataSaver.AddLineToLast(); -} - -// ----------------------------------------------------------------------------- -// CATDatParser::Footer -// Print footer of report -// ----------------------------------------------------------------------------- -void CATDatParser::Footer() -{ - LOG_FUNC_ENTRY("CATDatParser::Footer"); - m_DataSaver.AddString( "\nTotal Runs: " ); - m_DataSaver.AddInteger( m_iTotalRuns ); - m_DataSaver.AddLineToLast(); - - int iFailedRuns = m_iTotalRuns - m_iSuccesfullRuns; - m_DataSaver.AddString( "Failed Runs: " ); - m_DataSaver.AddInteger( iFailedRuns ); - m_DataSaver.AddLineToLast(); - - char cTemp[128]; - string sResult( itoa( m_iTotalRuns, cTemp, 10 ) ); - sResult.append( ";" ); - sResult.append( itoa( iFailedRuns, cTemp, 10 ) ); - sResult.append( ";" ); - - m_DataSaver.SaveXML( sResult, RESULT ); -} - -// ----------------------------------------------------------------------------- -// CATDatParser::ClearParsingVariables -// Clear/Reset all member variables related to parsing data file -// ----------------------------------------------------------------------------- -void CATDatParser::ClearParsingVariables() -{ - LOG_FUNC_ENTRY("CATDatParser::ClearParsingVariables"); - // Clear variables related to analyze - m_eProcess_state = PROCESS_STATE::not_started; - m_bProcessStartFound = false; - m_bDllLoadFound = false; - m_iTotalNumberOfLeaks = 0; - m_iPinPointedLeaks = 0; - m_iLeakNumber = 0; - m_iTotalRuns = 0; - m_iSuccesfullRuns = 0; - m_bSubtestOnGoing = false; - m_iSubtestStartHandleCount = 0; - CleanMemoryAddresses(); -} - -// ----------------------------------------------------------------------------- -// CATDatParser::Parse -// Parses data file. Note! header and footer of the report are done in -// separate functions. -// ----------------------------------------------------------------------------- -int CATDatParser::Parse() -{ - LOG_FUNC_ENTRY("CATDatParser::Parse"); - // Read all lines - char cLine[MAX_LINE_LENGTH]; - do - { - string sLine; - try { - m_In.getline( cLine, MAX_LINE_LENGTH ); - sLine = cLine ; - } catch(...) - { - LOG_STRING( AT_MSG << "Unexpected error, reading data file." ); - continue; - } - if( sLine.find( LABEL_DATA_FILE_VERSION ) != string::npos ) - { - // Check data file version - if( sLine.find( AT_DATA_FILE_VERSION ) == string::npos ) - { - return AT_RETURN_CODE::WRONG_DATA_FILE_VERSION; - } - } - else if( sLine.find( LABEL_PROCESS_START ) != string::npos ) - { - if ( ! ParseProcessStart( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_DLL_LOAD ) != string::npos ) - { - if ( ! ParseDllLoad( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_DLL_UNLOAD ) != string::npos ) - { - if ( ! ParseDllUnload( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_MEM_LEAK ) != string::npos) - { - if ( ! ParseMemLeak( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_PROCESS_END ) != string::npos ) - { - if ( ! ParseProcessEnd( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_ERROR_OCCURED ) != string::npos ) - { - if ( ! ParseErrorOccured( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_HANDLE_LEAK ) != string::npos ) - { - if ( ! ParseHandleLeak( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_TEST_START ) != string::npos ) - { - if ( ! ParseTestStart( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_TEST_END ) != string::npos ) - { - if ( ! ParseTestEnd( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - else if( sLine.find( LABEL_LOGGING_CANCELLED ) != string::npos ) - { - if ( ! ParseLoggingCancelled( sLine ) ) - return AT_RETURN_CODE::ANALYZE_ERROR; - } - } - while( m_In.good() ); - // Message of failed run if process start was last line in data. - if ( m_eProcess_state == PROCESS_STATE::ongoing ) - { - m_DataSaver.AddString( "Test run failed.\n" ); - m_DataSaver.AddLineToLast(); - } - return AT_RETURN_CODE::OK; -} - -// ----------------------------------------------------------------------------- -// CATDatParser::ParseProcessStart -// ----------------------------------------------------------------------------- -bool CATDatParser::ParseProcessStart( string& sLine) -{ - LOG_FUNC_ENTRY("CATDatParser::ParseProcessStart"); - if ( m_eProcess_state == PROCESS_STATE::ongoing ) - { - m_DataSaver.AddString( "Test run failed.\n" ); - m_DataSaver.AddLineToLast(); - } - m_eProcess_state = PROCESS_STATE::ongoing; - m_bProcessStartFound = true; - - // Clear handle leaks - m_vHandleLeaks.clear(); - // Increment runs - m_iTotalRuns++; - // Clean leak count - m_iTotalNumberOfLeaks = 0; - // Clean pin pointed leaks count. - m_iPinPointedLeaks = 0; - // Clean leak number - m_iLeakNumber = 0; - - // Clean loaded mods - m_vDllLoadModList.clear(); - m_vDllLoadModListSubTest.clear(); - - // Skip text PROCESS_START - GetStringUntilNextSpace( sLine ); - // Get process name - m_sCurrentProcessName = GetStringUntilNextSpace( sLine ); - // Get Pid - string sPid = GetStringUntilNextSpace( sLine ); - m_iCurrentProcessId = _httoi( sPid.c_str() ); - - // Header for process tart - m_DataSaver.AddString( "\n--------------------------------\n" ); - m_DataSaver.AddString( "Test Run start (" ); - m_DataSaver.AddString( m_sCurrentProcessName.c_str() ); - m_DataSaver.AddString( "): " ); - - // Get start time - string sTime = GetStringUntilNextSpace( sLine ); - sTime = ConvertTimeToLocalTime( sTime ); - m_DataSaver.AddString( sTime.c_str() ); - - // Create data for xml - string sData( sTime ); - sData.append( ";" ); - - // Build mode UDEB/UREL. - string sBuildType = GetStringUntilNextSpace( sLine ); - - m_DataSaver.AddString( " Build target: " ); - if( sBuildType.compare( "0" ) == 0 ) - { - m_eBuildType = CATProject::UREL; - } - else if( sBuildType.compare( "1" ) == 0 ) - { - m_eBuildType = CATProject::UDEB; - } - m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() ); - - // Version. - string sVersion = GetStringUntilNextSpace( sLine ); - unsigned int iVer = 0; - if ( hexToDec( sVersion, iVer ) && iVer != 0 ) - m_iDataVersion = iVer; - - // End line in data. - m_DataSaver.AddLineToLast(); - - // xml - sData.append( CATProject::GetBuildTypeString( m_eBuildType ) ); - sData.append( ";" ); - sData.append( m_sCurrentProcessName ); - m_DataSaver.SaveXML( sData, RUN ); - - // If projects platform defined check that it is same in data. (future feature). - if ( ! m_sProjectPlatform.empty() ) - { - // If platform info is added to data file do check here. - } - // If projects build type defined check that it is same in data. - if ( m_eProjectBuildType != -1 ) - { - if ( m_eBuildType != m_eProjectBuildType ) - { - string sError(AT_MSG); - sError.append( "Error, analyzed data has build type of " ); - sError.append( CATProject::GetBuildTypeString( m_eBuildType ) ); - sError.append( " and project has build type " ); - sError.append( CATProject::GetBuildTypeString( m_eProjectBuildType ) ); - sError.append( ". Pinpointed code lines are not valid." ); - m_DataSaver.AddString( sError.c_str(), false ); - m_DataSaver.AddLineToLast(); - } - } - return true; -} - -// ----------------------------------------------------------------------------- -// CATDatParser::ParseProcessEnd -// ----------------------------------------------------------------------------- -bool CATDatParser::ParseProcessEnd( string& sLine ) -{ - LOG_FUNC_ENTRY("CATDatParser::ParseProcessEnd"); - GetStringUntilNextSpace( sLine ); - - // Get process id - string sProcessID = GetStringUntilNextSpace( sLine ); - unsigned long iProcessID = _httoi( sProcessID.c_str() ); - - // Get time - string sTime = GetStringUntilNextSpace( sLine ); - - // Convert leak time - sTime = ConvertTimeToLocalTime( sTime ); - - // Process started? - if( iProcessID == m_iCurrentProcessId ) - { - m_iSuccesfullRuns++; - m_DataSaver.AddLineToLast(); - m_DataSaver.AddString( "Test Run end (" ); - m_DataSaver.AddString( m_sCurrentProcessName.c_str() ); - m_DataSaver.AddString( "): " ); - m_DataSaver.AddString( sTime.c_str() ); - m_DataSaver.AddLineToLast(); - m_DataSaver.AddString( "Build target: " ); - m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() ); - m_DataSaver.AddLineToLast(); - - m_eProcess_state = PROCESS_STATE::stopped; - // Number of leaks - if ( m_iLogLevel == 1 || m_iLogLevel == 2 ) - { - if ( m_iPinPointedLeaks > 0 ) - { - m_DataSaver.AddInteger( m_iPinPointedLeaks ); - m_DataSaver.AddString( " number of pinpointed memory leak(s)." ); - m_DataSaver.AddLineToLast(); - } - m_DataSaver.AddInteger( m_iLeakNumber ); - m_DataSaver.AddString( " total number of memory leak(s)." ); - m_DataSaver.AddLineToLast(); - } - else - { - m_DataSaver.AddInteger( m_iTotalNumberOfLeaks ); - m_DataSaver.AddString( " memory leak(s) found." ); - m_DataSaver.AddLineToLast(); - } - - // xml - char cTemp[128]; - m_DataSaver.SaveXML( itoa( m_iTotalNumberOfLeaks, cTemp, 10 ) , MEM_LEAKS ); - - // Print all modules which have leaks - for( size_t i = 0 ; i < m_vDllLoadModList.size() ; i++ ) - { - if( m_vDllLoadModList.at(i).iLeaks > 0 ) - { - m_DataSaver.AddInteger( m_vDllLoadModList.at(i).iLeaks ); - m_DataSaver.AddString( " memory leak(s) in module: " ); - m_DataSaver.AddString( m_vDllLoadModList.at(i).sModuleName.c_str() ); - m_DataSaver.AddLineToLast(); - - // xml - string sModuleNameAndLeaks( m_vDllLoadModList[i].sModuleName ); - sModuleNameAndLeaks.append(";"); - sModuleNameAndLeaks.append( itoa( m_vDllLoadModList[i].iLeaks, cTemp, 10 ) ); - m_DataSaver.SaveXML( sModuleNameAndLeaks , MEM_LEAK_MODULE ); - } - } - - if ( m_vHandleLeaks.size() > 0 ) - { - // We have handle leaks - bool bHandLeaksFound = false; - int iTotalNrOfLeaks = 0; - // Print handle leaks - for( size_t i = 0 ; i < m_vHandleLeaks.size() ; i++ ) - { - string sTempHandleLeak( m_vHandleLeaks[i] ); - // Name. - string sHandleLeakModule( GetStringUntilNextSpace( sTempHandleLeak ) ); - // Count. - string sNrOfLeaks( GetStringUntilNextSpace(sTempHandleLeak) ); - unsigned long iNrOfLeaks = _httoi( sNrOfLeaks.c_str() ); - iTotalNrOfLeaks += iNrOfLeaks; - if( iNrOfLeaks ) - { - if( !bHandLeaksFound ) - { - m_DataSaver.SaveXML( sNrOfLeaks , HANDLE_LEAKS ); - } - bHandLeaksFound = true; - m_DataSaver.AddInteger( iNrOfLeaks ); - // Just print out how many leaks found. - // Because its always unknown. - m_DataSaver.AddString( " handle leak(s) found." ); - m_DataSaver.AddLineToLast(); - - // xml - string sXMLInfo( sHandleLeakModule ); - sXMLInfo.append( ";" ); sXMLInfo.append( sNrOfLeaks ); - m_DataSaver.SaveXML( sXMLInfo , HANDLE_LEAK_MODULE ); - } - } - // Update number if handle leaks - m_DataSaver.SaveXML( itoa( iTotalNrOfLeaks, cTemp, 10 ) , HANDLE_LEAKS ); - if( !bHandLeaksFound ) - { - //m_DataSaver.AddLineToLast(); - m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS ); - m_DataSaver.AddLineToLast(); - } - } - else - { - // No handle leaks - m_DataSaver.AddLineToLast(); - m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS ); - m_DataSaver.AddLineToLast(); - } - - // Process end to xml - m_DataSaver.SaveXML( sTime, RUN_END ); - // Reset current process - m_iCurrentProcessId = 0; - } - - // If no dll load or process start found - if ( ! m_bProcessStartFound || !m_bDllLoadFound ) - { - m_DataSaver.AddLineToLast(); - m_DataSaver.AddString( AT_ANALYZE_INSUFFICIENT_LOGGING_DATA ); - m_DataSaver.AddLineToLast(); - } - - return true; -} - -// ----------------------------------------------------------------------------- -// CATDatParser::ParseDllLoad -// ----------------------------------------------------------------------------- -bool CATDatParser::ParseDllLoad( string& sLine ) -{ - LOG_FUNC_ENTRY("CATDatParser::ParseDllLoad"); - //DLL_LOAD