forked from OSchip/llvm-project
1069 lines
41 KiB
C++
1069 lines
41 KiB
C++
//===-- 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;
|
|
}
|