| //===-- MICmdCmdBreak.cpp ---------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| //++ |
| // File: MICmdCmdBreak.cpp |
| // |
| // Overview: CMICmdCmdBreakInsert implementation. |
| // CMICmdCmdBreakDelete implementation. |
| // CMICmdCmdBreakDisable implementation. |
| // CMICmdCmdBreakEnable implementation. |
| // CMICmdCmdBreakAfter implementation. |
| // CMICmdCmdBreakCondition 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/SBBreakpointLocation.h> |
| |
| // In-house headers: |
| #include "MICmnConfig.h" |
| #include "MICmdCmdBreak.h" |
| #include "MICmnMIResultRecord.h" |
| #include "MICmnMIValueConst.h" |
| #include "MICmnMIOutOfBandRecord.h" |
| #include "MICmnLLDBDebugger.h" |
| #include "MICmnLLDBDebugSessionInfo.h" |
| #include "MICmdArgContext.h" |
| #include "MICmdArgValFile.h" |
| #include "MICmdArgValNumber.h" |
| #include "MICmdArgValString.h" |
| #include "MICmdArgValThreadGrp.h" |
| #include "MICmdArgValOptionLong.h" |
| #include "MICmdArgValOptionShort.h" |
| #include "MICmdArgValListOfN.h" |
| #include "MICmnStreamStdout.h" |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakInsert constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakInsert::CMICmdCmdBreakInsert( void ) |
| : m_bBrkPtIsTemp( false ) |
| , m_bBrkPtIsPending( false ) |
| , m_nBrkPtIgnoreCount( 0 ) |
| , m_bBrkPtEnabled( false ) |
| , m_bBrkPtCondition( false ) |
| , m_bBrkPtThreadId( false ) |
| , m_nBrkPtThreadId( 0 ) |
| , m_constStrArgNamedTempBrkPt( "t" ) |
| , m_constStrArgNamedHWBrkPt( "h" ) |
| , m_constStrArgNamedPendinfBrkPt( "f" ) |
| , m_constStrArgNamedDisableBrkPt( "d" ) |
| , m_constStrArgNamedTracePt( "a" ) |
| , m_constStrArgNamedConditionalBrkPt( "c" ) |
| , m_constStrArgNamedInoreCnt( "i" ) |
| , m_constStrArgNamedRestrictBrkPtToThreadId( "p" ) |
| , m_constStrArgNamedLocation( "location" ) |
| , m_constStrArgNamedThreadGroup( "thread-group" ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "break-insert"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakInsert destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakInsert::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTempBrkPt, false, true )) ); |
| //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedPendinfBrkPt, false, true, CMICmdArgValListBase::eArgValType_String, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedDisableBrkPt, false, false ) ) ); |
| //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedConditionalBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuoted, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedInoreCnt, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedRestrictBrkPtToThreadId, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedLocation, false, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGroup, false, true, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakInsert::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt ); |
| CMICMDBASE_GETOPTION( pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup ); |
| CMICMDBASE_GETOPTION( pArgLocation, String, m_constStrArgNamedLocation ); |
| CMICMDBASE_GETOPTION( pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt ); |
| CMICMDBASE_GETOPTION( pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt ); |
| CMICMDBASE_GETOPTION( pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt ); |
| CMICMDBASE_GETOPTION( pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt ); |
| CMICMDBASE_GETOPTION( pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId ); |
| |
| m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound(); |
| m_bBrkPtIsTemp = pArgTempBrkPt->GetFound(); |
| m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound(); |
| if( m_bHaveArgOptionThreadGrp ) |
| { |
| MIuint nThreadGrp = 0; |
| pArgThreadGroup->GetExpectedOption< CMICmdArgValThreadGrp, MIuint >( nThreadGrp ); |
| m_strArgOptionThreadGrp = CMIUtilString::Format( "i%d", nThreadGrp ); |
| } |
| m_bBrkPtIsPending = pArgPendingBrkPt->GetFound(); |
| if( pArgLocation->GetFound() ) |
| m_brkName = pArgLocation->GetValue(); |
| else if( m_bBrkPtIsPending ) |
| { |
| pArgPendingBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkName ); |
| } |
| if( pArgIgnoreCnt->GetFound() ) |
| { |
| pArgIgnoreCnt->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtIgnoreCount ); |
| } |
| m_bBrkPtCondition = pArgConditionalBrkPt->GetFound(); |
| if( m_bBrkPtCondition ) |
| { |
| pArgConditionalBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkPtCondition ); |
| } |
| m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound(); |
| if( m_bBrkPtCondition ) |
| { |
| pArgRestrictBrkPtToThreadId->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtThreadId ); |
| } |
| |
| // Determine if break on a file line or at a function |
| BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet; |
| const CMIUtilString cColon = ":"; |
| CMIUtilString fileName; |
| MIuint nFileLine = 0; |
| CMIUtilString strFileFn; |
| const MIint nPosColon = m_brkName.find( cColon ); |
| if( nPosColon != (MIint) std::string::npos ) |
| { |
| CMIUtilString::VecString_t vecFileAndLocation; |
| const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation ); MIunused( nSplits ); |
| if( vecFileAndLocation.size() != 2 ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) ); |
| return MIstatus::failure; |
| } |
| fileName = vecFileAndLocation.at( 0 ); |
| const CMIUtilString & rStrLineOrFn( vecFileAndLocation.at( 1 ) ); |
| if( rStrLineOrFn.empty() ) |
| eBrkPtType = eBreakPoint_ByName; |
| else |
| { |
| MIint64 nValue = 0; |
| if( rStrLineOrFn.ExtractNumber( nValue ) ) |
| { |
| nFileLine = static_cast< MIuint >( nValue ); |
| eBrkPtType = eBreakPoint_ByFileLine; |
| } |
| else |
| { |
| strFileFn = rStrLineOrFn; |
| eBrkPtType = eBreakPoint_ByFileFn; |
| } |
| } |
| } |
| |
| // Determine if break defined as an address |
| lldb::addr_t nAddress = 0; |
| if( eBrkPtType == eBreakPoint_NotDefineYet ) |
| { |
| MIint64 nValue = 0; |
| if( m_brkName.ExtractNumber( nValue ) ) |
| { |
| nAddress = static_cast< lldb::addr_t >( nValue ); |
| eBrkPtType = eBreakPoint_ByAddress; |
| } |
| } |
| |
| // Break defined as an function |
| if( eBrkPtType == eBreakPoint_NotDefineYet ) |
| { |
| eBrkPtType = eBreakPoint_ByName; |
| } |
| |
| // Ask LLDB to create a breakpoint |
| bool bOk = MIstatus::success; |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget; |
| switch( eBrkPtType ) |
| { |
| case eBreakPoint_ByAddress: |
| m_brkPt = rTarget.BreakpointCreateByAddress( nAddress ); |
| break; |
| case eBreakPoint_ByFileFn: |
| m_brkPt = rTarget.BreakpointCreateByName( strFileFn.c_str(), fileName.c_str() ); |
| break; |
| case eBreakPoint_ByFileLine: |
| m_brkPt = rTarget.BreakpointCreateByLocation( fileName.c_str(), nFileLine ); |
| break; |
| case eBreakPoint_ByName: |
| m_brkPt = rTarget.BreakpointCreateByName( m_brkName.c_str(), rTarget.GetExecutable().GetFilename() ); |
| break; |
| case eBreakPoint_count: |
| case eBreakPoint_NotDefineYet: |
| case eBreakPoint_Invalid: |
| bOk = MIstatus::failure; |
| break; |
| } |
| |
| if( bOk ) |
| { |
| m_brkPt.SetEnabled( m_bBrkPtEnabled ); |
| m_brkPt.SetIgnoreCount( m_nBrkPtIgnoreCount ); |
| if( m_bBrkPtCondition ) |
| m_brkPt.SetCondition( m_brkPtCondition.c_str() ); |
| if( m_bBrkPtThreadId ) |
| m_brkPt.SetThreadID( m_nBrkPtThreadId ); |
| if( !m_brkPt.IsValid() ) |
| m_bBrkPtIsPending = pArgPendingBrkPt->GetFound(); |
| } |
| |
| // CODETAG_LLDB_BREAKPOINT_CREATION |
| // This is in the main thread |
| // Record break point information to be by LLDB event handler function |
| CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo; |
| sBrkPtInfo.m_id = m_brkPt.GetID(); |
| sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp; |
| sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled; |
| sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp; |
| sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp; |
| sBrkPtInfo.m_strOrigLoc = m_brkName; |
| sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount; |
| sBrkPtInfo.m_bPending = m_bBrkPtIsPending; |
| sBrkPtInfo.m_bCondition = m_bBrkPtCondition; |
| sBrkPtInfo.m_strCondition = m_brkPtCondition; |
| sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId; |
| sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId; |
| bOk = bOk && rSessionInfo.RecordBrkPtInfo( m_brkPt.GetID(), sBrkPtInfo ); |
| |
| if( !bOk ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) ); |
| return MIstatus::failure; |
| } |
| if( m_brkPt.GetID() > (lldb::break_id_t) rSessionInfo.m_nBrkPointCntMax ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED ), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax, m_brkName.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakInsert::Acknowledge( void ) |
| { |
| // Get breakpoint information |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo; |
| if( !rSessionInfo.GetBrkPtInfo( m_brkPt, sBrkPtInfo ) ) |
| { |
| return MIstatus::failure; |
| } |
| |
| // CODETAG_LLDB_BREAKPOINT_CREATION |
| // Add more breakpoint information or overwrite existing information |
| sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp; |
| sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled; |
| sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp; |
| sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp; |
| sBrkPtInfo.m_nTimes = m_brkPt.GetNumLocations(); |
| sBrkPtInfo.m_strOrigLoc = m_brkName; |
| sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount; |
| sBrkPtInfo.m_bPending = m_bBrkPtIsPending; |
| sBrkPtInfo.m_bCondition = m_bBrkPtCondition; |
| sBrkPtInfo.m_strCondition = m_brkPtCondition; |
| sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId; |
| sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId; |
| |
| // MI print "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}" |
| CMICmnMIValueTuple miValueTuple; |
| if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) ) |
| { |
| return MIstatus::failure; |
| } |
| |
| const CMICmnMIValueResult miValueResultD( "bkpt", miValueTuple ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdBreakInsert::CreateSelf( void ) |
| { |
| return new CMICmdCmdBreakInsert(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakDelete constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakDelete::CMICmdCmdBreakDelete( void ) |
| : m_constStrArgNamedBrkPt( "breakpoint" ) |
| , m_constStrArgNamedThreadGrp( "thread-group" ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "break-delete"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakDelete destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakDelete::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakDelete::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt ); |
| |
| // ATM we only handle one break point ID |
| MIuint64 nBrk = UINT64_MAX; |
| if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| const bool bBrkPt = rSessionInfo.m_lldbTarget.BreakpointDelete( static_cast< lldb::break_id_t >( nBrk ) ); |
| if( !bBrkPt ) |
| { |
| const CMIUtilString strBrkNum( CMIUtilString::Format( "%d", nBrk ) ); |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkNum.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakDelete::Acknowledge( void ) |
| { |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdBreakDelete::CreateSelf( void ) |
| { |
| return new CMICmdCmdBreakDelete(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakDisable constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakDisable::CMICmdCmdBreakDisable( void ) |
| : m_constStrArgNamedThreadGrp( "thread-group" ) |
| , m_constStrArgNamedBrkPt( "breakpoint" ) |
| , m_bBrkPtDisabledOk( false ) |
| , m_nBrkPtId( 0 ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "break-disable"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakDisable destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakDisable::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakDisable::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt ); |
| |
| // ATM we only handle one break point ID |
| MIuint64 nBrk = UINT64_MAX; |
| if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) ); |
| if( brkPt.IsValid() ) |
| { |
| m_bBrkPtDisabledOk = true; |
| brkPt.SetEnabled( false ); |
| m_nBrkPtId = nBrk; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakDisable::Acknowledge( void ) |
| { |
| if( m_bBrkPtDisabledOk ) |
| { |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) ); |
| const CMICmnMIValueResult miValueResult( "number", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( "n" ); |
| const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 ); |
| bool bOk = miValueTuple.Add( miValueResult2 ); |
| const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple ); |
| const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 ); |
| bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() ); |
| |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done ); |
| m_miResultRecord = miRecordResult; |
| return bOk; |
| } |
| |
| const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) ); |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) ); |
| const CMICmnMIValueResult miValueResult( "msg", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdBreakDisable::CreateSelf( void ) |
| { |
| return new CMICmdCmdBreakDisable(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakEnable constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakEnable::CMICmdCmdBreakEnable( void ) |
| : m_constStrArgNamedThreadGrp( "thread-group" ) |
| , m_constStrArgNamedBrkPt( "breakpoint" ) |
| , m_bBrkPtEnabledOk( false ) |
| , m_nBrkPtId( 0 ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "break-enable"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakEnable destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakEnable::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakEnable::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt ); |
| |
| // ATM we only handle one break point ID |
| MIuint64 nBrk = UINT64_MAX; |
| if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) ); |
| if( brkPt.IsValid() ) |
| { |
| m_bBrkPtEnabledOk = true; |
| brkPt.SetEnabled( false ); |
| m_nBrkPtId = nBrk; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakEnable::Acknowledge( void ) |
| { |
| if( m_bBrkPtEnabledOk ) |
| { |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) ); |
| const CMICmnMIValueResult miValueResult( "number", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( "y" ); |
| const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 ); |
| bool bOk = miValueTuple.Add( miValueResult2 ); |
| const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple ); |
| const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 ); |
| bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() ); |
| |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done ); |
| m_miResultRecord = miRecordResult; |
| return bOk; |
| } |
| |
| const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) ); |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) ); |
| const CMICmnMIValueResult miValueResult( "msg", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdBreakEnable::CreateSelf( void ) |
| { |
| return new CMICmdCmdBreakEnable(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakAfter constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakAfter::CMICmdCmdBreakAfter( void ) |
| : m_constStrArgNamedThreadGrp( "thread-group" ) |
| , m_constStrArgNamedNumber( "number" ) |
| , m_constStrArgNamedCount( "count" ) |
| , m_nBrkPtId( 0 ) |
| , m_nBrkPtCount( 0 ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "break-after"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakAfter destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakAfter::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedCount, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakAfter::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber ); |
| CMICMDBASE_GETOPTION( pArgCount, Number, m_constStrArgNamedCount ); |
| |
| m_nBrkPtId = pArgNumber->GetValue(); |
| m_nBrkPtCount = pArgCount->GetValue(); |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) ); |
| if( brkPt.IsValid() ) |
| { |
| brkPt.SetIgnoreCount( m_nBrkPtCount ); |
| |
| CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo; |
| if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) ); |
| return MIstatus::failure; |
| } |
| sBrkPtInfo.m_nIgnore = m_nBrkPtCount; |
| rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo ); |
| } |
| else |
| { |
| const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) ); |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakAfter::Acknowledge( void ) |
| { |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdBreakAfter::CreateSelf( void ) |
| { |
| return new CMICmdCmdBreakAfter(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakCondition constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakCondition::CMICmdCmdBreakCondition( void ) |
| : m_constStrArgNamedThreadGrp( "thread-group" ) |
| , m_constStrArgNamedNumber( "number" ) |
| , m_constStrArgNamedExpr( "expr" ) |
| , m_constStrArgNamedExprNoQuotes( "expression not surround by quotes" ) // Not specified in MI spec, we need to handle expressions not surrounded by quotes |
| , m_nBrkPtId( 0 ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "break-condition"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdBreakCondition destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakCondition::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedExpr, true, true, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedExprNoQuotes, true, false, CMICmdArgValListBase::eArgValType_StringQuotedNumber ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakCondition::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber ); |
| CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgNamedExpr ); |
| |
| m_nBrkPtId = pArgNumber->GetValue(); |
| m_strBrkPtExpr = pArgExpr->GetValue(); |
| m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes(); |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) ); |
| if( brkPt.IsValid() ) |
| { |
| brkPt.SetCondition( m_strBrkPtExpr.c_str() ); |
| |
| CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo; |
| if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) ); |
| return MIstatus::failure; |
| } |
| sBrkPtInfo.m_strCondition = m_strBrkPtExpr; |
| rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo ); |
| } |
| else |
| { |
| const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) ); |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdBreakCondition::Acknowledge( void ) |
| { |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdBreakCondition::CreateSelf( void ) |
| { |
| return new CMICmdCmdBreakCondition(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: A breakpoint expression can be passed to *this command as: |
| // a single string i.e. '2' -> ok. |
| // a quoted string i.e. "a > 100" -> ok |
| // a non quoted string i.e. 'a > 100' -> not ok |
| // CMICmdArgValString only extracts the first space seperated string, the "a". |
| // This function using the optional argument type CMICmdArgValListOfN collects |
| // the rest of the expression so that is may be added to the 'a' part to form a |
| // complete expression string i.e. "a > 100". |
| // If the expression value was guaranteed to be surrounded by quotes them this |
| // function would not be necessary. |
| // Type: Method. |
| // Args: None. |
| // Return: CMIUtilString - Rest of the breakpoint expression. |
| // Throws: None. |
| //-- |
| CMIUtilString CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes( void ) |
| { |
| CMIUtilString strExpression; |
| |
| CMICmdArgValListOfN * pArgExprNoQuotes = CMICmdBase::GetOption< CMICmdArgValListOfN >( m_constStrArgNamedExprNoQuotes ); |
| if( pArgExprNoQuotes != nullptr ) |
| { |
| CMIUtilString strExpression; |
| const CMICmdArgValListBase::VecArgObjPtr_t & rVecExprParts( pArgExprNoQuotes->GetExpectedOptions() ); |
| if( !rVecExprParts.empty() ) |
| { |
| CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin(); |
| while( it != rVecExprParts.end() ) |
| { |
| const CMICmdArgValString * pPartExpr = static_cast< CMICmdArgValString * >( *it ); |
| const CMIUtilString & rPartExpr = pPartExpr->GetValue(); |
| strExpression += " "; |
| strExpression += rPartExpr; |
| |
| // Next |
| ++it; |
| } |
| strExpression = strExpression.Trim(); |
| } |
| } |
| |
| return strExpression; |
| } |