| //===-- MICmnLLDBDebugSessionInfo.cpp ---------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| //++ |
| // File: MICmnLLDBDebugSessionInfo.cpp |
| // |
| // Overview: CMICmnLLDBDebugSessionInfo implementation. |
| // |
| // Environment: Compilers: Visual C++ 12. |
| // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 |
| // Libraries: See MIReadmetxt. |
| // |
| // Copyright: None. |
| //-- |
| |
| // Third party headers: |
| #include <lldb/API/SBThread.h> |
| #ifdef _WIN32 |
| #include <io.h> // For the ::_access() |
| #else |
| #include <unistd.h> // For the ::access() |
| #endif // _WIN32 |
| #include <lldb/API/SBBreakpointLocation.h> |
| |
| // In-house headers: |
| #include "MICmnLLDBDebugSessionInfo.h" |
| #include "MICmnLLDBDebugger.h" |
| #include "MICmnResources.h" |
| #include "MICmnMIResultRecord.h" |
| #include "MICmnMIValueConst.h" |
| #include "MICmnMIValueList.h" |
| #include "MICmnMIValueTuple.h" |
| #include "MICmdData.h" |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmnLLDBDebugSessionInfo constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo( void ) |
| : m_rLldbDebugger( CMICmnLLDBDebugger::Instance().GetTheDebugger() ) |
| , m_rLlldbListener( CMICmnLLDBDebugger::Instance().GetTheListener() ) |
| , m_nBrkPointCntMax( INT32_MAX ) |
| , m_currentSelectedThread( LLDB_INVALID_THREAD_ID ) |
| , m_constStrSharedDataKeyWkDir( "Working Directory" ) |
| , m_constStrSharedDataSolibPath( "Solib Path" ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmnLLDBDebugSessionInfo destructor. |
| // Type: Overridable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmnLLDBDebugSessionInfo::~CMICmnLLDBDebugSessionInfo( void ) |
| { |
| Shutdown(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Initialize resources for *this object. |
| // Type: Method. |
| // Args: None. |
| // Return: MIstatus::success - Functionality succeeded. |
| // MIstatus::failure - Functionality failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::Initialize( void ) |
| { |
| m_clientUsageRefCnt++; |
| |
| if( m_bInitialized ) |
| return MIstatus::success; |
| |
| m_currentSelectedThread = LLDB_INVALID_THREAD_ID; |
| CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero(); |
| |
| m_bInitialized = MIstatus::success; |
| |
| return m_bInitialized; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Release resources for *this object. |
| // Type: Method. |
| // Args: None. |
| // Return: MIstatus::success - Functionality succeeded. |
| // MIstatus::failure - Functionality failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::Shutdown( void ) |
| { |
| if( --m_clientUsageRefCnt > 0 ) |
| return MIstatus::success; |
| |
| if( !m_bInitialized ) |
| return MIstatus::success; |
| |
| bool bOk = MIstatus::success; |
| CMIUtilString errMsg; |
| |
| // Tidy up |
| bOk = SharedDataDestroy(); |
| if( !bOk ) |
| { |
| errMsg = CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE ) ); |
| errMsg += "\n"; |
| } |
| m_vecActiveThreadId.clear(); |
| CMICmnLLDBDebugSessionInfoVarObj::VarObjClear(); |
| |
| m_bInitialized = false; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Command instances can create and share data between other instances of commands. |
| // Data can also be assigned by a command and retrieved by LLDB event handler. |
| // This function takes down those resources build up over the use of the commands. |
| // This function should be called when the creation and running of command has |
| // stopped i.e. application shutdown. |
| // Type: Method. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::SharedDataDestroy( void ) |
| { |
| m_mapIdToSessionData.Clear(); |
| m_vecVarObj.clear(); |
| m_mapBrkPtIdToBrkPtInfo.clear(); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Record information about a LLDB break point so that is can be recalled in other |
| // commands or LLDB event handling functions. |
| // Type: Method. |
| // Args: vBrkPtId - (R) LLDB break point ID. |
| // vrBrkPtInfo - (R) Break point information object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfo( const MIuint vnBrkPtId, const SBrkPtInfo & vrBrkPtInfo ) |
| { |
| MapPairBrkPtIdToBrkPtInfo_t pr( vnBrkPtId, vrBrkPtInfo ); |
| m_mapBrkPtIdToBrkPtInfo.insert( pr ); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Retrieve information about a LLDB break point previous recorded either by |
| // commands or LLDB event handling functions. |
| // Type: Method. |
| // Args: vBrkPtId - (R) LLDB break point ID. |
| // vrwBrkPtInfo - (W) Break point information object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoGet( const MIuint vnBrkPtId, SBrkPtInfo & vrwBrkPtInfo ) const |
| { |
| const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId ); |
| if( it != m_mapBrkPtIdToBrkPtInfo.end() ) |
| { |
| vrwBrkPtInfo = (*it).second; |
| return MIstatus::success; |
| } |
| |
| return MIstatus::failure; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Delete information about a specific LLDB break point object. This function |
| // should be called when a LLDB break point is deleted. |
| // Type: Method. |
| // Args: vBrkPtId - (R) LLDB break point ID. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete( const MIuint vnBrkPtId ) |
| { |
| const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId ); |
| if( it != m_mapBrkPtIdToBrkPtInfo.end() ) |
| { |
| m_mapBrkPtIdToBrkPtInfo.erase( it ); |
| return MIstatus::success; |
| } |
| |
| return MIstatus::failure; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Retrieve the specified thread's frame information. |
| // Type: Method. |
| // Args: vCmdData - (R) A command's information. |
| // vThreadIdx - (R) Thread index. |
| // vwrThreadFrames - (W) Frame data. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::GetThreadFrames( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMICmnMIValueTuple & vwrThreadFrames ) |
| { |
| lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx ); |
| const uint32_t nFrames = thread.GetNumFrames(); |
| if( nFrames == 0 ) |
| { |
| vwrThreadFrames = CMICmnMIValueTuple(); |
| return MIstatus::success; |
| } |
| |
| CMICmnMIValueTuple miValueTupleAll; |
| for( MIuint nLevel = 0; nLevel < nFrames; nLevel++ ) |
| { |
| lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel ); |
| lldb::addr_t pc = 0; |
| CMIUtilString fnName; |
| CMIUtilString fileName; |
| CMIUtilString path; |
| MIuint nLine = 0; |
| if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) ) |
| return MIstatus::failure; |
| |
| // Function args |
| CMICmnMIValueList miValueList( true ); |
| const MIuint vMaskVarTypes = 0x1000; |
| if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) ) |
| return MIstatus::failure; |
| |
| const MIchar * pUnknown = "??"; |
| if( fnName != pUnknown ) |
| { |
| std::replace( fnName.begin(), fnName.end(), ')', ' ' ); |
| std::replace( fnName.begin(), fnName.end(), '(', ' ' ); |
| std::replace( fnName.begin(), fnName.end(), '\'', ' ' ); |
| } |
| |
| const CMIUtilString strLevel( CMIUtilString::Format( "%d", nLevel ) ); |
| const CMICmnMIValueConst miValueConst( strLevel ); |
| const CMICmnMIValueResult miValueResult( "level", miValueConst ); |
| miValueTupleAll.Add( miValueResult ); |
| |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) ) |
| return MIstatus::failure; |
| } |
| |
| vwrThreadFrames = miValueTupleAll; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Return the resolved file's path for the given file. |
| // Type: Method. |
| // Args: vCmdData - (R) A command's information. |
| // vPath - (R) Original path. |
| // vwrResolvedPath - (W) Resolved path. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::ResolvePath( const SMICmdData & vCmdData, const CMIUtilString & vPath, CMIUtilString & vwrResolvedPath ) |
| { |
| // ToDo: Verify this code as it does not work as vPath is always empty |
| |
| CMIUtilString strResolvedPath; |
| if( !SharedDataRetrieve< CMIUtilString >( m_constStrSharedDataKeyWkDir, strResolvedPath ) ) |
| { |
| vwrResolvedPath = ""; |
| SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ), vCmdData.strMiCmd.c_str(), m_constStrSharedDataKeyWkDir.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| vwrResolvedPath = vPath; |
| |
| return ResolvePath( strResolvedPath, vwrResolvedPath ); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Return the resolved file's path for the given file. |
| // Type: Method. |
| // Args: vstrUnknown - (R) String assigned to path when resolved path is empty. |
| // vwrResolvedPath - (RW) The original path overwritten with resolved path. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::ResolvePath( const CMIUtilString & vstrUnknown, CMIUtilString & vwrResolvedPath ) |
| { |
| if( vwrResolvedPath.size() < 1 ) |
| { |
| vwrResolvedPath = vstrUnknown; |
| return MIstatus::success; |
| } |
| |
| bool bOk = MIstatus::success; |
| |
| CMIUtilString::VecString_t vecPathFolders; |
| const MIuint nSplits = vwrResolvedPath.Split( "/", vecPathFolders ); MIunused( nSplits ); |
| MIuint nFoldersBack = 1; // 1 is just the file (last element of vector) |
| while( bOk && (vecPathFolders.size() >= nFoldersBack) ) |
| { |
| CMIUtilString strTestPath; |
| MIuint nFoldersToAdd = nFoldersBack; |
| while( nFoldersToAdd > 0 ) |
| { |
| strTestPath += "/"; |
| strTestPath += vecPathFolders[ vecPathFolders.size() - nFoldersToAdd ]; |
| nFoldersToAdd--; |
| } |
| bool bYesAccessible = false; |
| bOk = AccessPath( strTestPath, bYesAccessible ); |
| if( bYesAccessible ) |
| { |
| vwrResolvedPath = strTestPath; |
| return MIstatus::success; |
| } |
| else |
| nFoldersBack++; |
| } |
| |
| // No files exist in the union of working directory and debuginfo path |
| // Simply use the debuginfo path and let the IDE handle it. |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Determine the given file path exists or not. |
| // Type: Method. |
| // Args: vPath - (R) File name path. |
| // vwbYesAccessible - (W) True - file exists, false = does not exist. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::AccessPath( const CMIUtilString & vPath, bool & vwbYesAccessible ) |
| { |
| #ifdef _WIN32 |
| vwbYesAccessible = (::_access( vPath.c_str(), 0 ) == 0); |
| #else |
| vwbYesAccessible = (::access( vPath.c_str(), 0 ) == 0); |
| #endif // _WIN32 |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Form MI partial response by appending more MI value type objects to the |
| // tuple type object past in. |
| // Type: Method. |
| // Args: vCmdData - (R) A command's information. |
| // vrThread - (R) LLDB thread object. |
| // vwrMIValueTuple - (W) MI value tuple object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple ) |
| { |
| lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread ); |
| |
| CMICmnMIValueTuple miValueTupleFrame; |
| if( !GetThreadFrames( vCmdData, rThread.GetIndexID(), miValueTupleFrame ) ) |
| return MIstatus::failure; |
| |
| const bool bSuspended = rThread.IsSuspended(); |
| const lldb::StopReason eReason = rThread.GetStopReason(); |
| const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); |
| const CMIUtilString strState( (bSuspended || bValidReason) ? "stopped" : "running" ); |
| |
| // Add "id" |
| const CMIUtilString strId( CMIUtilString::Format( "%d", rThread.GetIndexID() ) ); |
| const CMICmnMIValueConst miValueConst1( strId ); |
| const CMICmnMIValueResult miValueResult1( "id", miValueConst1 ); |
| if( !vwrMIValueTuple.Add( miValueResult1 ) ) |
| return MIstatus::failure; |
| |
| // Add "target-id" |
| const MIchar * pThreadName = rThread.GetName(); |
| const MIuint len = (pThreadName != nullptr) ? CMIUtilString( pThreadName ).length() : 0; |
| const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && CMIUtilString::IsAllValidAlphaAndNumeric( *pThreadName ) ); // 32 is arbitary number |
| const MIchar * pThrdFmt = bHaveName ? "%s" : "Thread %d"; |
| CMIUtilString strThread; |
| if( bHaveName ) |
| strThread = CMIUtilString::Format( pThrdFmt, pThreadName ); |
| else |
| strThread = CMIUtilString::Format( pThrdFmt, rThread.GetIndexID() ); |
| const CMICmnMIValueConst miValueConst2( strThread ); |
| const CMICmnMIValueResult miValueResult2( "target-id", miValueConst2 ); |
| if( !vwrMIValueTuple.Add( miValueResult2 ) ) |
| return MIstatus::failure; |
| |
| // Add "frame" |
| const CMICmnMIValueResult miValueResult3( "frame", miValueTupleFrame ); |
| if( !vwrMIValueTuple.Add( miValueResult3 ) ) |
| return MIstatus::failure; |
| |
| // Add "state" |
| const CMICmnMIValueConst miValueConst4( strState ); |
| const CMICmnMIValueResult miValueResult4( "state", miValueConst4 ); |
| if( !vwrMIValueTuple.Add( miValueResult4 ) ) |
| return MIstatus::failure; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Form MI partial response by appending more MI value type objects to the |
| // tuple type object past in. |
| // Type: Method. |
| // Args: vrFrame - (R) LLDB thread object. |
| // vMaskVarTypes - (R) 0x1000 = arguments, |
| // 0x0100 = locals, |
| // 0x0010 = statics, |
| // 0x0001 = in scope only. |
| // vwrMIValueList - (W) MI value list object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList ) |
| { |
| bool bOk = MIstatus::success; |
| lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame ); |
| |
| const bool bArg = (vMaskVarTypes & 0x1000); |
| const bool bLocals = (vMaskVarTypes & 0x0100); |
| const bool bStatics = (vMaskVarTypes & 0x0010); |
| const bool bInScopeOnly = (vMaskVarTypes & 0x0001); |
| const MIchar * pUnkwn = "??"; |
| lldb::SBValueList listArg = rFrame.GetVariables( bArg, bLocals, bStatics, bInScopeOnly ); |
| const MIuint nArgs = listArg.GetSize(); |
| for( MIuint i = 0; bOk && (i < nArgs); i++ ) |
| { |
| lldb::SBValue val = listArg.GetValueAtIndex( i ); |
| const MIchar * pValue = val.GetValue(); |
| pValue = (pValue != nullptr) ? pValue : pUnkwn; |
| const MIchar * pName = val.GetName(); |
| pName = (pName != nullptr) ? pName : pUnkwn; |
| const CMICmnMIValueConst miValueConst( pName ); |
| const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( pValue ); |
| const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
| miValueTuple.Add( miValueResult2 ); |
| bOk = vwrMiValueList.Add( miValueTuple ); |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Form MI partial response by appending more MI value type objects to the |
| // tuple type object past in. |
| // Type: Method. |
| // Args: vrThread - (R) LLDB thread object. |
| // vwrMIValueTuple - (W) MI value tuple object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::SBThread & vrThread, const MIuint vnLevel, CMICmnMIValueTuple & vwrMiValueTuple ) |
| { |
| lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread ); |
| |
| lldb::SBFrame frame = rThread.GetFrameAtIndex( vnLevel ); |
| lldb::addr_t pc = 0; |
| CMIUtilString fnName; |
| CMIUtilString fileName; |
| CMIUtilString path; |
| MIuint nLine = 0; |
| if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) ) |
| return MIstatus::failure; |
| |
| CMICmnMIValueList miValueList( true ); |
| const MIuint vMaskVarTypes = 0x1000; |
| if( !MIResponseFormVariableInfo( frame, vMaskVarTypes, miValueList ) ) |
| return MIstatus::failure; |
| |
| // MI print "{level=\"0\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}" |
| const CMIUtilString strLevel( CMIUtilString::Format( "%d", vnLevel ) ); |
| const CMICmnMIValueConst miValueConst( strLevel ); |
| const CMICmnMIValueResult miValueResult( "level", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| if( !MIResponseFormFrameInfo( pc, fnName, miValueList.GetString(), fileName, path, nLine, miValueTuple ) ) |
| return MIstatus::failure; |
| |
| vwrMiValueTuple = miValueTuple; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Retrieve the frame information from LLDB frame object. |
| // Type: Method. |
| // Args: vrFrame - (R) LLDB thread object. |
| // vPc - (W) Address number. |
| // vFnName - (W) Function name. |
| // vFileName - (W) File name text. |
| // vPath - (W) Full file name and path text. |
| // vnLine - (W) File line number. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::GetFrameInfo( const lldb::SBFrame & vrFrame, lldb::addr_t & vwPc, CMIUtilString & vwFnName, CMIUtilString & vwFileName, CMIUtilString & vwPath, MIuint & vwnLine ) |
| { |
| lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame ); |
| |
| static char pBuffer[ MAX_PATH ]; |
| const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath( &pBuffer[ 0 ], sizeof( pBuffer ) ); MIunused( nBytes ); |
| CMIUtilString strResolvedPath( &pBuffer[ 0 ] ); |
| const MIchar * pUnkwn = "??"; |
| if( !ResolvePath( pUnkwn, strResolvedPath ) ) |
| return MIstatus::failure; |
| vwPath = strResolvedPath; |
| |
| vwPc = rFrame.GetPC(); |
| |
| const MIchar * pFnName = rFrame.GetFunctionName(); |
| vwFnName = (pFnName != nullptr) ? pFnName : pUnkwn; |
| |
| const MIchar * pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename(); |
| vwFileName = (pFileName != nullptr) ? pFileName : pUnkwn; |
| |
| vwnLine = rFrame.GetLineEntry().GetLine(); |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Form MI partial response by appending more MI value type objects to the |
| // tuple type object past in. |
| // Type: Method. |
| // Args: vPc - (R) Address number. |
| // vFnName - (R) Function name. |
| // vArgs - (R) Variable information MI response. |
| // vFileName - (R) File name text. |
| // vPath - (R) Full file name and path text. |
| // vnLine - (R) File line number. |
| // vwrMIValueTuple - (W) MI value tuple object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vArgs, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple ) |
| { |
| const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vPc ) ); |
| const CMICmnMIValueConst miValueConst2( strAddr ); |
| const CMICmnMIValueResult miValueResult2( "addr", miValueConst2 ); |
| if( !vwrMiValueTuple.Add( miValueResult2 ) ) |
| return MIstatus::failure; |
| const CMICmnMIValueConst miValueConst3( vFnName ); |
| const CMICmnMIValueResult miValueResult3( "func", miValueConst3 ); |
| if( !vwrMiValueTuple.Add( miValueResult3 ) ) |
| return MIstatus::failure; |
| const CMICmnMIValueConst miValueConst8( vArgs, true ); |
| const CMICmnMIValueResult miValueResult4( "args", miValueConst8 ); |
| if( !vwrMiValueTuple.Add( miValueResult4 ) ) |
| return MIstatus::failure; |
| const CMICmnMIValueConst miValueConst5( vFileName ); |
| const CMICmnMIValueResult miValueResult5( "file", miValueConst5 ); |
| if( !vwrMiValueTuple.Add( miValueResult5 ) ) |
| return MIstatus::failure; |
| const CMICmnMIValueConst miValueConst6( vPath ); |
| const CMICmnMIValueResult miValueResult6( "fullname", miValueConst6 ); |
| if( !vwrMiValueTuple.Add( miValueResult6 ) ) |
| return MIstatus::failure; |
| const CMIUtilString strLine( CMIUtilString::Format( "%d", vnLine ) ); |
| const CMICmnMIValueConst miValueConst7( strLine ); |
| const CMICmnMIValueResult miValueResult7( "line", miValueConst7 ); |
| if( !vwrMiValueTuple.Add( miValueResult7 ) ) |
| return MIstatus::failure; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Form MI partial response by appending more MI value type objects to the |
| // tuple type object past in. |
| // Type: Method. |
| // Args: vrBrkPtInfo - (R) Break point information object. |
| // vwrMIValueTuple - (W) MI value tuple object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple ) |
| { |
| const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vrBrkPtInfo.m_pc ) ); |
| const CMICmnMIValueConst miValueConst2( strAddr ); |
| const CMICmnMIValueResult miValueResult2( "addr", miValueConst2 ); |
| if( !vwrMiValueTuple.Add( miValueResult2 ) ) |
| return MIstatus::failure; |
| const CMICmnMIValueConst miValueConst3( vrBrkPtInfo.m_fnName ); |
| const CMICmnMIValueResult miValueResult3( "func", miValueConst3 ); |
| if( !vwrMiValueTuple.Add( miValueResult3 ) ) |
| return MIstatus::failure; |
| const CMICmnMIValueConst miValueConst5( vrBrkPtInfo.m_fileName ); |
| const CMICmnMIValueResult miValueResult5( "file", miValueConst5 ); |
| if( !vwrMiValueTuple.Add( miValueResult5 ) ) |
| return MIstatus::failure; |
| const CMIUtilString strN5 = CMIUtilString::Format( "%s/%s", vrBrkPtInfo.m_path.c_str(), vrBrkPtInfo.m_fileName.c_str() ); |
| const CMICmnMIValueConst miValueConst6( strN5 ); |
| const CMICmnMIValueResult miValueResult6( "fullname", miValueConst6 ); |
| if( !vwrMiValueTuple.Add( miValueResult6 ) ) |
| return MIstatus::failure; |
| const CMIUtilString strLine( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nLine ) ); |
| const CMICmnMIValueConst miValueConst7( strLine ); |
| const CMICmnMIValueResult miValueResult7( "line", miValueConst7 ); |
| if( !vwrMiValueTuple.Add( miValueResult7 ) ) |
| return MIstatus::failure; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Form MI partial response by appending more MI value type objects to the |
| // tuple type object past in. |
| // Type: Method. |
| // Args: vrBrkPtInfo - (R) Break point information object. |
| // vwrMIValueTuple - (W) MI value tuple object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple ) |
| { |
| // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\", func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}" |
| |
| // "number=" |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_id ) ); |
| const CMICmnMIValueResult miValueResult( "number", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| // "type=" |
| const CMICmnMIValueConst miValueConst2( vrBrkPtInfo.m_strType ); |
| const CMICmnMIValueResult miValueResult2( "type", miValueConst2 ); |
| bool bOk = miValueTuple.Add( miValueResult2 ); |
| // "disp=" |
| const CMICmnMIValueConst miValueConst3( vrBrkPtInfo.m_bDisp ? "del" : "keep" ); |
| const CMICmnMIValueResult miValueResult3( "disp", miValueConst3 ); |
| bOk = bOk && miValueTuple.Add( miValueResult3 ); |
| // "enabled=" |
| const CMICmnMIValueConst miValueConst4( vrBrkPtInfo.m_bEnabled ? "y" : "n" ); |
| const CMICmnMIValueResult miValueResult4( "enabled", miValueConst4 ); |
| bOk = bOk && miValueTuple.Add( miValueResult4 ); |
| // "addr=" |
| // "func=" |
| // "file=" |
| // "fullname=" |
| // "line=" |
| bOk = bOk && MIResponseFormBrkPtFrameInfo( vrBrkPtInfo, miValueTuple ); |
| // "pending=" |
| if( vrBrkPtInfo.m_bPending ) |
| { |
| const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strOrigLoc ); |
| const CMICmnMIValueList miValueList( miValueConst ); |
| const CMICmnMIValueResult miValueResult( "pending", miValueList ); |
| bOk = bOk && miValueTuple.Add( miValueResult ); |
| } |
| if( vrBrkPtInfo.m_bHaveArgOptionThreadGrp ) |
| { |
| const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strOptThrdGrp ); |
| const CMICmnMIValueList miValueList( miValueConst ); |
| const CMICmnMIValueResult miValueResult( "thread-groups", miValueList ); |
| bOk = bOk && miValueTuple.Add( miValueResult ); |
| } |
| // "times=" |
| const CMICmnMIValueConst miValueConstB( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nTimes ) ); |
| const CMICmnMIValueResult miValueResultB( "times", miValueConstB ); |
| bOk = bOk && miValueTuple.Add( miValueResultB ); |
| // "thread=" |
| if( vrBrkPtInfo.m_bBrkPtThreadId ) |
| { |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nBrkPtThreadId ) ); |
| const CMICmnMIValueResult miValueResult( "thread", miValueConst ); |
| bOk = bOk && miValueTuple.Add( miValueResult ); |
| } |
| // "cond=" |
| if( vrBrkPtInfo.m_bCondition ) |
| { |
| const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strCondition ); |
| const CMICmnMIValueResult miValueResult( "cond", miValueConst ); |
| bOk = bOk && miValueTuple.Add( miValueResult ); |
| } |
| // "ignore=" |
| if( vrBrkPtInfo.m_nIgnore != 0 ) |
| { |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nIgnore ) ); |
| const CMICmnMIValueResult miValueResult( "ignore", miValueConst ); |
| bOk = bOk && miValueTuple.Add( miValueResult ); |
| } |
| // "original-location=" |
| const CMICmnMIValueConst miValueConstC( vrBrkPtInfo.m_strOrigLoc ); |
| const CMICmnMIValueResult miValueResultC( "original-location", miValueConstC ); |
| bOk = bOk && miValueTuple.Add( miValueResultC ); |
| |
| vwrMiValueTuple = miValueTuple; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Retrieve breakpoint information and write into the given breakpoint information |
| // object. Note not all possible information is retrieved and so the information |
| // object may need to be filled in with more information after calling this |
| // function. Mainly breakpoint location information of information that is |
| // unlikely to change. |
| // Type: Method. |
| // Args: vBrkPt - (R) LLDB break point object. |
| // vrBrkPtInfo - (W) Break point information object. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmnLLDBDebugSessionInfo::GetBrkPtInfo( const lldb::SBBreakpoint & vBrkPt, SBrkPtInfo & vrwBrkPtInfo ) const |
| { |
| lldb::SBBreakpoint & rBrkPt = const_cast< lldb::SBBreakpoint & >( vBrkPt ); |
| lldb::SBBreakpointLocation brkPtLoc = rBrkPt.GetLocationAtIndex( 0 ); |
| lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress(); |
| lldb::SBSymbolContext symbolCntxt = brkPtAddr.GetSymbolContext( lldb::eSymbolContextEverything ); |
| const MIchar * pUnkwn = "??"; |
| lldb::SBModule rModule = symbolCntxt.GetModule(); |
| const MIchar * pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn; MIunused( pModule ); |
| const MIchar * pFile = pUnkwn; |
| const MIchar * pFn = pUnkwn; |
| const MIchar * pFilePath = pUnkwn; |
| size_t nLine = 0; |
| const size_t nAddr = brkPtAddr.GetLoadAddress( m_lldbTarget ); |
| |
| lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit(); |
| if( rCmplUnit.IsValid() ) |
| { |
| lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec(); |
| pFile = rFileSpec.GetFilename(); |
| pFilePath = rFileSpec.GetDirectory(); |
| lldb::SBFunction rFn = symbolCntxt.GetFunction(); |
| if( rFn.IsValid() ) |
| pFn = rFn.GetName(); |
| lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry(); |
| if( rLnEntry.GetLine() > 0 ) |
| nLine = rLnEntry.GetLine(); |
| } |
| |
| vrwBrkPtInfo.m_id = vBrkPt.GetID(); |
| vrwBrkPtInfo.m_strType = "breakpoint"; |
| vrwBrkPtInfo.m_pc = nAddr; |
| vrwBrkPtInfo.m_fnName = pFn; |
| vrwBrkPtInfo.m_fileName = pFile; |
| vrwBrkPtInfo.m_path = pFilePath; |
| vrwBrkPtInfo.m_nLine = nLine; |
| vrwBrkPtInfo.m_nTimes = vBrkPt.GetHitCount(); |
| |
| return MIstatus::success; |
| } |