1 //===-- MICmnLLDBDebugSessionInfo.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 // Third party headers:
11 #include <inttypes.h> // For PRIx64
12 #include "lldb/API/SBThread.h"
14 #include <io.h> // For the ::_access()
16 #include <unistd.h> // For the ::access()
18 #include "lldb/API/SBBreakpointLocation.h"
21 #include "MICmdData.h"
22 #include "MICmnLLDBDebugSessionInfo.h"
23 #include "MICmnLLDBDebugger.h"
24 #include "MICmnLLDBUtilSBValue.h"
25 #include "MICmnMIResultRecord.h"
26 #include "MICmnMIValueConst.h"
27 #include "MICmnMIValueList.h"
28 #include "MICmnMIValueTuple.h"
29 #include "MICmnResources.h"
32 //++ ------------------------------------------------------------------------------------
33 // Details: CMICmnLLDBDebugSessionInfo constructor.
39 CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo()
40 : m_nBrkPointCntMax(INT32_MAX)
41 , m_currentSelectedThread(LLDB_INVALID_THREAD_ID)
42 , m_constStrSharedDataKeyWkDir("Working Directory")
43 , m_constStrSharedDataSolibPath("Solib Path")
44 , m_constStrPrintCharArrayAsString("Print CharArrayAsString")
45 , m_constStrPrintExpandAggregates("Print ExpandAggregates")
46 , m_constStrPrintAggregateFieldNames("Print AggregateFieldNames")
50 //++ ------------------------------------------------------------------------------------
51 // Details: CMICmnLLDBDebugSessionInfo destructor.
57 CMICmnLLDBDebugSessionInfo::~CMICmnLLDBDebugSessionInfo()
62 //++ ------------------------------------------------------------------------------------
63 // Details: Initialize resources for *this object.
66 // Return: MIstatus::success - Functionality succeeded.
67 // MIstatus::failure - Functionality failed.
71 CMICmnLLDBDebugSessionInfo::Initialize()
73 m_clientUsageRefCnt++;
76 return MIstatus::success;
78 m_currentSelectedThread = LLDB_INVALID_THREAD_ID;
79 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero();
81 m_bInitialized = MIstatus::success;
83 return m_bInitialized;
86 //++ ------------------------------------------------------------------------------------
87 // Details: Release resources for *this object.
90 // Return: MIstatus::success - Functionality succeeded.
91 // MIstatus::failure - Functionality failed.
95 CMICmnLLDBDebugSessionInfo::Shutdown()
97 if (--m_clientUsageRefCnt > 0)
98 return MIstatus::success;
101 return MIstatus::success;
106 m_vecActiveThreadId.clear();
107 CMICmnLLDBDebugSessionInfoVarObj::VarObjClear();
109 m_bInitialized = false;
111 return MIstatus::success;
114 //++ ------------------------------------------------------------------------------------
115 // Details: Command instances can create and share data between other instances of commands.
116 // Data can also be assigned by a command and retrieved by LLDB event handler.
117 // This function takes down those resources build up over the use of the commands.
118 // This function should be called when the creation and running of command has
119 // stopped i.e. application shutdown.
126 CMICmnLLDBDebugSessionInfo::SharedDataDestroy()
128 m_mapIdToSessionData.Clear();
130 m_mapBrkPtIdToBrkPtInfo.clear();
133 //++ ------------------------------------------------------------------------------------
134 // Details: Record information about a LLDB break point so that is can be recalled in other
135 // commands or LLDB event handling functions.
137 // Args: vBrkPtId - (R) LLDB break point ID.
138 // vrBrkPtInfo - (R) Break point information object.
139 // Return: MIstatus::success - Functional succeeded.
140 // MIstatus::failure - Functional failed.
144 CMICmnLLDBDebugSessionInfo::RecordBrkPtInfo(const MIuint vnBrkPtId, const SBrkPtInfo &vrBrkPtInfo)
146 MapPairBrkPtIdToBrkPtInfo_t pr(vnBrkPtId, vrBrkPtInfo);
147 m_mapBrkPtIdToBrkPtInfo.insert(pr);
149 return MIstatus::success;
152 //++ ------------------------------------------------------------------------------------
153 // Details: Retrieve information about a LLDB break point previous recorded either by
154 // commands or LLDB event handling functions.
156 // Args: vBrkPtId - (R) LLDB break point ID.
157 // vrwBrkPtInfo - (W) Break point information object.
158 // Return: MIstatus::success - Functional succeeded.
159 // MIstatus::failure - Functional failed.
163 CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoGet(const MIuint vnBrkPtId, SBrkPtInfo &vrwBrkPtInfo) const
165 const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find(vnBrkPtId);
166 if (it != m_mapBrkPtIdToBrkPtInfo.end())
168 vrwBrkPtInfo = (*it).second;
169 return MIstatus::success;
172 return MIstatus::failure;
175 //++ ------------------------------------------------------------------------------------
176 // Details: Delete information about a specific LLDB break point object. This function
177 // should be called when a LLDB break point is deleted.
179 // Args: vBrkPtId - (R) LLDB break point ID.
180 // Return: MIstatus::success - Functional succeeded.
181 // MIstatus::failure - Functional failed.
185 CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete(const MIuint vnBrkPtId)
187 const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find(vnBrkPtId);
188 if (it != m_mapBrkPtIdToBrkPtInfo.end())
190 m_mapBrkPtIdToBrkPtInfo.erase(it);
191 return MIstatus::success;
194 return MIstatus::failure;
197 //++ ------------------------------------------------------------------------------------
198 // Details: Retrieve the specified thread's frame information.
200 // Args: vCmdData - (R) A command's information.
201 // vThreadIdx - (R) Thread index.
202 // vwrThreadFrames - (W) Frame data.
203 // Return: MIstatus::success - Functional succeeded.
204 // MIstatus::failure - Functional failed.
208 CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, const FrameInfoFormat_e veFrameInfoFormat,
209 CMIUtilString &vwrThreadFrames)
211 lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx);
212 const uint32_t nFrames = thread.GetNumFrames();
215 // MI print "frame={}"
216 CMICmnMIValueTuple miValueTuple;
217 CMICmnMIValueResult miValueResult("frame", miValueTuple);
218 vwrThreadFrames = miValueResult.GetString();
219 return MIstatus::success;
223 // "frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%016" PRIx64 "\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},
225 CMIUtilString strListCommaSeparated;
226 for (MIuint nLevel = 0; nLevel < nFrames; nLevel++)
228 CMICmnMIValueTuple miValueTuple;
229 if (!MIResponseFormFrameInfo(thread, nLevel, veFrameInfoFormat, miValueTuple))
230 return MIstatus::failure;
232 const CMICmnMIValueResult miValueResult2("frame", miValueTuple);
234 strListCommaSeparated += ",";
235 strListCommaSeparated += miValueResult2.GetString();
238 vwrThreadFrames = strListCommaSeparated;
240 return MIstatus::success;
243 //++ ------------------------------------------------------------------------------------
244 // Details: Return the resolved file's path for the given file.
246 // Args: vCmdData - (R) A command's information.
247 // vPath - (R) Original path.
248 // vwrResolvedPath - (W) Resolved path.
249 // Return: MIstatus::success - Functional succeeded.
250 // MIstatus::failure - Functional failed.
254 CMICmnLLDBDebugSessionInfo::ResolvePath(const SMICmdData &vCmdData, const CMIUtilString &vPath, CMIUtilString &vwrResolvedPath)
256 // ToDo: Verify this code as it does not work as vPath is always empty
258 CMIUtilString strResolvedPath;
259 if (!SharedDataRetrieve<CMIUtilString>(m_constStrSharedDataKeyWkDir, strResolvedPath))
261 vwrResolvedPath = "";
262 SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SHARED_DATA_NOT_FOUND), vCmdData.strMiCmd.c_str(),
263 m_constStrSharedDataKeyWkDir.c_str()));
264 return MIstatus::failure;
267 vwrResolvedPath = vPath;
269 return ResolvePath(strResolvedPath, vwrResolvedPath);
272 //++ ------------------------------------------------------------------------------------
273 // Details: Return the resolved file's path for the given file.
275 // Args: vstrUnknown - (R) String assigned to path when resolved path is empty.
276 // vwrResolvedPath - (RW) The original path overwritten with resolved path.
277 // Return: MIstatus::success - Functional succeeded.
278 // MIstatus::failure - Functional failed.
282 CMICmnLLDBDebugSessionInfo::ResolvePath(const CMIUtilString &vstrUnknown, CMIUtilString &vwrResolvedPath)
284 if (vwrResolvedPath.size() < 1)
286 vwrResolvedPath = vstrUnknown;
287 return MIstatus::success;
290 bool bOk = MIstatus::success;
292 CMIUtilString::VecString_t vecPathFolders;
293 const MIuint nSplits = vwrResolvedPath.Split("/", vecPathFolders);
295 MIuint nFoldersBack = 1; // 1 is just the file (last element of vector)
296 while (bOk && (vecPathFolders.size() >= nFoldersBack))
298 CMIUtilString strTestPath;
299 MIuint nFoldersToAdd = nFoldersBack;
300 while (nFoldersToAdd > 0)
303 strTestPath += vecPathFolders[vecPathFolders.size() - nFoldersToAdd];
306 bool bYesAccessible = false;
307 bOk = AccessPath(strTestPath, bYesAccessible);
310 vwrResolvedPath = strTestPath;
311 return MIstatus::success;
317 // No files exist in the union of working directory and debuginfo path
318 // Simply use the debuginfo path and let the IDE handle it.
323 //++ ------------------------------------------------------------------------------------
324 // Details: Determine the given file path exists or not.
326 // Args: vPath - (R) File name path.
327 // vwbYesAccessible - (W) True - file exists, false = does not exist.
328 // Return: MIstatus::success - Functional succeeded.
329 // MIstatus::failure - Functional failed.
333 CMICmnLLDBDebugSessionInfo::AccessPath(const CMIUtilString &vPath, bool &vwbYesAccessible)
336 vwbYesAccessible = (::_access(vPath.c_str(), 0) == 0);
338 vwbYesAccessible = (::access(vPath.c_str(), 0) == 0);
341 return MIstatus::success;
344 //++ ------------------------------------------------------------------------------------
345 // Details: Form MI partial response by appending more MI value type objects to the
346 // tuple type object past in.
348 // Args: vCmdData - (R) A command's information.
349 // vrThread - (R) LLDB thread object.
350 // vwrMIValueTuple - (W) MI value tuple object.
351 // Return: MIstatus::success - Functional succeeded.
352 // MIstatus::failure - Functional failed.
356 CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread,
357 const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple)
359 lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
361 const bool bSuspended = rThread.IsSuspended();
362 const lldb::StopReason eReason = rThread.GetStopReason();
363 const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid));
364 const CMIUtilString strState((bSuspended || bValidReason) ? "stopped" : "running");
367 const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID()));
368 const CMICmnMIValueConst miValueConst1(strId);
369 const CMICmnMIValueResult miValueResult1("id", miValueConst1);
370 vwrMIValueTuple.Add(miValueResult1);
373 const char *pThreadName = rThread.GetName();
374 const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0;
375 const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) &&
376 CMIUtilString::IsAllValidAlphaAndNumeric(pThreadName)); // 32 is arbitrary number
377 const char *pThrdFmt = bHaveName ? "%s" : "Thread %d";
378 CMIUtilString strThread;
380 strThread = CMIUtilString::Format(pThrdFmt, pThreadName);
382 strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID());
383 const CMICmnMIValueConst miValueConst2(strThread);
384 const CMICmnMIValueResult miValueResult2("target-id", miValueConst2);
385 vwrMIValueTuple.Add(miValueResult2);
388 if (veThreadInfoFormat != eThreadInfoFormat_NoFrames)
390 CMIUtilString strFrames;
391 if (!GetThreadFrames(vCmdData, rThread.GetIndexID(), eFrameInfoFormat_AllArgumentsInSimpleForm, strFrames))
392 return MIstatus::failure;
394 const CMICmnMIValueConst miValueConst3(strFrames, true);
395 vwrMIValueTuple.Add(miValueConst3, false);
399 const CMICmnMIValueConst miValueConst4(strState);
400 const CMICmnMIValueResult miValueResult4("state", miValueConst4);
401 vwrMIValueTuple.Add(miValueResult4);
403 return MIstatus::success;
406 //++ ------------------------------------------------------------------------------------
407 // Details: Form MI partial response by appending more MI value type objects to the
408 // tuple type object past in.
410 // Args: vrFrame - (R) LLDB thread object.
411 // vMaskVarTypes - (R) Construed according to VariableType_e.
412 // veVarInfoFormat - (R) The type of variable info that should be shown.
413 // vwrMIValueList - (W) MI value list object.
414 // Return: MIstatus::success - Functional succeeded.
415 // MIstatus::failure - Functional failed.
419 CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes,
420 const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList,
421 const MIuint vnMaxDepth, /* = 10 */
422 const bool vbMarkArgs /* = false*/)
424 bool bOk = MIstatus::success;
425 lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
427 const bool bArg = (vMaskVarTypes & eVariableType_Arguments);
428 const bool bLocals = (vMaskVarTypes & eVariableType_Locals);
429 const bool bStatics = (vMaskVarTypes & eVariableType_Statics);
430 const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope);
432 // Handle arguments first
433 lldb::SBValueList listArg = rFrame.GetVariables(bArg, false, false, false);
434 bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listArg, vnMaxDepth, true, vbMarkArgs);
436 // Handle remaining variables
437 lldb::SBValueList listVars = rFrame.GetVariables(false, bLocals, bStatics, bInScopeOnly);
438 bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listVars, vnMaxDepth, false, vbMarkArgs);
444 CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat,
445 CMICmnMIValueList &vwrMiValueList,
446 const lldb::SBValueList &vwrSBValueList,
447 const MIuint vnMaxDepth,
449 const bool vbMarkArgs)
451 const MIuint nArgs = vwrSBValueList.GetSize();
452 for (MIuint i = 0; i < nArgs; i++)
454 CMICmnMIValueTuple miValueTuple;
455 lldb::SBValue value = vwrSBValueList.GetValueAtIndex(i);
456 // If one stops inside try block with, which catch clause type is unnamed
457 // (e.g std::exception&) then value name will be nullptr as well as value pointer
458 const char* name = value.GetName();
461 const CMICmnMIValueConst miValueConst(name);
462 const CMICmnMIValueResult miValueResultName("name", miValueConst);
463 if (vbMarkArgs && vbIsArgs)
465 const CMICmnMIValueConst miValueConstArg("1");
466 const CMICmnMIValueResult miValueResultArg("arg", miValueConstArg);
467 miValueTuple.Add(miValueResultArg);
469 if (veVarInfoFormat != eVariableInfoFormat_NoValues)
471 miValueTuple.Add(miValueResultName); // name
472 if (veVarInfoFormat == eVariableInfoFormat_SimpleValues)
474 const CMICmnMIValueConst miValueConst3(value.GetTypeName());
475 const CMICmnMIValueResult miValueResult3("type", miValueConst3);
476 miValueTuple.Add(miValueResult3);
478 const MIuint nChildren = value.GetNumChildren();
479 const bool bIsPointerType = value.GetType().IsPointerType();
480 if (nChildren == 0 || // no children
481 (bIsPointerType && nChildren == 1) || // pointers
482 veVarInfoFormat == eVariableInfoFormat_AllValues) // show all values
484 CMIUtilString strValue;
485 if (GetVariableInfo(value, vnMaxDepth == 0, strValue))
487 const CMICmnMIValueConst miValueConst2(strValue.Escape().AddSlashes());
488 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
489 miValueTuple.Add(miValueResult2);
492 vwrMiValueList.Add(miValueTuple);
498 // If we are printing names only with vbMarkArgs, we still need to add the name to the value tuple
499 miValueTuple.Add(miValueResultName); // name
500 vwrMiValueList.Add(miValueTuple);
504 // If we are printing name only then no need to put it in the tuple.
505 vwrMiValueList.Add(miValueResultName);
508 return MIstatus::success;
511 //++ ------------------------------------------------------------------------------------
512 // Details: Extract the value's name and value or recurse into child value object.
514 // Args: vrValue - (R) LLDB value object.
515 // vbInSimpleForm - (R) True = Get variable info in simple form (i.e. don't expand aggregates).
516 // - False = Get variable info (and expand aggregates if any).
517 // vwrStrValue t - (W) The string representation of this value.
518 // Return: MIstatus::success - Functional succeeded.
519 // MIstatus::failure - Functional failed.
523 CMICmnLLDBDebugSessionInfo::GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm, CMIUtilString &vwrStrValue)
525 const CMICmnLLDBUtilSBValue utilValue(vrValue, true, false);
526 const bool bExpandAggregates = vbInSimpleForm ? false : true;
527 vwrStrValue = utilValue.GetValue(bExpandAggregates);
528 return MIstatus::success;
531 //++ ------------------------------------------------------------------------------------
532 // Details: Form MI partial response by appending more MI value type objects to the
533 // tuple type object past in.
535 // Args: vrThread - (R) LLDB thread object.
536 // vwrMIValueTuple - (W) MI value tuple object.
537 // vArgInfo - (R) Args information in MI response form.
538 // Return: MIstatus::success - Functional succeeded.
539 // MIstatus::failure - Functional failed.
543 CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel,
544 const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple)
546 lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread);
548 lldb::SBFrame frame = rThread.GetFrameAtIndex(vnLevel);
550 CMIUtilString fnName;
551 CMIUtilString fileName;
554 if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine))
555 return MIstatus::failure;
557 // MI print "{level=\"0\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}"
558 const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel));
559 const CMICmnMIValueConst miValueConst(strLevel);
560 const CMICmnMIValueResult miValueResult("level", miValueConst);
561 vwrMiValueTuple.Add(miValueResult);
562 const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, pc));
563 const CMICmnMIValueConst miValueConst2(strAddr);
564 const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
565 vwrMiValueTuple.Add(miValueResult2);
566 const CMICmnMIValueConst miValueConst3(fnName);
567 const CMICmnMIValueResult miValueResult3("func", miValueConst3);
568 vwrMiValueTuple.Add(miValueResult3);
569 if (veFrameInfoFormat != eFrameInfoFormat_NoArguments)
571 CMICmnMIValueList miValueList(true);
572 const MIuint maskVarTypes = eVariableType_Arguments;
573 if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm)
575 if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList, 0))
576 return MIstatus::failure;
579 if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList))
580 return MIstatus::failure;
582 const CMICmnMIValueResult miValueResult4("args", miValueList);
583 vwrMiValueTuple.Add(miValueResult4);
585 const CMICmnMIValueConst miValueConst5(fileName);
586 const CMICmnMIValueResult miValueResult5("file", miValueConst5);
587 vwrMiValueTuple.Add(miValueResult5);
588 const CMICmnMIValueConst miValueConst6(path);
589 const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
590 vwrMiValueTuple.Add(miValueResult6);
591 const CMIUtilString strLine(CMIUtilString::Format("%d", nLine));
592 const CMICmnMIValueConst miValueConst7(strLine);
593 const CMICmnMIValueResult miValueResult7("line", miValueConst7);
594 vwrMiValueTuple.Add(miValueResult7);
596 return MIstatus::success;
599 //++ ------------------------------------------------------------------------------------
600 // Details: Retrieve the frame information from LLDB frame object.
602 // Args: vrFrame - (R) LLDB thread object.
603 // vPc - (W) Address number.
604 // vFnName - (W) Function name.
605 // vFileName - (W) File name text.
606 // vPath - (W) Full file name and path text.
607 // vnLine - (W) File line number.
608 // Return: MIstatus::success - Functional succeeded.
609 // MIstatus::failure - Functional failed.
613 CMICmnLLDBDebugSessionInfo::GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc, CMIUtilString &vwFnName,
614 CMIUtilString &vwFileName, CMIUtilString &vwPath, MIuint &vwnLine)
616 lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
618 static char pBuffer[PATH_MAX];
619 const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer));
621 CMIUtilString strResolvedPath(&pBuffer[0]);
622 const char *pUnkwn = "??";
623 if (!ResolvePath(pUnkwn, strResolvedPath))
624 return MIstatus::failure;
625 vwPath = strResolvedPath;
627 vwPc = rFrame.GetPC();
629 const char *pFnName = rFrame.GetFunctionName();
630 vwFnName = (pFnName != nullptr) ? pFnName : pUnkwn;
632 const char *pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename();
633 vwFileName = (pFileName != nullptr) ? pFileName : pUnkwn;
635 vwnLine = rFrame.GetLineEntry().GetLine();
637 return MIstatus::success;
640 //++ ------------------------------------------------------------------------------------
641 // Details: Form MI partial response by appending more MI value type objects to the
642 // tuple type object past in.
644 // Args: vrBrkPtInfo - (R) Break point information object.
645 // vwrMIValueTuple - (W) MI value tuple object.
650 CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple)
652 const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64, vrBrkPtInfo.m_pc));
653 const CMICmnMIValueConst miValueConst2(strAddr);
654 const CMICmnMIValueResult miValueResult2("addr", miValueConst2);
655 vwrMiValueTuple.Add(miValueResult2);
656 const CMICmnMIValueConst miValueConst3(vrBrkPtInfo.m_fnName);
657 const CMICmnMIValueResult miValueResult3("func", miValueConst3);
658 vwrMiValueTuple.Add(miValueResult3);
659 const CMICmnMIValueConst miValueConst5(vrBrkPtInfo.m_fileName);
660 const CMICmnMIValueResult miValueResult5("file", miValueConst5);
661 vwrMiValueTuple.Add(miValueResult5);
662 const CMIUtilString strN5 = CMIUtilString::Format("%s/%s", vrBrkPtInfo.m_path.c_str(), vrBrkPtInfo.m_fileName.c_str());
663 const CMICmnMIValueConst miValueConst6(strN5);
664 const CMICmnMIValueResult miValueResult6("fullname", miValueConst6);
665 vwrMiValueTuple.Add(miValueResult6);
666 const CMIUtilString strLine(CMIUtilString::Format("%d", vrBrkPtInfo.m_nLine));
667 const CMICmnMIValueConst miValueConst7(strLine);
668 const CMICmnMIValueResult miValueResult7("line", miValueConst7);
669 vwrMiValueTuple.Add(miValueResult7);
672 //++ ------------------------------------------------------------------------------------
673 // Details: Form MI partial response by appending more MI value type objects to the
674 // tuple type object past in.
676 // Args: vrBrkPtInfo - (R) Break point information object.
677 // vwrMIValueTuple - (W) MI value tuple object.
678 // Return: MIstatus::success - Functional succeeded.
679 // MIstatus::failure - Functional failed.
683 CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple)
685 // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\",
686 // func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}"
689 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_id));
690 const CMICmnMIValueResult miValueResult("number", miValueConst);
691 CMICmnMIValueTuple miValueTuple(miValueResult);
693 const CMICmnMIValueConst miValueConst2(vrBrkPtInfo.m_strType);
694 const CMICmnMIValueResult miValueResult2("type", miValueConst2);
695 miValueTuple.Add(miValueResult2);
697 const CMICmnMIValueConst miValueConst3(vrBrkPtInfo.m_bDisp ? "del" : "keep");
698 const CMICmnMIValueResult miValueResult3("disp", miValueConst3);
699 miValueTuple.Add(miValueResult3);
701 const CMICmnMIValueConst miValueConst4(vrBrkPtInfo.m_bEnabled ? "y" : "n");
702 const CMICmnMIValueResult miValueResult4("enabled", miValueConst4);
703 miValueTuple.Add(miValueResult4);
709 MIResponseFormBrkPtFrameInfo(vrBrkPtInfo, miValueTuple);
711 if (vrBrkPtInfo.m_bPending)
713 const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOrigLoc);
714 const CMICmnMIValueList miValueList(miValueConst);
715 const CMICmnMIValueResult miValueResult("pending", miValueList);
716 miValueTuple.Add(miValueResult);
718 if (vrBrkPtInfo.m_bHaveArgOptionThreadGrp)
720 const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOptThrdGrp);
721 const CMICmnMIValueList miValueList(miValueConst);
722 const CMICmnMIValueResult miValueResult("thread-groups", miValueList);
723 miValueTuple.Add(miValueResult);
726 const CMICmnMIValueConst miValueConstB(CMIUtilString::Format("%d", vrBrkPtInfo.m_nTimes));
727 const CMICmnMIValueResult miValueResultB("times", miValueConstB);
728 miValueTuple.Add(miValueResultB);
730 if (vrBrkPtInfo.m_bBrkPtThreadId)
732 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_nBrkPtThreadId));
733 const CMICmnMIValueResult miValueResult("thread", miValueConst);
734 miValueTuple.Add(miValueResult);
737 if (vrBrkPtInfo.m_bCondition)
739 const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strCondition);
740 const CMICmnMIValueResult miValueResult("cond", miValueConst);
741 miValueTuple.Add(miValueResult);
744 if (vrBrkPtInfo.m_nIgnore != 0)
746 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_nIgnore));
747 const CMICmnMIValueResult miValueResult("ignore", miValueConst);
748 miValueTuple.Add(miValueResult);
750 // "original-location="
751 const CMICmnMIValueConst miValueConstC(vrBrkPtInfo.m_strOrigLoc);
752 const CMICmnMIValueResult miValueResultC("original-location", miValueConstC);
753 miValueTuple.Add(miValueResultC);
755 vwrMiValueTuple = miValueTuple;
757 return MIstatus::success;
760 //++ ------------------------------------------------------------------------------------
761 // Details: Retrieve breakpoint information and write into the given breakpoint information
762 // object. Note not all possible information is retrieved and so the information
763 // object may need to be filled in with more information after calling this
764 // function. Mainly breakpoint location information of information that is
765 // unlikely to change.
767 // Args: vBrkPt - (R) LLDB break point object.
768 // vrBrkPtInfo - (W) Break point information object.
769 // Return: MIstatus::success - Functional succeeded.
770 // MIstatus::failure - Functional failed.
774 CMICmnLLDBDebugSessionInfo::GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkPtInfo &vrwBrkPtInfo) const
776 lldb::SBBreakpoint &rBrkPt = const_cast<lldb::SBBreakpoint &>(vBrkPt);
777 lldb::SBBreakpointLocation brkPtLoc = rBrkPt.GetLocationAtIndex(0);
778 lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress();
779 lldb::SBSymbolContext symbolCntxt = brkPtAddr.GetSymbolContext(lldb::eSymbolContextEverything);
780 const char *pUnkwn = "??";
781 lldb::SBModule rModule = symbolCntxt.GetModule();
782 const char *pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn;
784 const char *pFile = pUnkwn;
785 const char *pFn = pUnkwn;
786 const char *pFilePath = pUnkwn;
788 lldb::addr_t nAddr = brkPtAddr.GetLoadAddress(GetTarget());
789 if (nAddr == LLDB_INVALID_ADDRESS)
790 nAddr = brkPtAddr.GetFileAddress();
792 lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit();
793 if (rCmplUnit.IsValid())
795 lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec();
796 pFile = rFileSpec.GetFilename();
797 pFilePath = rFileSpec.GetDirectory();
798 lldb::SBFunction rFn = symbolCntxt.GetFunction();
801 lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry();
802 if (rLnEntry.GetLine() > 0)
803 nLine = rLnEntry.GetLine();
806 vrwBrkPtInfo.m_id = vBrkPt.GetID();
807 vrwBrkPtInfo.m_strType = "breakpoint";
808 vrwBrkPtInfo.m_pc = nAddr;
809 vrwBrkPtInfo.m_fnName = pFn;
810 vrwBrkPtInfo.m_fileName = pFile;
811 vrwBrkPtInfo.m_path = pFilePath;
812 vrwBrkPtInfo.m_nLine = nLine;
813 vrwBrkPtInfo.m_nTimes = vBrkPt.GetHitCount();
815 return MIstatus::success;
818 //++ ------------------------------------------------------------------------------------
819 // Details: Get current debugger.
822 // Return: lldb::SBDebugger - current debugger.
826 CMICmnLLDBDebugSessionInfo::GetDebugger() const
828 return CMICmnLLDBDebugger::Instance().GetTheDebugger();
831 //++ ------------------------------------------------------------------------------------
832 // Details: Get current listener.
835 // Return: lldb::SBListener - current listener.
839 CMICmnLLDBDebugSessionInfo::GetListener() const
841 return CMICmnLLDBDebugger::Instance().GetTheListener();
844 //++ ------------------------------------------------------------------------------------
845 // Details: Get current target.
848 // Return: lldb::SBTarget - current target.
852 CMICmnLLDBDebugSessionInfo::GetTarget() const
854 return GetDebugger().GetSelectedTarget();
857 //++ ------------------------------------------------------------------------------------
858 // Details: Get current process.
861 // Return: lldb::SBProcess - current process.
865 CMICmnLLDBDebugSessionInfo::GetProcess() const
867 return GetTarget().GetProcess();