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 //===----------------------------------------------------------------------===//
10 // Overview: CMICmdCmdBreakInsert implementation.
11 // CMICmdCmdBreakDelete implementation.
12 // CMICmdCmdBreakDisable implementation.
13 // CMICmdCmdBreakEnable implementation.
14 // CMICmdCmdBreakAfter implementation.
15 // CMICmdCmdBreakCondition implementation.
17 // Third Party Headers:
18 #include "lldb/API/SBBreakpointLocation.h"
21 #include "MICmdCmdBreak.h"
22 #include "MICmnMIResultRecord.h"
23 #include "MICmnMIValueConst.h"
24 #include "MICmnMIOutOfBandRecord.h"
25 #include "MICmnLLDBDebugger.h"
26 #include "MICmnLLDBDebugSessionInfo.h"
27 #include "MICmdArgValFile.h"
28 #include "MICmdArgValNumber.h"
29 #include "MICmdArgValString.h"
30 #include "MICmdArgValThreadGrp.h"
31 #include "MICmdArgValOptionLong.h"
32 #include "MICmdArgValOptionShort.h"
33 #include "MICmdArgValListOfN.h"
34 #include "MICmnStreamStdout.h"
36 //++ ------------------------------------------------------------------------------------
37 // Details: CMICmdCmdBreakInsert constructor.
43 CMICmdCmdBreakInsert::CMICmdCmdBreakInsert()
44 : m_bBrkPtIsTemp(false)
45 , m_bBrkPtIsPending(false)
46 , m_nBrkPtIgnoreCount(0)
47 , m_bBrkPtEnabled(false)
48 , m_bBrkPtCondition(false)
49 , m_bBrkPtThreadId(false)
51 , m_constStrArgNamedTempBrkPt("t")
52 , m_constStrArgNamedHWBrkPt("h")
53 , m_constStrArgNamedPendinfBrkPt("f")
54 , m_constStrArgNamedDisableBrkPt("d")
55 , m_constStrArgNamedTracePt("a")
56 , m_constStrArgNamedConditionalBrkPt("c")
57 , m_constStrArgNamedInoreCnt("i")
58 , m_constStrArgNamedRestrictBrkPtToThreadId("p")
59 , m_constStrArgNamedLocation("location")
61 // Command factory matches this name with that received from the stdin stream
62 m_strMiCmd = "break-insert";
64 // Required by the CMICmdFactory when registering *this command
65 m_pSelfCreatorFn = &CMICmdCmdBreakInsert::CreateSelf;
68 //++ ------------------------------------------------------------------------------------
69 // Details: CMICmdCmdBreakInsert destructor.
70 // Type: Overrideable.
75 CMICmdCmdBreakInsert::~CMICmdCmdBreakInsert()
79 //++ ------------------------------------------------------------------------------------
80 // Details: The invoker requires this function. The parses the command line options
81 // arguments to extract values for each of those arguments.
84 // Return: MIstatus::success - Functional succeeded.
85 // MIstatus::failure - Functional failed.
89 CMICmdCmdBreakInsert::ParseArgs()
91 m_setCmdArgs.Add(new CMICmdArgValOptionShort(m_constStrArgNamedTempBrkPt, false, true));
92 // Not implemented m_setCmdArgs.Add(new CMICmdArgValOptionShort( m_constStrArgNamedHWBrkPt, false, false));
93 m_setCmdArgs.Add(new CMICmdArgValOptionShort(m_constStrArgNamedPendinfBrkPt, false, true,
94 CMICmdArgValListBase::eArgValType_StringQuotedNumberPath, 1));
95 m_setCmdArgs.Add(new CMICmdArgValOptionShort(m_constStrArgNamedDisableBrkPt, false, false));
96 // Not implemented m_setCmdArgs.Add(new CMICmdArgValOptionShort( m_constStrArgNamedTracePt, false, false));
97 m_setCmdArgs.Add(new CMICmdArgValOptionShort(m_constStrArgNamedConditionalBrkPt, false, true,
98 CMICmdArgValListBase::eArgValType_StringQuoted, 1));
100 new CMICmdArgValOptionShort(m_constStrArgNamedInoreCnt, false, true, CMICmdArgValListBase::eArgValType_Number, 1));
101 m_setCmdArgs.Add(new CMICmdArgValOptionShort(m_constStrArgNamedRestrictBrkPtToThreadId, false, true,
102 CMICmdArgValListBase::eArgValType_Number, 1));
103 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedLocation, false, true));
104 return ParseValidateCmdOptions();
107 //++ ------------------------------------------------------------------------------------
108 // Helper function for CMICmdCmdBreakInsert::Execute().
110 // Given a string, return the position of the ':' separator in 'file:func'
111 // or 'file:line', if any. If not found, return npos. For example, return
112 // 5 for 'foo.c:std::string'.
114 static size_t findFileSeparatorPos(const std::string& x)
116 // Full paths in windows can have ':' after a drive letter, so we
117 // search backwards, taking care to skip C++ namespace tokens '::'.
118 size_t n = x.rfind(':');
119 while (n != std::string::npos && n > 1 && x[n-1] == ':')
121 n = x.rfind(':', n - 2);
126 //++ ------------------------------------------------------------------------------------
127 // Details: The invoker requires this function. The command does work in this function.
128 // The command is likely to communicate with the LLDB SBDebugger in here.
131 // Return: MIstatus::success - Functional succeeded.
132 // MIstatus::failure - Functional failed.
136 CMICmdCmdBreakInsert::Execute()
138 CMICMDBASE_GETOPTION(pArgTempBrkPt, OptionShort, m_constStrArgNamedTempBrkPt);
139 CMICMDBASE_GETOPTION(pArgThreadGroup, OptionLong, m_constStrArgThreadGroup);
140 CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgNamedLocation);
141 CMICMDBASE_GETOPTION(pArgIgnoreCnt, OptionShort, m_constStrArgNamedInoreCnt);
142 CMICMDBASE_GETOPTION(pArgPendingBrkPt, OptionShort, m_constStrArgNamedPendinfBrkPt);
143 CMICMDBASE_GETOPTION(pArgDisableBrkPt, OptionShort, m_constStrArgNamedDisableBrkPt);
144 CMICMDBASE_GETOPTION(pArgConditionalBrkPt, OptionShort, m_constStrArgNamedConditionalBrkPt);
145 CMICMDBASE_GETOPTION(pArgRestrictBrkPtToThreadId, OptionShort, m_constStrArgNamedRestrictBrkPtToThreadId);
147 m_bBrkPtEnabled = !pArgDisableBrkPt->GetFound();
148 m_bBrkPtIsTemp = pArgTempBrkPt->GetFound();
149 m_bHaveArgOptionThreadGrp = pArgThreadGroup->GetFound();
150 if (m_bHaveArgOptionThreadGrp)
152 MIuint nThreadGrp = 0;
153 pArgThreadGroup->GetExpectedOption<CMICmdArgValThreadGrp, MIuint>(nThreadGrp);
154 m_strArgOptionThreadGrp = CMIUtilString::Format("i%d", nThreadGrp);
156 m_bBrkPtIsPending = pArgPendingBrkPt->GetFound();
157 if (pArgLocation->GetFound())
158 m_brkName = pArgLocation->GetValue();
159 else if (m_bBrkPtIsPending)
161 pArgPendingBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkName);
163 if (pArgIgnoreCnt->GetFound())
165 pArgIgnoreCnt->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtIgnoreCount);
167 m_bBrkPtCondition = pArgConditionalBrkPt->GetFound();
168 if (m_bBrkPtCondition)
170 pArgConditionalBrkPt->GetExpectedOption<CMICmdArgValString, CMIUtilString>(m_brkPtCondition);
172 m_bBrkPtThreadId = pArgRestrictBrkPtToThreadId->GetFound();
173 if (m_bBrkPtCondition)
175 pArgRestrictBrkPtToThreadId->GetExpectedOption<CMICmdArgValNumber, MIuint>(m_nBrkPtThreadId);
178 // Determine if break on a file line or at a function
179 BreakPoint_e eBrkPtType = eBreakPoint_NotDefineYet;
180 CMIUtilString fileName;
181 MIuint nFileLine = 0;
182 CMIUtilString strFileFn;
183 CMIUtilString rStrLineOrFn;
184 // Is the string in the form 'file:func' or 'file:line'?
185 // If so, find the position of the ':' separator.
186 const size_t nPosColon = findFileSeparatorPos(m_brkName);
187 if (nPosColon != std::string::npos)
189 // Extract file name and line number from it
190 fileName = m_brkName.substr(0, nPosColon);
191 rStrLineOrFn = m_brkName.substr(nPosColon + 1, m_brkName.size() - nPosColon - 1);
193 if (rStrLineOrFn.empty())
194 eBrkPtType = eBreakPoint_ByName;
198 if (rStrLineOrFn.ExtractNumber(nValue))
200 nFileLine = static_cast<MIuint>(nValue);
201 eBrkPtType = eBreakPoint_ByFileLine;
205 strFileFn = rStrLineOrFn;
206 eBrkPtType = eBreakPoint_ByFileFn;
211 // Determine if break defined as an address
212 lldb::addr_t nAddress = 0;
213 if (eBrkPtType == eBreakPoint_NotDefineYet)
216 if (m_brkName.ExtractNumber(nValue))
218 nAddress = static_cast<lldb::addr_t>(nValue);
219 eBrkPtType = eBreakPoint_ByAddress;
223 // Break defined as an function
224 if (eBrkPtType == eBreakPoint_NotDefineYet)
226 eBrkPtType = eBreakPoint_ByName;
229 // Ask LLDB to create a breakpoint
230 bool bOk = MIstatus::success;
231 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
232 lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
235 case eBreakPoint_ByAddress:
236 m_brkPt = sbTarget.BreakpointCreateByAddress(nAddress);
238 case eBreakPoint_ByFileFn:
240 lldb::SBFileSpecList module; // search in all modules
241 lldb::SBFileSpecList compUnit;
242 compUnit.Append (lldb::SBFileSpec(fileName.c_str()));
243 m_brkPt = sbTarget.BreakpointCreateByName(strFileFn.c_str(), module, compUnit);
246 case eBreakPoint_ByFileLine:
247 m_brkPt = sbTarget.BreakpointCreateByLocation(fileName.c_str(), nFileLine);
249 case eBreakPoint_ByName:
250 m_brkPt = sbTarget.BreakpointCreateByName(m_brkName.c_str(), nullptr);
252 case eBreakPoint_count:
253 case eBreakPoint_NotDefineYet:
254 case eBreakPoint_Invalid:
255 bOk = MIstatus::failure;
261 if (!m_bBrkPtIsPending && (m_brkPt.GetNumLocations() == 0))
263 sbTarget.BreakpointDelete(m_brkPt.GetID());
264 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_LOCATION_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
265 return MIstatus::failure;
268 m_brkPt.SetEnabled(m_bBrkPtEnabled);
269 m_brkPt.SetIgnoreCount(m_nBrkPtIgnoreCount);
270 if (m_bBrkPtCondition)
271 m_brkPt.SetCondition(m_brkPtCondition.c_str());
272 if (m_bBrkPtThreadId)
273 m_brkPt.SetThreadID(m_nBrkPtThreadId);
276 // CODETAG_LLDB_BREAKPOINT_CREATION
277 // This is in the main thread
278 // Record break point information to be by LLDB event handler function
279 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
280 if (!rSessionInfo.GetBrkPtInfo(m_brkPt, sBrkPtInfo))
281 return MIstatus::failure;
282 sBrkPtInfo.m_id = m_brkPt.GetID();
283 sBrkPtInfo.m_bDisp = m_bBrkPtIsTemp;
284 sBrkPtInfo.m_bEnabled = m_bBrkPtEnabled;
285 sBrkPtInfo.m_bHaveArgOptionThreadGrp = m_bHaveArgOptionThreadGrp;
286 sBrkPtInfo.m_strOptThrdGrp = m_strArgOptionThreadGrp;
287 sBrkPtInfo.m_nTimes = m_brkPt.GetHitCount();
288 sBrkPtInfo.m_strOrigLoc = m_brkName;
289 sBrkPtInfo.m_nIgnore = m_nBrkPtIgnoreCount;
290 sBrkPtInfo.m_bPending = m_bBrkPtIsPending;
291 sBrkPtInfo.m_bCondition = m_bBrkPtCondition;
292 sBrkPtInfo.m_strCondition = m_brkPtCondition;
293 sBrkPtInfo.m_bBrkPtThreadId = m_bBrkPtThreadId;
294 sBrkPtInfo.m_nBrkPtThreadId = m_nBrkPtThreadId;
296 bOk = bOk && rSessionInfo.RecordBrkPtInfo(m_brkPt.GetID(), sBrkPtInfo);
299 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_brkName.c_str()));
300 return MIstatus::failure;
303 // CODETAG_LLDB_BRKPT_ID_MAX
304 if (m_brkPt.GetID() > (lldb::break_id_t)rSessionInfo.m_nBrkPointCntMax)
306 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_CNT_EXCEEDED), m_cmdData.strMiCmd.c_str(), rSessionInfo.m_nBrkPointCntMax,
308 return MIstatus::failure;
311 return MIstatus::success;
314 //++ ------------------------------------------------------------------------------------
315 // Details: The invoker requires this function. The command prepares a MI Record Result
316 // for the work carried out in the Execute().
319 // Return: MIstatus::success - Functional succeeded.
320 // MIstatus::failure - Functional failed.
324 CMICmdCmdBreakInsert::Acknowledge()
326 // Get breakpoint information
327 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
328 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
329 if (!rSessionInfo.RecordBrkPtInfoGet(m_brkPt.GetID(), sBrkPtInfo))
330 return MIstatus::failure;
333 // "^done,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",thread-groups=[\"%s\"],times=\"%d\",original-location=\"%s\"}"
334 CMICmnMIValueTuple miValueTuple;
335 if (!rSessionInfo.MIResponseFormBrkPtInfo(sBrkPtInfo, miValueTuple))
336 return MIstatus::failure;
338 const CMICmnMIValueResult miValueResultD("bkpt", miValueTuple);
339 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResultD);
340 m_miResultRecord = miRecordResult;
342 return MIstatus::success;
345 //++ ------------------------------------------------------------------------------------
346 // Details: Required by the CMICmdFactory when registering *this command. The factory
347 // calls this function to create an instance of *this command.
348 // Type: Static method.
350 // Return: CMICmdBase * - Pointer to a new command.
354 CMICmdCmdBreakInsert::CreateSelf()
356 return new CMICmdCmdBreakInsert();
359 //---------------------------------------------------------------------------------------
360 //---------------------------------------------------------------------------------------
361 //---------------------------------------------------------------------------------------
363 //++ ------------------------------------------------------------------------------------
364 // Details: CMICmdCmdBreakDelete constructor.
370 CMICmdCmdBreakDelete::CMICmdCmdBreakDelete()
371 : m_constStrArgNamedBrkPt("breakpoint")
373 // Command factory matches this name with that received from the stdin stream
374 m_strMiCmd = "break-delete";
376 // Required by the CMICmdFactory when registering *this command
377 m_pSelfCreatorFn = &CMICmdCmdBreakDelete::CreateSelf;
380 //++ ------------------------------------------------------------------------------------
381 // Details: CMICmdCmdBreakDelete destructor.
382 // Type: Overrideable.
387 CMICmdCmdBreakDelete::~CMICmdCmdBreakDelete()
391 //++ ------------------------------------------------------------------------------------
392 // Details: The invoker requires this function. The parses the command line options
393 // arguments to extract values for each of those arguments.
396 // Return: MIstatus::success - Functional succeeded.
397 // MIstatus::failure - Functional failed.
401 CMICmdCmdBreakDelete::ParseArgs()
403 m_setCmdArgs.Add(new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number));
404 return ParseValidateCmdOptions();
407 //++ ------------------------------------------------------------------------------------
408 // Details: The invoker requires this function. The command does work in this function.
409 // The command is likely to communicate with the LLDB SBDebugger in here.
412 // Return: MIstatus::success - Functional succeeded.
413 // MIstatus::failure - Functional failed.
417 CMICmdCmdBreakDelete::Execute()
419 CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
421 // ATM we only handle one break point ID
422 MIuint64 nBrk = UINT64_MAX;
423 if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk))
425 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str()));
426 return MIstatus::failure;
429 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
430 const bool bBrkPt = rSessionInfo.GetTarget().BreakpointDelete(static_cast<lldb::break_id_t>(nBrk));
433 const CMIUtilString strBrkNum(CMIUtilString::Format("%d", nBrk));
434 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), strBrkNum.c_str()));
435 return MIstatus::failure;
438 return MIstatus::success;
441 //++ ------------------------------------------------------------------------------------
442 // Details: The invoker requires this function. The command prepares a MI Record Result
443 // for the work carried out in the Execute().
446 // Return: MIstatus::success - Functional succeeded.
447 // MIstatus::failure - Functional failed.
451 CMICmdCmdBreakDelete::Acknowledge()
453 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
454 m_miResultRecord = miRecordResult;
456 return MIstatus::success;
459 //++ ------------------------------------------------------------------------------------
460 // Details: Required by the CMICmdFactory when registering *this command. The factory
461 // calls this function to create an instance of *this command.
462 // Type: Static method.
464 // Return: CMICmdBase * - Pointer to a new command.
468 CMICmdCmdBreakDelete::CreateSelf()
470 return new CMICmdCmdBreakDelete();
473 //---------------------------------------------------------------------------------------
474 //---------------------------------------------------------------------------------------
475 //---------------------------------------------------------------------------------------
477 //++ ------------------------------------------------------------------------------------
478 // Details: CMICmdCmdBreakDisable constructor.
484 CMICmdCmdBreakDisable::CMICmdCmdBreakDisable()
485 : m_constStrArgNamedBrkPt("breakpoint")
486 , m_bBrkPtDisabledOk(false)
489 // Command factory matches this name with that received from the stdin stream
490 m_strMiCmd = "break-disable";
492 // Required by the CMICmdFactory when registering *this command
493 m_pSelfCreatorFn = &CMICmdCmdBreakDisable::CreateSelf;
496 //++ ------------------------------------------------------------------------------------
497 // Details: CMICmdCmdBreakDisable destructor.
498 // Type: Overrideable.
503 CMICmdCmdBreakDisable::~CMICmdCmdBreakDisable()
507 //++ ------------------------------------------------------------------------------------
508 // Details: The invoker requires this function. The parses the command line options
509 // arguments to extract values for each of those arguments.
512 // Return: MIstatus::success - Functional succeeded.
513 // MIstatus::failure - Functional failed.
517 CMICmdCmdBreakDisable::ParseArgs()
519 m_setCmdArgs.Add(new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number));
520 return ParseValidateCmdOptions();
523 //++ ------------------------------------------------------------------------------------
524 // Details: The invoker requires this function. The command does work in this function.
525 // The command is likely to communicate with the LLDB SBDebugger in here.
528 // Return: MIstatus::success - Functional succeeded.
529 // MIstatus::failure - Functional failed.
533 CMICmdCmdBreakDisable::Execute()
535 CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
537 // ATM we only handle one break point ID
538 MIuint64 nBrk = UINT64_MAX;
539 if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk))
541 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str()));
542 return MIstatus::failure;
545 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
546 lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
549 m_bBrkPtDisabledOk = true;
550 brkPt.SetEnabled(false);
554 return MIstatus::success;
557 //++ ------------------------------------------------------------------------------------
558 // Details: The invoker requires this function. The command prepares a MI Record Result
559 // for the work carried out in the Execute().
562 // Return: MIstatus::success - Functional succeeded.
563 // MIstatus::failure - Functional failed.
567 CMICmdCmdBreakDisable::Acknowledge()
569 if (m_bBrkPtDisabledOk)
571 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId));
572 const CMICmnMIValueResult miValueResult("number", miValueConst);
573 CMICmnMIValueTuple miValueTuple(miValueResult);
574 const CMICmnMIValueConst miValueConst2("n");
575 const CMICmnMIValueResult miValueResult2("enabled", miValueConst2);
576 miValueTuple.Add(miValueResult2);
577 const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple);
578 const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3);
579 bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
581 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
582 m_miResultRecord = miRecordResult;
586 const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
587 const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
588 const CMICmnMIValueResult miValueResult("msg", miValueConst);
589 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
590 m_miResultRecord = miRecordResult;
592 return MIstatus::success;
595 //++ ------------------------------------------------------------------------------------
596 // Details: Required by the CMICmdFactory when registering *this command. The factory
597 // calls this function to create an instance of *this command.
598 // Type: Static method.
600 // Return: CMICmdBase * - Pointer to a new command.
604 CMICmdCmdBreakDisable::CreateSelf()
606 return new CMICmdCmdBreakDisable();
609 //---------------------------------------------------------------------------------------
610 //---------------------------------------------------------------------------------------
611 //---------------------------------------------------------------------------------------
613 //++ ------------------------------------------------------------------------------------
614 // Details: CMICmdCmdBreakEnable constructor.
620 CMICmdCmdBreakEnable::CMICmdCmdBreakEnable()
621 : m_constStrArgNamedBrkPt("breakpoint")
622 , m_bBrkPtEnabledOk(false)
625 // Command factory matches this name with that received from the stdin stream
626 m_strMiCmd = "break-enable";
628 // Required by the CMICmdFactory when registering *this command
629 m_pSelfCreatorFn = &CMICmdCmdBreakEnable::CreateSelf;
632 //++ ------------------------------------------------------------------------------------
633 // Details: CMICmdCmdBreakEnable destructor.
634 // Type: Overrideable.
639 CMICmdCmdBreakEnable::~CMICmdCmdBreakEnable()
643 //++ ------------------------------------------------------------------------------------
644 // Details: The invoker requires this function. The parses the command line options
645 // arguments to extract values for each of those arguments.
648 // Return: MIstatus::success - Functional succeeded.
649 // MIstatus::failure - Functional failed.
653 CMICmdCmdBreakEnable::ParseArgs()
655 m_setCmdArgs.Add(new CMICmdArgValListOfN(m_constStrArgNamedBrkPt, true, true, CMICmdArgValListBase::eArgValType_Number));
656 return ParseValidateCmdOptions();
659 //++ ------------------------------------------------------------------------------------
660 // Details: The invoker requires this function. The command does work in this function.
661 // The command is likely to communicate with the LLDB SBDebugger in here.
664 // Return: MIstatus::success - Functional succeeded.
665 // MIstatus::failure - Functional failed.
669 CMICmdCmdBreakEnable::Execute()
671 CMICMDBASE_GETOPTION(pArgBrkPt, ListOfN, m_constStrArgNamedBrkPt);
673 // ATM we only handle one break point ID
674 MIuint64 nBrk = UINT64_MAX;
675 if (!pArgBrkPt->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nBrk))
677 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgNamedBrkPt.c_str()));
678 return MIstatus::failure;
681 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
682 lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(nBrk));
685 m_bBrkPtEnabledOk = true;
686 brkPt.SetEnabled(false);
690 return MIstatus::success;
693 //++ ------------------------------------------------------------------------------------
694 // Details: The invoker requires this function. The command prepares a MI Record Result
695 // for the work carried out in the Execute().
698 // Return: MIstatus::success - Functional succeeded.
699 // MIstatus::failure - Functional failed.
703 CMICmdCmdBreakEnable::Acknowledge()
705 if (m_bBrkPtEnabledOk)
707 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", m_nBrkPtId));
708 const CMICmnMIValueResult miValueResult("number", miValueConst);
709 CMICmnMIValueTuple miValueTuple(miValueResult);
710 const CMICmnMIValueConst miValueConst2("y");
711 const CMICmnMIValueResult miValueResult2("enabled", miValueConst2);
712 miValueTuple.Add(miValueResult2);
713 const CMICmnMIValueResult miValueResult3("bkpt", miValueTuple);
714 const CMICmnMIOutOfBandRecord miOutOfBandRecord(CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult3);
715 bool bOk = CMICmnStreamStdout::TextToStdout(miOutOfBandRecord.GetString());
717 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
718 m_miResultRecord = miRecordResult;
722 const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
723 const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), strBrkPtId.c_str()));
724 const CMICmnMIValueResult miValueResult("msg", miValueConst);
725 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
726 m_miResultRecord = miRecordResult;
728 return MIstatus::success;
731 //++ ------------------------------------------------------------------------------------
732 // Details: Required by the CMICmdFactory when registering *this command. The factory
733 // calls this function to create an instance of *this command.
734 // Type: Static method.
736 // Return: CMICmdBase * - Pointer to a new command.
740 CMICmdCmdBreakEnable::CreateSelf()
742 return new CMICmdCmdBreakEnable();
745 //---------------------------------------------------------------------------------------
746 //---------------------------------------------------------------------------------------
747 //---------------------------------------------------------------------------------------
749 //++ ------------------------------------------------------------------------------------
750 // Details: CMICmdCmdBreakAfter constructor.
756 CMICmdCmdBreakAfter::CMICmdCmdBreakAfter()
757 : m_constStrArgNamedNumber("number")
758 , m_constStrArgNamedCount("count")
762 // Command factory matches this name with that received from the stdin stream
763 m_strMiCmd = "break-after";
765 // Required by the CMICmdFactory when registering *this command
766 m_pSelfCreatorFn = &CMICmdCmdBreakAfter::CreateSelf;
769 //++ ------------------------------------------------------------------------------------
770 // Details: CMICmdCmdBreakAfter destructor.
771 // Type: Overrideable.
776 CMICmdCmdBreakAfter::~CMICmdCmdBreakAfter()
780 //++ ------------------------------------------------------------------------------------
781 // Details: The invoker requires this function. The parses the command line options
782 // arguments to extract values for each of those arguments.
785 // Return: MIstatus::success - Functional succeeded.
786 // MIstatus::failure - Functional failed.
790 CMICmdCmdBreakAfter::ParseArgs()
792 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true));
793 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNamedCount, true, true));
794 return ParseValidateCmdOptions();
797 //++ ------------------------------------------------------------------------------------
798 // Details: The invoker requires this function. The command does work in this function.
799 // The command is likely to communicate with the LLDB SBDebugger in here.
802 // Return: MIstatus::success - Functional succeeded.
803 // MIstatus::failure - Functional failed.
807 CMICmdCmdBreakAfter::Execute()
809 CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
810 CMICMDBASE_GETOPTION(pArgCount, Number, m_constStrArgNamedCount);
812 m_nBrkPtId = pArgNumber->GetValue();
813 m_nBrkPtCount = pArgCount->GetValue();
815 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
816 lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
819 brkPt.SetIgnoreCount(m_nBrkPtCount);
821 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
822 if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo))
824 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
825 return MIstatus::failure;
827 sBrkPtInfo.m_nIgnore = m_nBrkPtCount;
828 rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
832 const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
833 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str()));
834 return MIstatus::failure;
837 return MIstatus::success;
840 //++ ------------------------------------------------------------------------------------
841 // Details: The invoker requires this function. The command prepares a MI Record Result
842 // for the work carried out in the Execute().
845 // Return: MIstatus::success - Functional succeeded.
846 // MIstatus::failure - Functional failed.
850 CMICmdCmdBreakAfter::Acknowledge()
852 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
853 m_miResultRecord = miRecordResult;
855 return MIstatus::success;
858 //++ ------------------------------------------------------------------------------------
859 // Details: Required by the CMICmdFactory when registering *this command. The factory
860 // calls this function to create an instance of *this command.
861 // Type: Static method.
863 // Return: CMICmdBase * - Pointer to a new command.
867 CMICmdCmdBreakAfter::CreateSelf()
869 return new CMICmdCmdBreakAfter();
872 //---------------------------------------------------------------------------------------
873 //---------------------------------------------------------------------------------------
874 //---------------------------------------------------------------------------------------
876 //++ ------------------------------------------------------------------------------------
877 // Details: CMICmdCmdBreakCondition constructor.
883 CMICmdCmdBreakCondition::CMICmdCmdBreakCondition()
884 : m_constStrArgNamedNumber("number")
885 , m_constStrArgNamedExpr("expr")
886 , m_constStrArgNamedExprNoQuotes(
887 "expression not surround by quotes") // Not specified in MI spec, we need to handle expressions not surrounded by quotes
890 // Command factory matches this name with that received from the stdin stream
891 m_strMiCmd = "break-condition";
893 // Required by the CMICmdFactory when registering *this command
894 m_pSelfCreatorFn = &CMICmdCmdBreakCondition::CreateSelf;
897 //++ ------------------------------------------------------------------------------------
898 // Details: CMICmdCmdBreakCondition destructor.
899 // Type: Overrideable.
904 CMICmdCmdBreakCondition::~CMICmdCmdBreakCondition()
908 //++ ------------------------------------------------------------------------------------
909 // Details: The invoker requires this function. The parses the command line options
910 // arguments to extract values for each of those arguments.
913 // Return: MIstatus::success - Functional succeeded.
914 // MIstatus::failure - Functional failed.
918 CMICmdCmdBreakCondition::ParseArgs()
920 m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNamedNumber, true, true));
921 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedExpr, true, true, true, true));
922 m_setCmdArgs.Add(new CMICmdArgValListOfN(m_constStrArgNamedExprNoQuotes, false, false,
923 CMICmdArgValListBase::eArgValType_StringQuotedNumber));
924 return ParseValidateCmdOptions();
927 //++ ------------------------------------------------------------------------------------
928 // Details: The invoker requires this function. The command does work in this function.
929 // The command is likely to communicate with the LLDB SBDebugger in here.
932 // Return: MIstatus::success - Functional succeeded.
933 // MIstatus::failure - Functional failed.
937 CMICmdCmdBreakCondition::Execute()
939 CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNamedNumber);
940 CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgNamedExpr);
942 m_nBrkPtId = pArgNumber->GetValue();
943 m_strBrkPtExpr = pArgExpr->GetValue();
944 m_strBrkPtExpr += GetRestOfExpressionNotSurroundedInQuotes();
946 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
947 lldb::SBBreakpoint brkPt = rSessionInfo.GetTarget().FindBreakpointByID(static_cast<lldb::break_id_t>(m_nBrkPtId));
950 brkPt.SetCondition(m_strBrkPtExpr.c_str());
952 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
953 if (!rSessionInfo.RecordBrkPtInfoGet(m_nBrkPtId, sBrkPtInfo))
955 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INFO_OBJ_NOT_FOUND), m_cmdData.strMiCmd.c_str(), m_nBrkPtId));
956 return MIstatus::failure;
958 sBrkPtInfo.m_strCondition = m_strBrkPtExpr;
959 rSessionInfo.RecordBrkPtInfo(m_nBrkPtId, sBrkPtInfo);
963 const CMIUtilString strBrkPtId(CMIUtilString::Format("%d", m_nBrkPtId));
964 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_BRKPT_INVALID), m_cmdData.strMiCmd.c_str(), strBrkPtId.c_str()));
965 return MIstatus::failure;
968 return MIstatus::success;
971 //++ ------------------------------------------------------------------------------------
972 // Details: The invoker requires this function. The command prepares a MI Record Result
973 // for the work carried out in the Execute().
976 // Return: MIstatus::success - Functional succeeded.
977 // MIstatus::failure - Functional failed.
981 CMICmdCmdBreakCondition::Acknowledge()
983 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
984 m_miResultRecord = miRecordResult;
986 return MIstatus::success;
989 //++ ------------------------------------------------------------------------------------
990 // Details: Required by the CMICmdFactory when registering *this command. The factory
991 // calls this function to create an instance of *this command.
992 // Type: Static method.
994 // Return: CMICmdBase * - Pointer to a new command.
998 CMICmdCmdBreakCondition::CreateSelf()
1000 return new CMICmdCmdBreakCondition();
1003 //++ ------------------------------------------------------------------------------------
1004 // Details: A breakpoint expression can be passed to *this command as:
1005 // a single string i.e. '2' -> ok.
1006 // a quoted string i.e. "a > 100" -> ok
1007 // a non quoted string i.e. 'a > 100' -> not ok
1008 // CMICmdArgValString only extracts the first space separated string, the "a".
1009 // This function using the optional argument type CMICmdArgValListOfN collects
1010 // the rest of the expression so that is may be added to the 'a' part to form a
1011 // complete expression string i.e. "a > 100".
1012 // If the expression value was guaranteed to be surrounded by quotes them this
1013 // function would not be necessary.
1016 // Return: CMIUtilString - Rest of the breakpoint expression.
1020 CMICmdCmdBreakCondition::GetRestOfExpressionNotSurroundedInQuotes()
1022 CMIUtilString strExpression;
1024 CMICmdArgValListOfN *pArgExprNoQuotes = CMICmdBase::GetOption<CMICmdArgValListOfN>(m_constStrArgNamedExprNoQuotes);
1025 if (pArgExprNoQuotes != nullptr)
1027 const CMICmdArgValListBase::VecArgObjPtr_t &rVecExprParts(pArgExprNoQuotes->GetExpectedOptions());
1028 if (!rVecExprParts.empty())
1030 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecExprParts.begin();
1031 while (it != rVecExprParts.end())
1033 const CMICmdArgValString *pPartExpr = static_cast<CMICmdArgValString *>(*it);
1034 const CMIUtilString &rPartExpr = pPartExpr->GetValue();
1035 strExpression += " ";
1036 strExpression += rPartExpr;
1041 strExpression = strExpression.Trim();
1045 return strExpression;