diff -r 3ff3fecb12fe -r 6a82cd05fb1e memana/analyzetoolclient/commandlineengine/internal/src/catdbghelper.cpp --- a/memana/analyzetoolclient/commandlineengine/internal/src/catdbghelper.cpp Thu Feb 11 15:52:57 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,314 +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: Windows debug api implementation for IAddressToLine interface. -* -*/ - -#include "../inc/catdbghelper.h" -#include "../inc/CATBase.h" -#include "../inc/CATMemoryAddress.h" -#include - -/** -* Notes on version number of api functions. -* 5.1 Windows XP -* 5.2 Windows Server 2003 -* 6.8 Debugging Tools for Windows 6.8 -* SymSetOptions DbgHelp.dll 5.1 or later -* SymSetSearchPath DbgHelp.dll 5.1 or later -* SymLoadModuleEx Versions 5.2 and 6.0 -* SymLoadModule64 DbgHelp.dll 5.1 or later -* SymFromAddr Versions 4.0 and 5.1 -* SymGetLineFromAddr64 DbgHelp.dll 5.1 or later -*/ - -// Wrapper class for symbol information package. -struct CSymbolInfo : public SYMBOL_INFO_PACKAGE -{ - CSymbolInfo() - { - si.SizeOfStruct = sizeof( SYMBOL_INFO ); - si.MaxNameLen = sizeof( name ); - } -}; - -// Wrapper class for line information container. -struct CLineInfo : public IMAGEHLP_LINE64 -{ - CLineInfo() - { - SizeOfStruct = sizeof( IMAGEHLP_LINE64 ); - } -}; - -CATDbgHelper::CATDbgHelper() -{ - LOG_FUNC_ENTRY("CATDbgHelper::CDbgHelper"); - // Set the some "default" base address. - m_BaseAddress = 0x2; - m_bMap = false; - m_pBinaryFile = NULL; -} - -CATDbgHelper::~CATDbgHelper() -{ - LOG_FUNC_ENTRY("CATDbgHelper::~CDbgHelper"); - // Close dbghelper only once. - if ( CDBGHELPER_OPEN ) - { - Close(); - } - if ( m_pBinaryFile ) - { - delete[] m_pBinaryFile; - m_pBinaryFile = NULL; - } -} - -bool CATDbgHelper::Open( const string& sParameter, const unsigned long iLong ) -{ - LOG_FUNC_ENTRY("CATDbgHelper::Open"); - // Verify that file exits. Version 5.1.2600.5512 of dbghelp.dll does not correctly - // return error code if missing image file. This can lead upto applicaton crash. - if ( ! CATBase::FileExists( sParameter.c_str() ) ) - { - LOG_STRING( "Missing image file: " << sParameter ); - return false; - } - - // Is it urel try read map? - if ( sParameter.find( "\\urel\\" ) != string::npos ) - { - string sMapFile = sParameter; - sMapFile.append( ".map" ); - ReadMapFile( sMapFile ); - } - - // Set base address used - m_BaseAddress = iLong + AT_VIRTUAL_OFFSET_DBGHELPER; - // Binary file (also referred as symbol). - size_t length = sParameter.length(); - if ( length == 0 ) - { - LOG_STRING("DbgHelp:Invalid binary parameter."); - return false; - } - - char* pChar = new char[ sParameter.length()+1 ]; - strcpy( pChar, sParameter.c_str() ); - // Have to be casted to PSTR before using dbg api. Even tho its typedef same. - // This will avoid access violations bug. - // Note pChar is not deleted because its the member pointer just casted its - // memory allocation freed in destructor. - if ( m_pBinaryFile ) - delete[] m_pBinaryFile; - - m_pBinaryFile = (PSTR) pChar; - - // Initialize dbghelper if not done only once. - if ( ! CDBGHELPER_OPEN ) - { - // Set symbol options - SymSetOptions( SYMOPT_LOAD_LINES | SYMOPT_DEBUG | SYMOPT_UNDNAME | SYMOPT_LOAD_ANYTHING ); - if ( !SymInitialize( GetCurrentProcess(), NULL, TRUE ) ) - { - LOG_STRING("DbgHelp:Error initializing dbghelper " << (int) GetLastError()); - return false; - } - LOG_STRING("DbgHelp:dbghelper opened."); - CDBGHELPER_OPEN = true; - } - - // Set symbol search path. - if ( !SymSetSearchPath( GetCurrentProcess(), NULL ) ) - { - LOG_STRING("DbgHelp:Error setting symbol search path " << (int) GetLastError()); - return false; - } - - // Load module. - DWORD64 ret; - ret = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL ); // 5.1 api version. - if ( ret != m_BaseAddress && ret != 0) - { - LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError()); - return false; - } - CDBGHELPER_CLIENTS++; - return true; -} - -string CATDbgHelper::GetError( void ) -{ - LOG_FUNC_ENTRY("CATDbgHelper::GetError"); - return string("not implemented."); -} - -bool CATDbgHelper::Close( void ) -{ - LOG_FUNC_ENTRY("CATDbgHelper::Close"); - if ( ! SymUnloadModule64( GetCurrentProcess(), m_BaseAddress ) ) - { - LOG_STRING("Dbghelp:Module unload failed."); - } - CDBGHELPER_CLIENTS--; - if ( CDBGHELPER_OPEN && CDBGHELPER_CLIENTS == 0) - { - // Cleanup dbghelper. - if ( ! SymCleanup( GetCurrentProcess() ) ) - { - LOG_STRING("dbghelper cleanup failed."); - return false; - } - LOG_STRING("dbghelper closed."); - // Set state not opened. - CDBGHELPER_OPEN = false; - } - return true; -} - -bool CATDbgHelper::AddressToLine( CATMemoryAddress* result ) -{ - LOG_FUNC_ENTRY("CATDbgHelper::AddressToLine"); - - // Set state out of range - result->SetAddressToLineState( CATMemoryAddress::OUT_OF_RANGE ); - - // check that dbghelper has been initialized successfully. - if ( ! CDBGHELPER_OPEN ) - return false; - - // Check has binary been moved, if so unload and load to new base address. - if ( result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER != m_BaseAddress ) - { - // Unload. - if ( SymUnloadModule64( GetCurrentProcess(), m_BaseAddress ) ) - { - // Set new base address. - m_BaseAddress = result->GetModuleStartAddress() + AT_VIRTUAL_OFFSET_DBGHELPER; - // (Re)load. - DWORD64 loading = SymLoadModule64( GetCurrentProcess(), NULL, m_pBinaryFile, NULL, m_BaseAddress, NULL ); - if ( loading != m_BaseAddress && loading != 0) - { - LOG_STRING("Dbghelp:Module load failed " << (int) GetLastError()); - return false; - } - } - else - LOG_STRING("Dbghelp:Module unload failed " << (int) GetLastError() ); - } - // Address to find (offset+given address). - unsigned long iAddressToFind = result->GetAddress() + AT_VIRTUAL_OFFSET_DBGHELPER; - // Displacements of line/symbol information. - DWORD64 displacementSymbol; - DWORD displacementLine; - // Structure to get symbol information. - CSymbolInfo symbol; - // Structure to get line information. - CLineInfo line; - // Find Symbol for given address - if( ! SymFromAddr( GetCurrentProcess(), iAddressToFind , &displacementSymbol, &symbol.si ) ) - { - LOG_STRING("Failed to find symbol information for given line."); - return AddressToFunction( result ); - } - // Find line information - if( ! SymGetLineFromAddr64( GetCurrentProcess(), iAddressToFind, &displacementLine, &line ) ) - { - // If it fails get symbol line information - LOG_STRING("Dbghelp:Failed to find line information for address, trying for symbol of address."); - if( ! SymGetLineFromAddr64( GetCurrentProcess(), symbol.si.Address, &displacementLine, &line ) ) - { - LOG_STRING("Dbghelp:Failed to find line information for symbol address."); - return AddressToFunction( result ); - } - } - // Set the results. - result->SetFileName( string( line.FileName ) ); - result->SetFunctionName( string( symbol.si.Name ) ); - result->SetExactLineNumber( (int) line.LineNumber ); - result->SetAddressToLineState( CATMemoryAddress::EXACT ); - // Return. - return true; -} - -bool CATDbgHelper::AddressToFunction( CATMemoryAddress* result ) -{ - LOG_FUNC_ENTRY("CATDbgHelper::AddressToFunction"); - bool bFound = false; - // If map file read use it and return. - if ( m_bMap ) - { - ULONG uCountedA = result->GetOffSetFromModuleStart(); - for ( vector::iterator it = m_vMapFileFuncList.begin() ; it != m_vMapFileFuncList.end() ; it++ ) - { - // Check is this the symbol where address is. - unsigned long iStart = it->iAddress; - unsigned long iEnd = it->iAddress + it->iFuncLength; - if ( uCountedA >= iStart - && uCountedA < iEnd ) - { - result->SetAddressToLineState( CATMemoryAddress::SYMBOL ); - result->SetFunctionName( it->sMangledName ); - bFound = true; - break; - } - } - } - return bFound; -} - -void CATDbgHelper::ReadMapFile( const string sMapFileName ) -{ - LOG_FUNC_ENTRY("CATDbgHelper::ReadMapFile"); - try { - ifstream in( sMapFileName.c_str() ); - if ( ! in.good() ) - { - in.close(); - return; - } - char cLine[MAX_LINE_LENGTH]; - do { - in.getline( cLine, MAX_LINE_LENGTH ); - // Search pattern for 'image ro' symbols is ".text" - string sLine( cLine ); - if ( sLine.find( ".text" ) != string::npos ) - { - MAP_FUNC_INFO symbol; - // Pickup symbol attributes - // Address - string sAddress = CATBase::GetStringUntilNextSpace( sLine, true ); - symbol.iAddress = CATBase::_httoi( sAddress.c_str() ); - // Lenght - string sLength = CATBase::GetStringUntilNextSpace( sLine, true ); - symbol.iFuncLength = CATBase::_httoi( sLength.c_str() ); - // Name - size_t iStart = sLine.find_first_of( '(' ); - size_t iEnd = sLine.find_last_of( ')' ); - if ( iStart != string::npos && iEnd != string::npos ) - { - symbol.sMangledName = sLine.substr( iStart+1, iEnd-iStart-1 ); - // Add symbol to vector - m_vMapFileFuncList.push_back( symbol ); - } - } - } while ( in.good() ); - in.close(); - m_bMap = true; - } catch (...) { - m_bMap = false; - LOG_STRING("DbgHelp: Error reading map file."); - } -} \ No newline at end of file