2014-05-16 18:51:01 +08:00
//===-- 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
2014-06-25 00:35:50 +08:00
# include <lldb/API/SBBreakpointLocation.h>
2014-05-16 18:51:01 +08:00
// 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 " )
2014-06-25 00:35:50 +08:00
, m_constStrSharedDataSolibPath ( " Solib Path " )
2014-05-16 18:51:01 +08:00
{
}
//++ ------------------------------------------------------------------------------------
// Details: CMICmnLLDBDebugSessionInfo destructor.
// Type: Overridable.
// Args: None.
// Return: None.
// Throws: None.
//--
CMICmnLLDBDebugSessionInfo : : ~ CMICmnLLDBDebugSessionInfo ( void )
{
Shutdown ( ) ;
}
//++ ------------------------------------------------------------------------------------
2014-06-25 00:35:50 +08:00
// Details: Initialize resources for *this object.
2014-05-16 18:51:01 +08:00
// 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 ;
}
//++ ------------------------------------------------------------------------------------
2014-06-25 00:35:50 +08:00
// Details: Release resources for *this object.
2014-05-16 18:51:01 +08:00
// 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.
2014-06-25 00:35:50 +08:00
// Data can also be assigned by a command and retrieved by LLDB event handler.
2014-05-16 18:51:01 +08:00
// 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 )
{
2014-06-25 00:35:50 +08:00
m_mapIdToSessionData . Clear ( ) ;
2014-05-16 18:51:01 +08:00
m_vecVarObj . clear ( ) ;
2014-06-25 00:35:50 +08:00
m_mapBrkPtIdToBrkPtInfo . clear ( ) ;
2014-05-16 18:51:01 +08:00
return MIstatus : : success ;
}
//++ ------------------------------------------------------------------------------------
2014-06-25 00:35:50 +08:00
// Details: Record information about a LLDB break point so that is can be recalled in other
// commands or LLDB event handling functions.
2014-05-16 18:51:01 +08:00
// Type: Method.
2014-06-25 00:35:50 +08:00
// Args: vBrkPtId - (R) LLDB break point ID.
// vrBrkPtInfo - (R) Break point information object.
2014-05-16 18:51:01 +08:00
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
2014-06-25 00:35:50 +08:00
bool CMICmnLLDBDebugSessionInfo : : RecordBrkPtInfo ( const MIuint vnBrkPtId , const SBrkPtInfo & vrBrkPtInfo )
2014-05-16 18:51:01 +08:00
{
2014-06-25 00:35:50 +08:00
MapPairBrkPtIdToBrkPtInfo_t pr ( vnBrkPtId , vrBrkPtInfo ) ;
m_mapBrkPtIdToBrkPtInfo . insert ( pr ) ;
2014-05-16 18:51:01 +08:00
return MIstatus : : success ;
}
//++ ------------------------------------------------------------------------------------
2014-06-25 00:35:50 +08:00
// Details: Retrieve information about a LLDB break point previous recorded either by
// commands or LLDB event handling functions.
2014-05-16 18:51:01 +08:00
// Type: Method.
2014-06-25 00:35:50 +08:00
// Args: vBrkPtId - (R) LLDB break point ID.
// vrwBrkPtInfo - (W) Break point information object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
2014-05-16 18:51:01 +08:00
// Throws: None.
//--
2014-06-25 00:35:50 +08:00
bool CMICmnLLDBDebugSessionInfo : : RecordBrkPtInfoGet ( const MIuint vnBrkPtId , SBrkPtInfo & vrwBrkPtInfo ) const
2014-05-16 18:51:01 +08:00
{
2014-06-25 00:35:50 +08:00
const MapBrkPtIdToBrkPtInfo_t : : const_iterator it = m_mapBrkPtIdToBrkPtInfo . find ( vnBrkPtId ) ;
if ( it ! = m_mapBrkPtIdToBrkPtInfo . end ( ) )
2014-05-16 18:51:01 +08:00
{
2014-06-25 00:35:50 +08:00
vrwBrkPtInfo = ( * it ) . second ;
return MIstatus : : success ;
2014-05-16 18:51:01 +08:00
}
2014-06-25 00:35:50 +08:00
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 ;
2014-05-16 18:51:01 +08:00
}
//++ ------------------------------------------------------------------------------------
// 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 ;
2014-06-25 00:35:50 +08:00
if ( ! SharedDataRetrieve < CMIUtilString > ( m_constStrSharedDataKeyWkDir , strResolvedPath ) )
2014-05-16 18:51:01 +08:00
{
vwrResolvedPath = " " ;
2014-06-25 00:35:50 +08:00
SetErrorDescription ( CMIUtilString : : Format ( MIRSRC ( IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ) , vCmdData . strMiCmd . c_str ( ) , m_constStrSharedDataKeyWkDir . c_str ( ) ) ) ;
2014-05-16 18:51:01 +08:00
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 ;
2014-06-25 00:35:50 +08:00
const MIuint nSplits = vwrResolvedPath . Split ( " / " , vecPathFolders ) ; MIunused ( nSplits ) ;
2014-05-16 18:51:01 +08:00
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"
2014-06-25 00:35:50 +08:00
const MIchar * pThreadName = rThread . GetName ( ) ;
2014-05-16 18:51:01 +08:00
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 ) ;
2014-06-25 00:35:50 +08:00
const MIchar * pValue = val . GetValue ( ) ;
2014-05-16 18:51:01 +08:00
pValue = ( pValue ! = nullptr ) ? pValue : pUnkwn ;
2014-06-25 00:35:50 +08:00
const MIchar * pName = val . GetName ( ) ;
2014-05-16 18:51:01 +08:00
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 ] ;
2014-06-25 00:35:50 +08:00
const MIuint nBytes = rFrame . GetLineEntry ( ) . GetFileSpec ( ) . GetPath ( & pBuffer [ 0 ] , sizeof ( pBuffer ) ) ; MIunused ( nBytes ) ;
2014-05-16 18:51:01 +08:00
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.
2014-06-25 00:35:50 +08:00
// Args: vrBrkPtInfo - (R) Break point information object.
2014-05-16 18:51:01 +08:00
// vwrMIValueTuple - (W) MI value tuple object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
2014-06-25 00:35:50 +08:00
bool CMICmnLLDBDebugSessionInfo : : MIResponseFormBrkPtFrameInfo ( const SBrkPtInfo & vrBrkPtInfo , CMICmnMIValueTuple & vwrMiValueTuple )
2014-05-16 18:51:01 +08:00
{
2014-06-25 00:35:50 +08:00
const CMIUtilString strAddr ( CMIUtilString : : Format ( " 0x%08llx " , vrBrkPtInfo . m_pc ) ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueConst miValueConst2 ( strAddr ) ;
const CMICmnMIValueResult miValueResult2 ( " addr " , miValueConst2 ) ;
if ( ! vwrMiValueTuple . Add ( miValueResult2 ) )
return MIstatus : : failure ;
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConst3 ( vrBrkPtInfo . m_fnName ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResult3 ( " func " , miValueConst3 ) ;
if ( ! vwrMiValueTuple . Add ( miValueResult3 ) )
return MIstatus : : failure ;
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConst5 ( vrBrkPtInfo . m_fileName ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResult5 ( " file " , miValueConst5 ) ;
if ( ! vwrMiValueTuple . Add ( miValueResult5 ) )
return MIstatus : : failure ;
2014-06-25 00:35:50 +08:00
const CMIUtilString strN5 = CMIUtilString : : Format ( " %s/%s " , vrBrkPtInfo . m_path . c_str ( ) , vrBrkPtInfo . m_fileName . c_str ( ) ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueConst miValueConst6 ( strN5 ) ;
const CMICmnMIValueResult miValueResult6 ( " fullname " , miValueConst6 ) ;
if ( ! vwrMiValueTuple . Add ( miValueResult6 ) )
return MIstatus : : failure ;
2014-06-25 00:35:50 +08:00
const CMIUtilString strLine ( CMIUtilString : : Format ( " %d " , vrBrkPtInfo . m_nLine ) ) ;
2014-05-16 18:51:01 +08:00
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.
2014-06-25 00:35:50 +08:00
// Args: vrBrkPtInfo - (R) Break point information object.
2014-05-16 18:51:01 +08:00
// vwrMIValueTuple - (W) MI value tuple object.
// Return: MIstatus::success - Functional succeeded.
// MIstatus::failure - Functional failed.
// Throws: None.
//--
2014-06-25 00:35:50 +08:00
bool CMICmnLLDBDebugSessionInfo : : MIResponseFormBrkPtInfo ( const SBrkPtInfo & vrBrkPtInfo , CMICmnMIValueTuple & vwrMiValueTuple )
2014-05-16 18:51:01 +08:00
{
// 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="
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConst ( CMIUtilString : : Format ( " %d " , vrBrkPtInfo . m_id ) ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResult ( " number " , miValueConst ) ;
CMICmnMIValueTuple miValueTuple ( miValueResult ) ;
// "type="
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConst2 ( vrBrkPtInfo . m_strType ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResult2 ( " type " , miValueConst2 ) ;
bool bOk = miValueTuple . Add ( miValueResult2 ) ;
// "disp="
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConst3 ( vrBrkPtInfo . m_bDisp ? " del " : " keep " ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResult3 ( " disp " , miValueConst3 ) ;
bOk = bOk & & miValueTuple . Add ( miValueResult3 ) ;
// "enabled="
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConst4 ( vrBrkPtInfo . m_bEnabled ? " y " : " n " ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResult4 ( " enabled " , miValueConst4 ) ;
bOk = bOk & & miValueTuple . Add ( miValueResult4 ) ;
// "addr="
// "func="
// "file="
// "fullname="
// "line="
2014-06-25 00:35:50 +08:00
bOk = bOk & & MIResponseFormBrkPtFrameInfo ( vrBrkPtInfo , miValueTuple ) ;
// "pending="
if ( vrBrkPtInfo . m_bPending )
2014-05-16 18:51:01 +08:00
{
2014-06-25 00:35:50 +08:00
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 ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueList miValueList ( miValueConst ) ;
const CMICmnMIValueResult miValueResult ( " thread-groups " , miValueList ) ;
bOk = bOk & & miValueTuple . Add ( miValueResult ) ;
}
// "times="
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConstB ( CMIUtilString : : Format ( " %d " , vrBrkPtInfo . m_nTimes ) ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResultB ( " times " , miValueConstB ) ;
bOk = bOk & & miValueTuple . Add ( miValueResultB ) ;
2014-06-25 00:35:50 +08:00
// "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 ) ;
}
2014-05-16 18:51:01 +08:00
// "original-location="
2014-06-25 00:35:50 +08:00
const CMICmnMIValueConst miValueConstC ( vrBrkPtInfo . m_strOrigLoc ) ;
2014-05-16 18:51:01 +08:00
const CMICmnMIValueResult miValueResultC ( " original-location " , miValueConstC ) ;
bOk = bOk & & miValueTuple . Add ( miValueResultC ) ;
vwrMiValueTuple = miValueTuple ;
return MIstatus : : success ;
}
2014-06-25 00:35:50 +08:00
//++ ------------------------------------------------------------------------------------
// 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 ;
}