1 //===-- MICmdCmdBreak.cpp ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // File: MICmdCmdBreak.cpp
13 // Overview: CMICmdCmdBreakInsert implementation.
14 // CMICmdCmdBreakDelete implementation.
15 // CMICmdCmdBreakDisable implementation.
16 // CMICmdCmdBreakEnable implementation.
17 // CMICmdCmdBreakAfter implementation.
18 // CMICmdCmdBreakCondition implementation.
20 // Environment: Compilers: Visual C++ 12.
21 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
22 // Libraries: See MIReadmetxt.
27 // Third Party Headers:
28 #include <lldb/API/SBBreakpointLocation.h>
31 #include "MICmdCmdBreak.h"
32 #include "MICmnMIResultRecord.h"
33 #include "MICmnMIValueConst.h"
34 #include "MICmnMIOutOfBandRecord.h"
35 #include "MICmnLLDBDebugger.h"
36 #include "MICmnLLDBDebugSessionInfo.h"
37 #include "MICmdArgValFile.h"
38 #include "MICmdArgValNumber.h"
39 #include "MICmdArgValString.h"
40 #include "MICmdArgValThreadGrp.h"
41 #include "MICmdArgValOptionLong.h"
42 #include "MICmdArgValOptionShort.h"
43 #include "MICmdArgValListOfN.h"
44 #include "MICmnStreamStdout.h"
46 //++ ------------------------------------------------------------------------------------
47 // Details: CMICmdCmdBreakInsert constructor.
53 CMICmdCmdBreakInsert::CMICmdCmdBreakInsert( void )
54 : m_bBrkPtIsTemp( false )
55 , m_bBrkPtIsPending( false )
56 , m_nBrkPtIgnoreCount( 0 )
57 , m_bBrkPtEnabled( false )
58 , m_bBrkPtCondition( false )
59 , m_bBrkPtThreadId( false )
60 , m_nBrkPtThreadId( 0 )
61 , m_constStrArgNamedTempBrkPt( "t" )
62 , m_constStrArgNamedHWBrkPt( "h" )
63 , m_constStrArgNamedPendinfBrkPt( "f" )
64 , m_constStrArgNamedDisableBrkPt( "d" )
65 , m_constStrArgNamedTracePt( "a" )
66 , m_constStrArgNamedConditionalBrkPt( "c" )
67 , m_constStrArgNamedInoreCnt( "i" )
68 , m_constStrArgNamedRestrictBrkPtToThreadId( "p" )
69 , m_constStrArgNamedLocation( "location" )
70 , m_constStrArgNamedThreadGroup( "thread-group" )
72 // Command factory matches this name with that received from the stdin stream
73 m_strMiCmd = "break-insert";
75 // Required by the CMICmdFactory when registering *this command
76 m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
79 //++ ------------------------------------------------------------------------------------
80 // Details: CMICmdCmdBreakInsert destructor.
81 // Type: Overrideable.
86 CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert( void )
90 //++ ------------------------------------------------------------------------------------
91 // Details: The invoker requires this function. The parses the command line options
92 // arguments to extract values for each of those arguments.
95 // Return: MIstatus::success - Functional succeeded.
96 // MIstatus::failure - Functional failed.
99 bool CMICmdCmdBreakInsert::ParseArgs( void )
101 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTempBrkPt, false, true )) );
102 //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false ) ) );
103 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedPendinfBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1 ) ) );
104 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedDisableBrkPt, false, false ) ) );
105 //Not implemented bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false ) ) );
106 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedConditionalBrkPt, false, true, CMICmdArgValListBase::eArgValType_StringQuoted, 1 ) ) );
107 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedInoreCnt, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
108 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgNamedRestrictBrkPtToThreadId, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
109 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedLocation, false, true ) ) );
110 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGroup, false, true, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
111 return (bOk && ParseValidateCmdOptions() );
114 //++ ------------------------------------------------------------------------------------
115 // Details: The invoker requires this function. The command does work in this function.
116 // The command is likely to communicate with the LLDB SBDebugger in here.
119 // Return: MIstatus::success - Functional succeeded.
120 // MIstatus::failure - Functional failed.
123 bool CMICmdCmdBreakInsert::Execute( void )
125 CMICMDBASE_GETOPTION( pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt );
126 CMICMDBASE_GETOPTION( pArgThreadGroup, OptionLong, m_constStrArgNamedThreadGroup );
127 CMICMDBASE_GETOPTION( pArgLocation, String, m_constStrArgNamedLocation );
128 CMICMDBASE_GETOPTION( pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt );
129 CMICMDBASE_GETOPTION( pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt );
130 CMICMDBASE_GETOPTION( pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt );
131 CMICMDBASE_GETOPTION( pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt );
132 CMICMDBASE_GETOPTION( pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId );
134 m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
135 m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
136 m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
137 if( m_bHaveArgOptionThreadGrp )
139 MIuint nThreadGrp = 0;
140 pArgThreadGroup->GetExpectedOption< CMICmdArgValThreadGrp, MIuint >( nThreadGrp );
141 m_strArgOptionThreadGrp = CMIUtilString::Format( "i%d", nThreadGrp );
143 m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
144 if( pArgLocation->GetFound() )
145 m_brkName = pArgLocation->GetValue();
146 else if( m_bBrkPtIsPending )
148 pArgPendingBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkName );
150 if( pArgIgnoreCnt->GetFound() )
152 pArgIgnoreCnt->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtIgnoreCount );
154 m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
155 if( m_bBrkPtCondition )
157 pArgConditionalBrkPt->GetExpectedOption< CMICmdArgValString, CMIUtilString >( m_brkPtCondition );
159 m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
160 if( m_bBrkPtCondition )
162 pArgRestrictBrkPtToThreadId->GetExpectedOption< CMICmdArgValNumber, MIuint >( m_nBrkPtThreadId );
165 // Determine if break on a file line or at a function
166 BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
167 const CMIUtilString cColon = ":";
168 CMIUtilString fileName;
169 MIuint nFileLine = 0;
170 CMIUtilString strFileFn;
171 const MIint nPosColon = m_brkName.find( cColon );
172 if( nPosColon != (MIint) std::string::npos )
174 CMIUtilString::VecString_t vecFileAndLocation;
175 const MIuint nSplits = m_brkName.Split( cColon, vecFileAndLocation ); MIunused( nSplits );
176 if( vecFileAndLocation.size() != 2 )
178 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_LOCATION_FORMAT ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
179 return MIstatus::failure;
181 fileName = vecFileAndLocation.at( 0 );
182 const CMIUtilString & rStrLineOrFn( vecFileAndLocation.at( 1 ) );
183 if( rStrLineOrFn.empty() )
184 eBrkPtType = eBreakPoint_ByName;
188 if( rStrLineOrFn.ExtractNumber( nValue ) )
190 nFileLine = static_cast< MIuint >( nValue );
191 eBrkPtType = eBreakPoint_ByFileLine;
195 strFileFn = rStrLineOrFn;
196 eBrkPtType = eBreakPoint_ByFileFn;
201 // Determine if break defined as an address
202 lldb::addr_t nAddress = 0;
203 if( eBrkPtType == eBreakPoint_NotDefineYet )
206 if( m_brkName.ExtractNumber( nValue ) )
208 nAddress = static_cast< lldb::addr_t >( nValue );
209 eBrkPtType = eBreakPoint_ByAddress;
213 // Break defined as an function
214 if( eBrkPtType == eBreakPoint_NotDefineYet )
216 eBrkPtType = eBreakPoint_ByName;
219 // Ask LLDB to create a breakpoint
220 bool bOk = MIstatus::success;
221 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
222 lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
225 case eBreakPoint_ByAddress:
226 m_brkPt = rTarget.BreakpointCreateByAddress( nAddress );
228 case eBreakPoint_ByFileFn:
229 m_brkPt = rTarget.BreakpointCreateByName( strFileFn.c_str(), fileName.c_str() );
231 case eBreakPoint_ByFileLine:
232 m_brkPt = rTarget.BreakpointCreateByLocation( fileName.c_str(), nFileLine );
234 case eBreakPoint_ByName:
235 m_brkPt = rTarget.BreakpointCreateByName( m_brkName.c_str(), rTarget.GetExecutable().GetFilename() );
237 case eBreakPoint_count:
238 case eBreakPoint_NotDefineYet:
239 case eBreakPoint_Invalid:
240 bOk = MIstatus::failure;
246 m_brkPt.SetEnabled( m_bBrkPtEnabled );
247 m_brkPt.SetIgnoreCount( m_nBrkPtIgnoreCount );
248 if( m_bBrkPtCondition )
249 m_brkPt.SetCondition( m_brkPtCondition.c_str() );
250 if( m_bBrkPtThreadId )
251 m_brkPt.SetThreadID( m_nBrkPtThreadId );
252 if( !m_brkPt.IsValid() )
253 m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
256 // CODETAG_LLDB_BREAKPOINT_CREATION
257 // This is in the main thread
258 // Record break point information to be by LLDB event handler function
259 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
260 sBrkPtInfo.m_id = m_brkPt.GetID();
261 sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
262 sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
263 sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
264 sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
265 sBrkPtInfo.m_strOrigLoc = m_brkName;
266 sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
267 sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
268 sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
269 sBrkPtInfo.m_strCondition = m_brkPtCondition;
270 sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
271 sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
272 bOk = bOk && rSessionInfo.RecordBrkPtInfo( m_brkPt.GetID(), sBrkPtInfo );
276 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_brkName.c_str() ) );
277 return MIstatus::failure;
280 // CODETAG_LLDB_BRKPT_ID_MAX
281 if( m_brkPt.GetID() > (lldb::break_id_t) rSessionInfo.m_nBrkPointCntMax )
283 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED ), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax, m_brkName.c_str() ) );
284 return MIstatus::failure;
287 return MIstatus::success;
290 //++ ------------------------------------------------------------------------------------
291 // Details: The invoker requires this function. The command prepares a MI Record Result
292 // for the work carried out in the Execute().
295 // Return: MIstatus::success - Functional succeeded.
296 // MIstatus::failure - Functional failed.
299 bool CMICmdCmdBreakInsert::Acknowledge( void )
301 // Get breakpoint information
302 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
303 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
304 if( !rSessionInfo.GetBrkPtInfo( m_brkPt, sBrkPtInfo ) )
306 return MIstatus::failure;
309 // CODETAG_LLDB_BREAKPOINT_CREATION
310 // Add more breakpoint information or overwrite existing information
311 sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
312 sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
313 sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
314 sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
315 sBrkPtInfo.m_nTimes = m_brkPt.GetNumLocations();
316 sBrkPtInfo.m_strOrigLoc = m_brkName;
317 sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
318 sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
319 sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
320 sBrkPtInfo.m_strCondition = m_brkPtCondition;
321 sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
322 sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
324 // 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\"}"
325 CMICmnMIValueTuple miValueTuple;
326 if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) )
328 return MIstatus::failure;
331 const CMICmnMIValueResult miValueResultD( "bkpt", miValueTuple );
332 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD );
333 m_miResultRecord = miRecordResult;
335 return MIstatus::success;
338 //++ ------------------------------------------------------------------------------------
339 // Details: Required by the CMICmdFactory when registering *this command. The factory
340 // calls this function to create an instance of *this command.
341 // Type: Static method.
343 // Return: CMICmdBase * - Pointer to a new command.
346 CMICmdBase * CMICmdCmdBreakInsert::CreateSelf( void )
348 return new CMICmdCmdBreakInsert();
351 //---------------------------------------------------------------------------------------
352 //---------------------------------------------------------------------------------------
353 //---------------------------------------------------------------------------------------
355 //++ ------------------------------------------------------------------------------------
356 // Details: CMICmdCmdBreakDelete constructor.
362 CMICmdCmdBreakDelete::CMICmdCmdBreakDelete( void )
363 : m_constStrArgNamedBrkPt( "breakpoint" )
364 , m_constStrArgNamedThreadGrp( "thread-group" )
366 // Command factory matches this name with that received from the stdin stream
367 m_strMiCmd = "break-delete";
369 // Required by the CMICmdFactory when registering *this command
370 m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
373 //++ ------------------------------------------------------------------------------------
374 // Details: CMICmdCmdBreakDelete destructor.
375 // Type: Overrideable.
380 CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete( void )
384 //++ ------------------------------------------------------------------------------------
385 // Details: The invoker requires this function. The parses the command line options
386 // arguments to extract values for each of those arguments.
389 // Return: MIstatus::success - Functional succeeded.
390 // MIstatus::failure - Functional failed.
393 bool CMICmdCmdBreakDelete::ParseArgs( void )
395 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
396 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
397 return (bOk && ParseValidateCmdOptions() );
400 //++ ------------------------------------------------------------------------------------
401 // Details: The invoker requires this function. The command does work in this function.
402 // The command is likely to communicate with the LLDB SBDebugger in here.
405 // Return: MIstatus::success - Functional succeeded.
406 // MIstatus::failure - Functional failed.
409 bool CMICmdCmdBreakDelete::Execute( void )
411 CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
413 // ATM we only handle one break point ID
414 MIuint64 nBrk = UINT64_MAX;
415 if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
417 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
418 return MIstatus::failure;
421 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
422 const bool bBrkPt = rSessionInfo.m_lldbTarget.BreakpointDelete( static_cast< lldb::break_id_t >( nBrk ) );
425 const CMIUtilString strBrkNum( CMIUtilString::Format( "%d", nBrk ) );
426 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkNum.c_str() ) );
427 return MIstatus::failure;
430 return MIstatus::success;
433 //++ ------------------------------------------------------------------------------------
434 // Details: The invoker requires this function. The command prepares a MI Record Result
435 // for the work carried out in the Execute().
438 // Return: MIstatus::success - Functional succeeded.
439 // MIstatus::failure - Functional failed.
442 bool CMICmdCmdBreakDelete::Acknowledge( void )
444 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
445 m_miResultRecord = miRecordResult;
447 return MIstatus::success;
450 //++ ------------------------------------------------------------------------------------
451 // Details: Required by the CMICmdFactory when registering *this command. The factory
452 // calls this function to create an instance of *this command.
453 // Type: Static method.
455 // Return: CMICmdBase * - Pointer to a new command.
458 CMICmdBase * CMICmdCmdBreakDelete::CreateSelf( void )
460 return new CMICmdCmdBreakDelete();
463 //---------------------------------------------------------------------------------------
464 //---------------------------------------------------------------------------------------
465 //---------------------------------------------------------------------------------------
467 //++ ------------------------------------------------------------------------------------
468 // Details: CMICmdCmdBreakDisable constructor.
474 CMICmdCmdBreakDisable::CMICmdCmdBreakDisable( void )
475 : m_constStrArgNamedThreadGrp( "thread-group" )
476 , m_constStrArgNamedBrkPt( "breakpoint" )
477 , m_bBrkPtDisabledOk( false )
480 // Command factory matches this name with that received from the stdin stream
481 m_strMiCmd = "break-disable";
483 // Required by the CMICmdFactory when registering *this command
484 m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
487 //++ ------------------------------------------------------------------------------------
488 // Details: CMICmdCmdBreakDisable destructor.
489 // Type: Overrideable.
494 CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable( void )
498 //++ ------------------------------------------------------------------------------------
499 // Details: The invoker requires this function. The parses the command line options
500 // arguments to extract values for each of those arguments.
503 // Return: MIstatus::success - Functional succeeded.
504 // MIstatus::failure - Functional failed.
507 bool CMICmdCmdBreakDisable::ParseArgs( void )
509 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
510 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
511 return (bOk && ParseValidateCmdOptions() );
514 //++ ------------------------------------------------------------------------------------
515 // Details: The invoker requires this function. The command does work in this function.
516 // The command is likely to communicate with the LLDB SBDebugger in here.
519 // Return: MIstatus::success - Functional succeeded.
520 // MIstatus::failure - Functional failed.
523 bool CMICmdCmdBreakDisable::Execute( void )
525 CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
527 // ATM we only handle one break point ID
528 MIuint64 nBrk = UINT64_MAX;
529 if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
531 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
532 return MIstatus::failure;
535 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
536 lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
537 if( brkPt.IsValid() )
539 m_bBrkPtDisabledOk = true;
540 brkPt.SetEnabled( false );
544 return MIstatus::success;
547 //++ ------------------------------------------------------------------------------------
548 // Details: The invoker requires this function. The command prepares a MI Record Result
549 // for the work carried out in the Execute().
552 // Return: MIstatus::success - Functional succeeded.
553 // MIstatus::failure - Functional failed.
556 bool CMICmdCmdBreakDisable::Acknowledge( void )
558 if( m_bBrkPtDisabledOk )
560 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
561 const CMICmnMIValueResult miValueResult( "number", miValueConst );
562 CMICmnMIValueTuple miValueTuple( miValueResult );
563 const CMICmnMIValueConst miValueConst2( "n" );
564 const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
565 bool bOk = miValueTuple.Add( miValueResult2 );
566 const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
567 const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
568 bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
570 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
571 m_miResultRecord = miRecordResult;
575 const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
576 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
577 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
578 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
579 m_miResultRecord = miRecordResult;
581 return MIstatus::success;
584 //++ ------------------------------------------------------------------------------------
585 // Details: Required by the CMICmdFactory when registering *this command. The factory
586 // calls this function to create an instance of *this command.
587 // Type: Static method.
589 // Return: CMICmdBase * - Pointer to a new command.
592 CMICmdBase * CMICmdCmdBreakDisable::CreateSelf( void )
594 return new CMICmdCmdBreakDisable();
597 //---------------------------------------------------------------------------------------
598 //---------------------------------------------------------------------------------------
599 //---------------------------------------------------------------------------------------
601 //++ ------------------------------------------------------------------------------------
602 // Details: CMICmdCmdBreakEnable constructor.
608 CMICmdCmdBreakEnable::CMICmdCmdBreakEnable( void )
609 : m_constStrArgNamedThreadGrp( "thread-group" )
610 , m_constStrArgNamedBrkPt( "breakpoint" )
611 , m_bBrkPtEnabledOk( false )
614 // Command factory matches this name with that received from the stdin stream
615 m_strMiCmd = "break-enable";
617 // Required by the CMICmdFactory when registering *this command
618 m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
621 //++ ------------------------------------------------------------------------------------
622 // Details: CMICmdCmdBreakEnable destructor.
623 // Type: Overrideable.
628 CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable( void )
632 //++ ------------------------------------------------------------------------------------
633 // Details: The invoker requires this function. The parses the command line options
634 // arguments to extract values for each of those arguments.
637 // Return: MIstatus::success - Functional succeeded.
638 // MIstatus::failure - Functional failed.
641 bool CMICmdCmdBreakEnable::ParseArgs( void )
643 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
644 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number ) ) );
645 return (bOk && ParseValidateCmdOptions() );
648 //++ ------------------------------------------------------------------------------------
649 // Details: The invoker requires this function. The command does work in this function.
650 // The command is likely to communicate with the LLDB SBDebugger in here.
653 // Return: MIstatus::success - Functional succeeded.
654 // MIstatus::failure - Functional failed.
657 bool CMICmdCmdBreakEnable::Execute( void )
659 CMICMDBASE_GETOPTION( pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt );
661 // ATM we only handle one break point ID
662 MIuint64 nBrk = UINT64_MAX;
663 if( !pArgBrkPt->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nBrk ) )
665 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str() ) );
666 return MIstatus::failure;
669 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
670 lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( nBrk ) );
671 if( brkPt.IsValid() )
673 m_bBrkPtEnabledOk = true;
674 brkPt.SetEnabled( false );
678 return MIstatus::success;
681 //++ ------------------------------------------------------------------------------------
682 // Details: The invoker requires this function. The command prepares a MI Record Result
683 // for the work carried out in the Execute().
686 // Return: MIstatus::success - Functional succeeded.
687 // MIstatus::failure - Functional failed.
690 bool CMICmdCmdBreakEnable::Acknowledge( void )
692 if( m_bBrkPtEnabledOk )
694 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", m_nBrkPtId ) );
695 const CMICmnMIValueResult miValueResult( "number", miValueConst );
696 CMICmnMIValueTuple miValueTuple( miValueResult );
697 const CMICmnMIValueConst miValueConst2( "y" );
698 const CMICmnMIValueResult miValueResult2( "enabled", miValueConst2 );
699 bool bOk = miValueTuple.Add( miValueResult2 );
700 const CMICmnMIValueResult miValueResult3( "bkpt", miValueTuple );
701 const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3 );
702 bOk = bOk && CMICmnStreamStdout::TextToStdout( miOutOfBandRecord.GetString() );
704 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
705 m_miResultRecord = miRecordResult;
709 const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
710 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), strBrkPtId.c_str() ) );
711 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
712 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
713 m_miResultRecord = miRecordResult;
715 return MIstatus::success;
718 //++ ------------------------------------------------------------------------------------
719 // Details: Required by the CMICmdFactory when registering *this command. The factory
720 // calls this function to create an instance of *this command.
721 // Type: Static method.
723 // Return: CMICmdBase * - Pointer to a new command.
726 CMICmdBase * CMICmdCmdBreakEnable::CreateSelf( void )
728 return new CMICmdCmdBreakEnable();
731 //---------------------------------------------------------------------------------------
732 //---------------------------------------------------------------------------------------
733 //---------------------------------------------------------------------------------------
735 //++ ------------------------------------------------------------------------------------
736 // Details: CMICmdCmdBreakAfter constructor.
742 CMICmdCmdBreakAfter::CMICmdCmdBreakAfter( void )
743 : m_constStrArgNamedThreadGrp( "thread-group" )
744 , m_constStrArgNamedNumber( "number" )
745 , m_constStrArgNamedCount( "count" )
749 // Command factory matches this name with that received from the stdin stream
750 m_strMiCmd = "break-after";
752 // Required by the CMICmdFactory when registering *this command
753 m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
756 //++ ------------------------------------------------------------------------------------
757 // Details: CMICmdCmdBreakAfter destructor.
758 // Type: Overrideable.
763 CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter( void )
767 //++ ------------------------------------------------------------------------------------
768 // Details: The invoker requires this function. The parses the command line options
769 // arguments to extract values for each of those arguments.
772 // Return: MIstatus::success - Functional succeeded.
773 // MIstatus::failure - Functional failed.
776 bool CMICmdCmdBreakAfter::ParseArgs( void )
778 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
779 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
780 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedCount, true, true ) ) );
781 return (bOk && ParseValidateCmdOptions() );
784 //++ ------------------------------------------------------------------------------------
785 // Details: The invoker requires this function. The command does work in this function.
786 // The command is likely to communicate with the LLDB SBDebugger in here.
789 // Return: MIstatus::success - Functional succeeded.
790 // MIstatus::failure - Functional failed.
793 bool CMICmdCmdBreakAfter::Execute( void )
795 CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
796 CMICMDBASE_GETOPTION( pArgCount, Number, m_constStrArgNamedCount );
798 m_nBrkPtId = pArgNumber->GetValue();
799 m_nBrkPtCount = pArgCount->GetValue();
801 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
802 lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
803 if( brkPt.IsValid() )
805 brkPt.SetIgnoreCount( m_nBrkPtCount );
807 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
808 if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
810 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
811 return MIstatus::failure;
813 sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
814 rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
818 const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
819 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
820 return MIstatus::failure;
823 return MIstatus::success;
826 //++ ------------------------------------------------------------------------------------
827 // Details: The invoker requires this function. The command prepares a MI Record Result
828 // for the work carried out in the Execute().
831 // Return: MIstatus::success - Functional succeeded.
832 // MIstatus::failure - Functional failed.
835 bool CMICmdCmdBreakAfter::Acknowledge( void )
837 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
838 m_miResultRecord = miRecordResult;
840 return MIstatus::success;
843 //++ ------------------------------------------------------------------------------------
844 // Details: Required by the CMICmdFactory when registering *this command. The factory
845 // calls this function to create an instance of *this command.
846 // Type: Static method.
848 // Return: CMICmdBase * - Pointer to a new command.
851 CMICmdBase * CMICmdCmdBreakAfter::CreateSelf( void )
853 return new CMICmdCmdBreakAfter();
856 //---------------------------------------------------------------------------------------
857 //---------------------------------------------------------------------------------------
858 //---------------------------------------------------------------------------------------
860 //++ ------------------------------------------------------------------------------------
861 // Details: CMICmdCmdBreakCondition constructor.
867 CMICmdCmdBreakCondition::CMICmdCmdBreakCondition( void )
868 : m_constStrArgNamedThreadGrp( "thread-group" )
869 , m_constStrArgNamedNumber( "number" )
870 , m_constStrArgNamedExpr( "expr" )
871 , m_constStrArgNamedExprNoQuotes( "expression not surround by quotes" ) // Not specified in MI spec, we need to handle expressions not surrounded by quotes
874 // Command factory matches this name with that received from the stdin stream
875 m_strMiCmd = "break-condition";
877 // Required by the CMICmdFactory when registering *this command
878 m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
881 //++ ------------------------------------------------------------------------------------
882 // Details: CMICmdCmdBreakCondition destructor.
883 // Type: Overrideable.
888 CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition( void )
892 //++ ------------------------------------------------------------------------------------
893 // Details: The invoker requires this function. The parses the command line options
894 // arguments to extract values for each of those arguments.
897 // Return: MIstatus::success - Functional succeeded.
898 // MIstatus::failure - Functional failed.
901 bool CMICmdCmdBreakCondition::ParseArgs( void )
903 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgNamedThreadGrp, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
904 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNamedNumber, true, true ) ) );
905 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedExpr, true, true, true, true ) ) );
906 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgNamedExprNoQuotes, true, false, CMICmdArgValListBase::eArgValType_StringQuotedNumber ) ) );
907 return (bOk && ParseValidateCmdOptions() );
910 //++ ------------------------------------------------------------------------------------
911 // Details: The invoker requires this function. The command does work in this function.
912 // The command is likely to communicate with the LLDB SBDebugger in here.
915 // Return: MIstatus::success - Functional succeeded.
916 // MIstatus::failure - Functional failed.
919 bool CMICmdCmdBreakCondition::Execute( void )
921 CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNamedNumber );
922 CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgNamedExpr );
924 m_nBrkPtId = pArgNumber->GetValue();
925 m_strBrkPtExpr = pArgExpr->GetValue();
926 m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
928 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
929 lldb::SBBreakpoint brkPt = rSessionInfo.m_lldbTarget.FindBreakpointByID( static_cast< lldb::break_id_t >( m_nBrkPtId ) );
930 if( brkPt.IsValid() )
932 brkPt.SetCondition( m_strBrkPtExpr.c_str() );
934 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
935 if( !rSessionInfo.RecordBrkPtInfoGet( m_nBrkPtId, sBrkPtInfo ) )
937 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND ), m_cmdData.strMiCmd.c_str(), m_nBrkPtId ) );
938 return MIstatus::failure;
940 sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
941 rSessionInfo.RecordBrkPtInfo( m_nBrkPtId, sBrkPtInfo );
945 const CMIUtilString strBrkPtId( CMIUtilString::Format( "%d", m_nBrkPtId ) );
946 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_INVALID ), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str() ) );
947 return MIstatus::failure;
950 return MIstatus::success;
953 //++ ------------------------------------------------------------------------------------
954 // Details: The invoker requires this function. The command prepares a MI Record Result
955 // for the work carried out in the Execute().
958 // Return: MIstatus::success - Functional succeeded.
959 // MIstatus::failure - Functional failed.
962 bool CMICmdCmdBreakCondition::Acknowledge( void )
964 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
965 m_miResultRecord = miRecordResult;
967 return MIstatus::success;
970 //++ ------------------------------------------------------------------------------------
971 // Details: Required by the CMICmdFactory when registering *this command. The factory
972 // calls this function to create an instance of *this command.
973 // Type: Static method.
975 // Return: CMICmdBase * - Pointer to a new command.
978 CMICmdBase * CMICmdCmdBreakCondition::CreateSelf( void )
980 return new CMICmdCmdBreakCondition();
983 //++ ------------------------------------------------------------------------------------
984 // Details: A breakpoint expression can be passed to *this command as:
985 // a single string i.e. '2' -> ok.
986 // a quoted string i.e. "a > 100" -> ok
987 // a non quoted string i.e. 'a > 100' -> not ok
988 // CMICmdArgValString only extracts the first space seperated string, the "a".
989 // This function using the optional argument type CMICmdArgValListOfN collects
990 // the rest of the expression so that is may be added to the 'a' part to form a
991 // complete expression string i.e. "a > 100".
992 // If the expression value was guaranteed to be surrounded by quotes them this
993 // function would not be necessary.
996 // Return: CMIUtilString - Rest of the breakpoint expression.
999 CMIUtilString CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes( void )
1001 CMIUtilString strExpression;
1003 CMICmdArgValListOfN * pArgExprNoQuotes = CMICmdBase::GetOption< CMICmdArgValListOfN >( m_constStrArgNamedExprNoQuotes );
1004 if( pArgExprNoQuotes != nullptr )
1006 CMIUtilString strExpression;
1007 const CMICmdArgValListBase::VecArgObjPtr_t & rVecExprParts( pArgExprNoQuotes->GetExpectedOptions() );
1008 if( !rVecExprParts.empty() )
1010 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin();
1011 while( it != rVecExprParts.end() )
1013 const CMICmdArgValString * pPartExpr = static_cast< CMICmdArgValString * >( *it );
1014 const CMIUtilString & rPartExpr = pPartExpr->GetValue();
1015 strExpression += " ";
1016 strExpression += rPartExpr;
1021 strExpression = strExpression.Trim();
1025 return strExpression;