File: | tools/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp |
Location: | line 777, column 5 |
Description: | Value stored to 'bOk' is never read |
1 | //===-- MICmnLLDBDebugSessionInfo.cpp ---------------------------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | // Third party headers: |
11 | #include <inttypes.h> // For PRIx64 |
12 | #include "lldb/API/SBThread.h" |
13 | #ifdef _WIN32 |
14 | #include <io.h> // For the ::_access() |
15 | #else |
16 | #include <unistd.h> // For the ::access() |
17 | #endif // _WIN32 |
18 | #include "lldb/API/SBBreakpointLocation.h" |
19 | |
20 | // In-house headers: |
21 | #include "MICmnLLDBDebugSessionInfo.h" |
22 | #include "MICmnLLDBDebugger.h" |
23 | #include "MICmnResources.h" |
24 | #include "MICmnMIResultRecord.h" |
25 | #include "MICmnMIValueConst.h" |
26 | #include "MICmnMIValueList.h" |
27 | #include "MICmnMIValueTuple.h" |
28 | #include "MICmdData.h" |
29 | #include "MICmnLLDBUtilSBValue.h" |
30 | |
31 | //++ ------------------------------------------------------------------------------------ |
32 | // Details: CMICmnLLDBDebugSessionInfo constructor. |
33 | // Type: Method. |
34 | // Args: None. |
35 | // Return: None. |
36 | // Throws: None. |
37 | //-- |
38 | CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo(void) |
39 | : m_nBrkPointCntMax(INT32_MAX(2147483647)) |
40 | , m_currentSelectedThread(LLDB_INVALID_THREAD_ID0) |
41 | , m_constStrSharedDataKeyWkDir("Working Directory") |
42 | , m_constStrSharedDataSolibPath("Solib Path") |
43 | , m_constStrPrintCharArrayAsString("Print CharArrayAsString") |
44 | , m_constStrPrintExpandAggregates("Print ExpandAggregates") |
45 | , m_constStrPrintAggregateFieldNames("Print AggregateFieldNames") |
46 | { |
47 | } |
48 | |
49 | //++ ------------------------------------------------------------------------------------ |
50 | // Details: CMICmnLLDBDebugSessionInfo destructor. |
51 | // Type: Overridable. |
52 | // Args: None. |
53 | // Return: None. |
54 | // Throws: None. |
55 | //-- |
56 | CMICmnLLDBDebugSessionInfo::~CMICmnLLDBDebugSessionInfo(void) |
57 | { |
58 | Shutdown(); |
59 | } |
60 | |
61 | //++ ------------------------------------------------------------------------------------ |
62 | // Details: Initialize resources for *this object. |
63 | // Type: Method. |
64 | // Args: None. |
65 | // Return: MIstatus::success - Functionality succeeded. |
66 | // MIstatus::failure - Functionality failed. |
67 | // Throws: None. |
68 | //-- |
69 | bool |
70 | CMICmnLLDBDebugSessionInfo::Initialize(void) |
71 | { |
72 | m_clientUsageRefCnt++; |
73 | |
74 | if (m_bInitialized) |
75 | return MIstatus::success; |
76 | |
77 | m_currentSelectedThread = LLDB_INVALID_THREAD_ID0; |
78 | CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero(); |
79 | |
80 | m_bInitialized = MIstatus::success; |
81 | |
82 | return m_bInitialized; |
83 | } |
84 | |
85 | //++ ------------------------------------------------------------------------------------ |
86 | // Details: Release resources for *this object. |
87 | // Type: Method. |
88 | // Args: None. |
89 | // Return: MIstatus::success - Functionality succeeded. |
90 | // MIstatus::failure - Functionality failed. |
91 | // Throws: None. |
92 | //-- |
93 | bool |
94 | CMICmnLLDBDebugSessionInfo::Shutdown(void) |
95 | { |
96 | if (--m_clientUsageRefCnt > 0) |
97 | return MIstatus::success; |
98 | |
99 | if (!m_bInitialized) |
100 | return MIstatus::success; |
101 | |
102 | bool bOk = MIstatus::success; |
103 | CMIUtilString errMsg; |
104 | |
105 | // Tidy up |
106 | bOk = SharedDataDestroy(); |
107 | if (!bOk) |
108 | { |
109 | errMsg = CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE)CMICmnResources::Instance().GetString(IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE ).c_str()); |
110 | errMsg += "\n"; |
111 | } |
112 | m_vecActiveThreadId.clear(); |
113 | CMICmnLLDBDebugSessionInfoVarObj::VarObjClear(); |
114 | |
115 | m_bInitialized = false; |
116 | |
117 | return MIstatus::success; |
118 | } |
119 | |
120 | //++ ------------------------------------------------------------------------------------ |
121 | // Details: Command instances can create and share data between other instances of commands. |
122 | // Data can also be assigned by a command and retrieved by LLDB event handler. |
123 | // This function takes down those resources build up over the use of the commands. |
124 | // This function should be called when the creation and running of command has |
125 | // stopped i.e. application shutdown. |
126 | // Type: Method. |
127 | // Args: None. |
128 | // Return: MIstatus::success - Functional succeeded. |
129 | // MIstatus::failure - Functional failed. |
130 | // Throws: None. |
131 | //-- |
132 | bool |
133 | CMICmnLLDBDebugSessionInfo::SharedDataDestroy(void) |
134 | { |
135 | m_mapIdToSessionData.Clear(); |
136 | m_vecVarObj.clear(); |
137 | m_mapBrkPtIdToBrkPtInfo.clear(); |
138 | |
139 | return MIstatus::success; |
140 | } |
141 | |
142 | //++ ------------------------------------------------------------------------------------ |
143 | // Details: Record information about a LLDB break point so that is can be recalled in other |
144 | // commands or LLDB event handling functions. |
145 | // Type: Method. |
146 | // Args: vBrkPtId - (R) LLDB break point ID. |
147 | // vrBrkPtInfo - (R) Break point information object. |
148 | // Return: MIstatus::success - Functional succeeded. |
149 | // MIstatus::failure - Functional failed. |
150 | // Throws: None. |
151 | //-- |
152 | bool |
153 | CMICmnLLDBDebugSessionInfo::RecordBrkPtInfo(const MIuint vnBrkPtId, const SBrkPtInfo &vrBrkPtInfo) |
154 | { |
155 | MapPairBrkPtIdToBrkPtInfo_t pr(vnBrkPtId, vrBrkPtInfo); |
156 | m_mapBrkPtIdToBrkPtInfo.insert(pr); |
157 | |
158 | return MIstatus::success; |
159 | } |
160 | |
161 | //++ ------------------------------------------------------------------------------------ |
162 | // Details: Retrieve information about a LLDB break point previous recorded either by |
163 | // commands or LLDB event handling functions. |
164 | // Type: Method. |
165 | // Args: vBrkPtId - (R) LLDB break point ID. |
166 | // vrwBrkPtInfo - (W) Break point information object. |
167 | // Return: MIstatus::success - Functional succeeded. |
168 | // MIstatus::failure - Functional failed. |
169 | // Throws: None. |
170 | //-- |
171 | bool |
172 | CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoGet(const MIuint vnBrkPtId, SBrkPtInfo &vrwBrkPtInfo) const |
173 | { |
174 | const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find(vnBrkPtId); |
175 | if (it != m_mapBrkPtIdToBrkPtInfo.end()) |
176 | { |
177 | vrwBrkPtInfo = (*it).second; |
178 | return MIstatus::success; |
179 | } |
180 | |
181 | return MIstatus::failure; |
182 | } |
183 | |
184 | //++ ------------------------------------------------------------------------------------ |
185 | // Details: Delete information about a specific LLDB break point object. This function |
186 | // should be called when a LLDB break point is deleted. |
187 | // Type: Method. |
188 | // Args: vBrkPtId - (R) LLDB break point ID. |
189 | // Return: MIstatus::success - Functional succeeded. |
190 | // MIstatus::failure - Functional failed. |
191 | // Throws: None. |
192 | //-- |
193 | bool |
194 | CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete(const MIuint vnBrkPtId) |
195 | { |
196 | const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find(vnBrkPtId); |
197 | if (it != m_mapBrkPtIdToBrkPtInfo.end()) |
198 | { |
199 | m_mapBrkPtIdToBrkPtInfo.erase(it); |
200 | return MIstatus::success; |
201 | } |
202 | |
203 | return MIstatus::failure; |
204 | } |
205 | |
206 | //++ ------------------------------------------------------------------------------------ |
207 | // Details: Retrieve the specified thread's frame information. |
208 | // Type: Method. |
209 | // Args: vCmdData - (R) A command's information. |
210 | // vThreadIdx - (R) Thread index. |
211 | // vwrThreadFrames - (W) Frame data. |
212 | // Return: MIstatus::success - Functional succeeded. |
213 | // MIstatus::failure - Functional failed. |
214 | // Throws: None. |
215 | //-- |
216 | bool |
217 | CMICmnLLDBDebugSessionInfo::GetThreadFrames(const SMICmdData &vCmdData, const MIuint vThreadIdx, const FrameInfoFormat_e veFrameInfoFormat, |
218 | CMIUtilString &vwrThreadFrames) |
219 | { |
220 | lldb::SBThread thread = GetProcess().GetThreadByIndexID(vThreadIdx); |
221 | const uint32_t nFrames = thread.GetNumFrames(); |
222 | if (nFrames == 0) |
223 | { |
224 | // MI print "frame={}" |
225 | CMICmnMIValueTuple miValueTuple; |
226 | CMICmnMIValueResult miValueResult("frame", miValueTuple); |
227 | vwrThreadFrames = miValueResult.GetString(); |
228 | return MIstatus::success; |
229 | } |
230 | |
231 | // MI print |
232 | // "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\"}, |
233 | // ..." |
234 | CMIUtilString strListCommaSeperated; |
235 | for (MIuint nLevel = 0; nLevel < nFrames; nLevel++) |
236 | { |
237 | CMICmnMIValueTuple miValueTuple; |
238 | if (!MIResponseFormFrameInfo(thread, nLevel, veFrameInfoFormat, miValueTuple)) |
239 | return MIstatus::failure; |
240 | |
241 | const CMICmnMIValueResult miValueResult2("frame", miValueTuple); |
242 | if (nLevel != 0) |
243 | strListCommaSeperated += ","; |
244 | strListCommaSeperated += miValueResult2.GetString(); |
245 | } |
246 | |
247 | vwrThreadFrames = strListCommaSeperated; |
248 | |
249 | return MIstatus::success; |
250 | } |
251 | |
252 | //++ ------------------------------------------------------------------------------------ |
253 | // Details: Return the resolved file's path for the given file. |
254 | // Type: Method. |
255 | // Args: vCmdData - (R) A command's information. |
256 | // vPath - (R) Original path. |
257 | // vwrResolvedPath - (W) Resolved path. |
258 | // Return: MIstatus::success - Functional succeeded. |
259 | // MIstatus::failure - Functional failed. |
260 | // Throws: None. |
261 | //-- |
262 | bool |
263 | CMICmnLLDBDebugSessionInfo::ResolvePath(const SMICmdData &vCmdData, const CMIUtilString &vPath, CMIUtilString &vwrResolvedPath) |
264 | { |
265 | // ToDo: Verify this code as it does not work as vPath is always empty |
266 | |
267 | CMIUtilString strResolvedPath; |
268 | if (!SharedDataRetrieve<CMIUtilString>(m_constStrSharedDataKeyWkDir, strResolvedPath)) |
269 | { |
270 | vwrResolvedPath = ""; |
271 | SetErrorDescription(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_SHARED_DATA_NOT_FOUND)CMICmnResources::Instance().GetString(IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ).c_str(), vCmdData.strMiCmd.c_str(), |
272 | m_constStrSharedDataKeyWkDir.c_str())); |
273 | return MIstatus::failure; |
274 | } |
275 | |
276 | vwrResolvedPath = vPath; |
277 | |
278 | return ResolvePath(strResolvedPath, vwrResolvedPath); |
279 | } |
280 | |
281 | //++ ------------------------------------------------------------------------------------ |
282 | // Details: Return the resolved file's path for the given file. |
283 | // Type: Method. |
284 | // Args: vstrUnknown - (R) String assigned to path when resolved path is empty. |
285 | // vwrResolvedPath - (RW) The original path overwritten with resolved path. |
286 | // Return: MIstatus::success - Functional succeeded. |
287 | // MIstatus::failure - Functional failed. |
288 | // Throws: None. |
289 | //-- |
290 | bool |
291 | CMICmnLLDBDebugSessionInfo::ResolvePath(const CMIUtilString &vstrUnknown, CMIUtilString &vwrResolvedPath) |
292 | { |
293 | if (vwrResolvedPath.size() < 1) |
294 | { |
295 | vwrResolvedPath = vstrUnknown; |
296 | return MIstatus::success; |
297 | } |
298 | |
299 | bool bOk = MIstatus::success; |
300 | |
301 | CMIUtilString::VecString_t vecPathFolders; |
302 | const MIuint nSplits = vwrResolvedPath.Split("/", vecPathFolders); |
303 | MIunused(nSplits)(void) nSplits;; |
304 | MIuint nFoldersBack = 1; // 1 is just the file (last element of vector) |
305 | while (bOk && (vecPathFolders.size() >= nFoldersBack)) |
306 | { |
307 | CMIUtilString strTestPath; |
308 | MIuint nFoldersToAdd = nFoldersBack; |
309 | while (nFoldersToAdd > 0) |
310 | { |
311 | strTestPath += "/"; |
312 | strTestPath += vecPathFolders[vecPathFolders.size() - nFoldersToAdd]; |
313 | nFoldersToAdd--; |
314 | } |
315 | bool bYesAccessible = false; |
316 | bOk = AccessPath(strTestPath, bYesAccessible); |
317 | if (bYesAccessible) |
318 | { |
319 | vwrResolvedPath = strTestPath; |
320 | return MIstatus::success; |
321 | } |
322 | else |
323 | nFoldersBack++; |
324 | } |
325 | |
326 | // No files exist in the union of working directory and debuginfo path |
327 | // Simply use the debuginfo path and let the IDE handle it. |
328 | |
329 | return bOk; |
330 | } |
331 | |
332 | //++ ------------------------------------------------------------------------------------ |
333 | // Details: Determine the given file path exists or not. |
334 | // Type: Method. |
335 | // Args: vPath - (R) File name path. |
336 | // vwbYesAccessible - (W) True - file exists, false = does not exist. |
337 | // Return: MIstatus::success - Functional succeeded. |
338 | // MIstatus::failure - Functional failed. |
339 | // Throws: None. |
340 | //-- |
341 | bool |
342 | CMICmnLLDBDebugSessionInfo::AccessPath(const CMIUtilString &vPath, bool &vwbYesAccessible) |
343 | { |
344 | #ifdef _WIN32 |
345 | vwbYesAccessible = (::_access(vPath.c_str(), 0) == 0); |
346 | #else |
347 | vwbYesAccessible = (::access(vPath.c_str(), 0) == 0); |
348 | #endif // _WIN32 |
349 | |
350 | return MIstatus::success; |
351 | } |
352 | |
353 | //++ ------------------------------------------------------------------------------------ |
354 | // Details: Form MI partial response by appending more MI value type objects to the |
355 | // tuple type object past in. |
356 | // Type: Method. |
357 | // Args: vCmdData - (R) A command's information. |
358 | // vrThread - (R) LLDB thread object. |
359 | // vwrMIValueTuple - (W) MI value tuple object. |
360 | // Return: MIstatus::success - Functional succeeded. |
361 | // MIstatus::failure - Functional failed. |
362 | // Throws: None. |
363 | //-- |
364 | bool |
365 | CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo(const SMICmdData &vCmdData, const lldb::SBThread &vrThread, |
366 | const ThreadInfoFormat_e veThreadInfoFormat, CMICmnMIValueTuple &vwrMIValueTuple) |
367 | { |
368 | lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread); |
369 | |
370 | const bool bSuspended = rThread.IsSuspended(); |
371 | const lldb::StopReason eReason = rThread.GetStopReason(); |
372 | const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); |
373 | const CMIUtilString strState((bSuspended || bValidReason) ? "stopped" : "running"); |
374 | |
375 | // Add "id" |
376 | const CMIUtilString strId(CMIUtilString::Format("%d", rThread.GetIndexID())); |
377 | const CMICmnMIValueConst miValueConst1(strId); |
378 | const CMICmnMIValueResult miValueResult1("id", miValueConst1); |
379 | if (!vwrMIValueTuple.Add(miValueResult1)) |
380 | return MIstatus::failure; |
381 | |
382 | // Add "target-id" |
383 | const MIchar *pThreadName = rThread.GetName(); |
384 | const MIuint len = (pThreadName != nullptr) ? CMIUtilString(pThreadName).length() : 0; |
385 | const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && |
386 | CMIUtilString::IsAllValidAlphaAndNumeric(*pThreadName)); // 32 is arbitary number |
387 | const MIchar *pThrdFmt = bHaveName ? "%s" : "Thread %d"; |
388 | CMIUtilString strThread; |
389 | if (bHaveName) |
390 | strThread = CMIUtilString::Format(pThrdFmt, pThreadName); |
391 | else |
392 | strThread = CMIUtilString::Format(pThrdFmt, rThread.GetIndexID()); |
393 | const CMICmnMIValueConst miValueConst2(strThread); |
394 | const CMICmnMIValueResult miValueResult2("target-id", miValueConst2); |
395 | if (!vwrMIValueTuple.Add(miValueResult2)) |
396 | return MIstatus::failure; |
397 | |
398 | // Add "frame" |
399 | if (veThreadInfoFormat != eThreadInfoFormat_NoFrames) |
400 | { |
401 | CMIUtilString strFrames; |
402 | if (!GetThreadFrames(vCmdData, rThread.GetIndexID(), eFrameInfoFormat_AllArgumentsInSimpleForm, strFrames)) |
403 | return MIstatus::failure; |
404 | |
405 | const CMICmnMIValueConst miValueConst3(strFrames, true); |
406 | if (!vwrMIValueTuple.Add(miValueConst3, false)) |
407 | return MIstatus::failure; |
408 | } |
409 | |
410 | // Add "state" |
411 | const CMICmnMIValueConst miValueConst4(strState); |
412 | const CMICmnMIValueResult miValueResult4("state", miValueConst4); |
413 | if (!vwrMIValueTuple.Add(miValueResult4)) |
414 | return MIstatus::failure; |
415 | |
416 | return MIstatus::success; |
417 | } |
418 | |
419 | //++ ------------------------------------------------------------------------------------ |
420 | // Details: Form MI partial response by appending more MI value type objects to the |
421 | // tuple type object past in. |
422 | // Type: Method. |
423 | // Args: vrFrame - (R) LLDB thread object. |
424 | // vMaskVarTypes - (R) Construed according to VariableType_e. |
425 | // veVarInfoFormat - (R) The type of variable info that should be shown. |
426 | // vwrMIValueList - (W) MI value list object. |
427 | // Return: MIstatus::success - Functional succeeded. |
428 | // MIstatus::failure - Functional failed. |
429 | // Throws: None. |
430 | //-- |
431 | bool |
432 | CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo(const lldb::SBFrame &vrFrame, const MIuint vMaskVarTypes, |
433 | const VariableInfoFormat_e veVarInfoFormat, CMICmnMIValueList &vwrMiValueList, |
434 | const MIuint vnMaxDepth, /* = 10 */ |
435 | const bool vbMarkArgs /* = false*/) |
436 | { |
437 | bool bOk = MIstatus::success; |
438 | lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame); |
439 | |
440 | const bool bArg = (vMaskVarTypes & eVariableType_Arguments); |
441 | const bool bLocals = (vMaskVarTypes & eVariableType_Locals); |
442 | const bool bStatics = (vMaskVarTypes & eVariableType_Statics); |
443 | const bool bInScopeOnly = (vMaskVarTypes & eVariableType_InScope); |
444 | |
445 | // Handle arguments first |
446 | lldb::SBValueList listArg = rFrame.GetVariables(bArg, false, false, false); |
447 | bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listArg, vnMaxDepth, true, vbMarkArgs); |
448 | |
449 | // Handle remaining variables |
450 | lldb::SBValueList listVars = rFrame.GetVariables(false, bLocals, bStatics, bInScopeOnly); |
451 | bOk = bOk && MIResponseForVariableInfoInternal(veVarInfoFormat, vwrMiValueList, listVars, vnMaxDepth, false, vbMarkArgs); |
452 | |
453 | return bOk; |
454 | } |
455 | |
456 | bool |
457 | CMICmnLLDBDebugSessionInfo::MIResponseForVariableInfoInternal(const VariableInfoFormat_e veVarInfoFormat, |
458 | CMICmnMIValueList &vwrMiValueList, |
459 | const lldb::SBValueList &vwrSBValueList, |
460 | const MIuint vnMaxDepth, |
461 | const bool vbIsArgs, |
462 | const bool vbMarkArgs) |
463 | { |
464 | bool bOk = MIstatus::success; |
465 | const MIuint nArgs = vwrSBValueList.GetSize(); |
466 | for (MIuint i = 0; bOk && (i < nArgs); i++) |
467 | { |
468 | CMICmnMIValueTuple miValueTuple; |
469 | lldb::SBValue value = vwrSBValueList.GetValueAtIndex(i); |
470 | const CMICmnMIValueConst miValueConst(value.GetName()); |
471 | const CMICmnMIValueResult miValueResultName("name", miValueConst); |
472 | if (vbMarkArgs && vbIsArgs) |
473 | { |
474 | const CMICmnMIValueConst miValueConstArg("1"); |
475 | const CMICmnMIValueResult miValueResultArg("arg", miValueConstArg); |
476 | miValueTuple.Add(miValueResultArg); |
477 | } |
478 | if (veVarInfoFormat != eVariableInfoFormat_NoValues) |
479 | { |
480 | miValueTuple.Add(miValueResultName); // name |
481 | if (veVarInfoFormat == eVariableInfoFormat_SimpleValues) |
482 | { |
483 | const CMICmnMIValueConst miValueConst3(value.GetTypeName()); |
484 | const CMICmnMIValueResult miValueResult3("type", miValueConst3); |
485 | miValueTuple.Add(miValueResult3); |
486 | } |
487 | const MIuint nChildren = value.GetNumChildren(); |
488 | const bool bIsPointerType = value.GetType().IsPointerType(); |
489 | if (nChildren == 0 || // no children |
490 | (bIsPointerType && nChildren == 1) || // pointers |
491 | veVarInfoFormat == eVariableInfoFormat_AllValues) // show all values |
492 | { |
493 | CMIUtilString strValue; |
494 | if (GetVariableInfo(value, vnMaxDepth == 0, strValue)) |
495 | { |
496 | const CMICmnMIValueConst miValueConst2(strValue.Escape().AddSlashes()); |
497 | const CMICmnMIValueResult miValueResult2("value", miValueConst2); |
498 | miValueTuple.Add(miValueResult2); |
499 | } |
500 | } |
501 | vwrMiValueList.Add(miValueTuple); |
502 | continue; |
503 | } |
504 | |
505 | if (vbMarkArgs) |
506 | { |
507 | // If we are printing names only with vbMarkArgs, we still need to add the name to the value tuple |
508 | miValueTuple.Add(miValueResultName); // name |
509 | vwrMiValueList.Add(miValueTuple); |
510 | } |
511 | else |
512 | { |
513 | // If we are printing name only then no need to put it in the tuple. |
514 | vwrMiValueList.Add(miValueResultName); |
515 | } |
516 | } |
517 | return bOk; |
518 | } |
519 | |
520 | //++ ------------------------------------------------------------------------------------ |
521 | // Details: Extract the value's name and value or recurse into child value object. |
522 | // Type: Method. |
523 | // Args: vrValue - (R) LLDB value object. |
524 | // vbInSimpleForm - (R) True = Get variable info in simple form (i.e. don't expand aggregates). |
525 | // - False = Get variable info (and expand aggregates if any). |
526 | // vwrStrValue t - (W) The string representatin of this value. |
527 | // Return: MIstatus::success - Functional succeeded. |
528 | // MIstatus::failure - Functional failed. |
529 | // Throws: None. |
530 | //-- |
531 | bool |
532 | CMICmnLLDBDebugSessionInfo::GetVariableInfo(const lldb::SBValue &vrValue, const bool vbInSimpleForm, CMIUtilString &vwrStrValue) |
533 | { |
534 | const CMICmnLLDBUtilSBValue utilValue(vrValue, true, false); |
535 | const bool bExpandAggregates = vbInSimpleForm ? false : true; |
536 | vwrStrValue = utilValue.GetValue(bExpandAggregates); |
537 | return MIstatus::success; |
538 | } |
539 | |
540 | //++ ------------------------------------------------------------------------------------ |
541 | // Details: Form MI partial response by appending more MI value type objects to the |
542 | // tuple type object past in. |
543 | // Type: Method. |
544 | // Args: vrThread - (R) LLDB thread object. |
545 | // vwrMIValueTuple - (W) MI value tuple object. |
546 | // vArgInfo - (R) Args information in MI response form. |
547 | // Return: MIstatus::success - Functional succeeded. |
548 | // MIstatus::failure - Functional failed. |
549 | // Throws: None. |
550 | //-- |
551 | bool |
552 | CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo(const lldb::SBThread &vrThread, const MIuint vnLevel, |
553 | const FrameInfoFormat_e veFrameInfoFormat, CMICmnMIValueTuple &vwrMiValueTuple) |
554 | { |
555 | lldb::SBThread &rThread = const_cast<lldb::SBThread &>(vrThread); |
556 | |
557 | lldb::SBFrame frame = rThread.GetFrameAtIndex(vnLevel); |
558 | lldb::addr_t pc = 0; |
559 | CMIUtilString fnName; |
560 | CMIUtilString fileName; |
561 | CMIUtilString path; |
562 | MIuint nLine = 0; |
563 | if (!GetFrameInfo(frame, pc, fnName, fileName, path, nLine)) |
564 | return MIstatus::failure; |
565 | |
566 | // MI print "{level=\"0\",addr=\"0x%016" PRIx64 "\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}" |
567 | const CMIUtilString strLevel(CMIUtilString::Format("%d", vnLevel)); |
568 | const CMICmnMIValueConst miValueConst(strLevel); |
569 | const CMICmnMIValueResult miValueResult("level", miValueConst); |
570 | if (!vwrMiValueTuple.Add(miValueResult)) |
571 | return MIstatus::failure; |
572 | const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64"l" "x", pc)); |
573 | const CMICmnMIValueConst miValueConst2(strAddr); |
574 | const CMICmnMIValueResult miValueResult2("addr", miValueConst2); |
575 | if (!vwrMiValueTuple.Add(miValueResult2)) |
576 | return MIstatus::failure; |
577 | const CMICmnMIValueConst miValueConst3(fnName); |
578 | const CMICmnMIValueResult miValueResult3("func", miValueConst3); |
579 | if (!vwrMiValueTuple.Add(miValueResult3)) |
580 | return MIstatus::failure; |
581 | if (veFrameInfoFormat != eFrameInfoFormat_NoArguments) |
582 | { |
583 | CMICmnMIValueList miValueList(true); |
584 | const MIuint maskVarTypes = eVariableType_Arguments; |
585 | if (veFrameInfoFormat == eFrameInfoFormat_AllArgumentsInSimpleForm) |
586 | { |
587 | if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList, 0)) |
588 | return MIstatus::failure; |
589 | } |
590 | else |
591 | if (!MIResponseFormVariableInfo(frame, maskVarTypes, eVariableInfoFormat_AllValues, miValueList)) |
592 | return MIstatus::failure; |
593 | |
594 | const CMICmnMIValueResult miValueResult4("args", miValueList); |
595 | if (!vwrMiValueTuple.Add(miValueResult4)) |
596 | return MIstatus::failure; |
597 | } |
598 | const CMICmnMIValueConst miValueConst5(fileName); |
599 | const CMICmnMIValueResult miValueResult5("file", miValueConst5); |
600 | if (!vwrMiValueTuple.Add(miValueResult5)) |
601 | return MIstatus::failure; |
602 | const CMICmnMIValueConst miValueConst6(path); |
603 | const CMICmnMIValueResult miValueResult6("fullname", miValueConst6); |
604 | if (!vwrMiValueTuple.Add(miValueResult6)) |
605 | return MIstatus::failure; |
606 | const CMIUtilString strLine(CMIUtilString::Format("%d", nLine)); |
607 | const CMICmnMIValueConst miValueConst7(strLine); |
608 | const CMICmnMIValueResult miValueResult7("line", miValueConst7); |
609 | if (!vwrMiValueTuple.Add(miValueResult7)) |
610 | return MIstatus::failure; |
611 | |
612 | return MIstatus::success; |
613 | } |
614 | |
615 | //++ ------------------------------------------------------------------------------------ |
616 | // Details: Retrieve the frame information from LLDB frame object. |
617 | // Type: Method. |
618 | // Args: vrFrame - (R) LLDB thread object. |
619 | // vPc - (W) Address number. |
620 | // vFnName - (W) Function name. |
621 | // vFileName - (W) File name text. |
622 | // vPath - (W) Full file name and path text. |
623 | // vnLine - (W) File line number. |
624 | // Return: MIstatus::success - Functional succeeded. |
625 | // MIstatus::failure - Functional failed. |
626 | // Throws: None. |
627 | //-- |
628 | bool |
629 | CMICmnLLDBDebugSessionInfo::GetFrameInfo(const lldb::SBFrame &vrFrame, lldb::addr_t &vwPc, CMIUtilString &vwFnName, |
630 | CMIUtilString &vwFileName, CMIUtilString &vwPath, MIuint &vwnLine) |
631 | { |
632 | lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame); |
633 | |
634 | static char pBuffer[MAX_PATH4096]; |
635 | const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer)); |
636 | MIunused(nBytes)(void) nBytes;; |
637 | CMIUtilString strResolvedPath(&pBuffer[0]); |
638 | const MIchar *pUnkwn = "??"; |
639 | if (!ResolvePath(pUnkwn, strResolvedPath)) |
640 | return MIstatus::failure; |
641 | vwPath = strResolvedPath; |
642 | |
643 | vwPc = rFrame.GetPC(); |
644 | |
645 | const MIchar *pFnName = rFrame.GetFunctionName(); |
646 | vwFnName = (pFnName != nullptr) ? pFnName : pUnkwn; |
647 | |
648 | const MIchar *pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename(); |
649 | vwFileName = (pFileName != nullptr) ? pFileName : pUnkwn; |
650 | |
651 | vwnLine = rFrame.GetLineEntry().GetLine(); |
652 | |
653 | return MIstatus::success; |
654 | } |
655 | |
656 | //++ ------------------------------------------------------------------------------------ |
657 | // Details: Form MI partial response by appending more MI value type objects to the |
658 | // tuple type object past in. |
659 | // Type: Method. |
660 | // Args: vrBrkPtInfo - (R) Break point information object. |
661 | // vwrMIValueTuple - (W) MI value tuple object. |
662 | // Return: MIstatus::success - Functional succeeded. |
663 | // MIstatus::failure - Functional failed. |
664 | // Throws: None. |
665 | //-- |
666 | bool |
667 | CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple) |
668 | { |
669 | const CMIUtilString strAddr(CMIUtilString::Format("0x%016" PRIx64"l" "x", vrBrkPtInfo.m_pc)); |
670 | const CMICmnMIValueConst miValueConst2(strAddr); |
671 | const CMICmnMIValueResult miValueResult2("addr", miValueConst2); |
672 | if (!vwrMiValueTuple.Add(miValueResult2)) |
673 | return MIstatus::failure; |
674 | const CMICmnMIValueConst miValueConst3(vrBrkPtInfo.m_fnName); |
675 | const CMICmnMIValueResult miValueResult3("func", miValueConst3); |
676 | if (!vwrMiValueTuple.Add(miValueResult3)) |
677 | return MIstatus::failure; |
678 | const CMICmnMIValueConst miValueConst5(vrBrkPtInfo.m_fileName); |
679 | const CMICmnMIValueResult miValueResult5("file", miValueConst5); |
680 | if (!vwrMiValueTuple.Add(miValueResult5)) |
681 | return MIstatus::failure; |
682 | const CMIUtilString strN5 = CMIUtilString::Format("%s/%s", vrBrkPtInfo.m_path.c_str(), vrBrkPtInfo.m_fileName.c_str()); |
683 | const CMICmnMIValueConst miValueConst6(strN5); |
684 | const CMICmnMIValueResult miValueResult6("fullname", miValueConst6); |
685 | if (!vwrMiValueTuple.Add(miValueResult6)) |
686 | return MIstatus::failure; |
687 | const CMIUtilString strLine(CMIUtilString::Format("%d", vrBrkPtInfo.m_nLine)); |
688 | const CMICmnMIValueConst miValueConst7(strLine); |
689 | const CMICmnMIValueResult miValueResult7("line", miValueConst7); |
690 | if (!vwrMiValueTuple.Add(miValueResult7)) |
691 | return MIstatus::failure; |
692 | |
693 | return MIstatus::success; |
694 | } |
695 | |
696 | //++ ------------------------------------------------------------------------------------ |
697 | // Details: Form MI partial response by appending more MI value type objects to the |
698 | // tuple type object past in. |
699 | // Type: Method. |
700 | // Args: vrBrkPtInfo - (R) Break point information object. |
701 | // vwrMIValueTuple - (W) MI value tuple object. |
702 | // Return: MIstatus::success - Functional succeeded. |
703 | // MIstatus::failure - Functional failed. |
704 | // Throws: None. |
705 | //-- |
706 | bool |
707 | CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo(const SBrkPtInfo &vrBrkPtInfo, CMICmnMIValueTuple &vwrMiValueTuple) |
708 | { |
709 | // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%016" PRIx64 "\", |
710 | // func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}" |
711 | |
712 | // "number=" |
713 | const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_id)); |
714 | const CMICmnMIValueResult miValueResult("number", miValueConst); |
715 | CMICmnMIValueTuple miValueTuple(miValueResult); |
716 | // "type=" |
717 | const CMICmnMIValueConst miValueConst2(vrBrkPtInfo.m_strType); |
718 | const CMICmnMIValueResult miValueResult2("type", miValueConst2); |
719 | bool bOk = miValueTuple.Add(miValueResult2); |
720 | // "disp=" |
721 | const CMICmnMIValueConst miValueConst3(vrBrkPtInfo.m_bDisp ? "del" : "keep"); |
722 | const CMICmnMIValueResult miValueResult3("disp", miValueConst3); |
723 | bOk = bOk && miValueTuple.Add(miValueResult3); |
724 | // "enabled=" |
725 | const CMICmnMIValueConst miValueConst4(vrBrkPtInfo.m_bEnabled ? "y" : "n"); |
726 | const CMICmnMIValueResult miValueResult4("enabled", miValueConst4); |
727 | bOk = bOk && miValueTuple.Add(miValueResult4); |
728 | // "addr=" |
729 | // "func=" |
730 | // "file=" |
731 | // "fullname=" |
732 | // "line=" |
733 | bOk = bOk && MIResponseFormBrkPtFrameInfo(vrBrkPtInfo, miValueTuple); |
734 | // "pending=" |
735 | if (vrBrkPtInfo.m_bPending) |
736 | { |
737 | const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOrigLoc); |
738 | const CMICmnMIValueList miValueList(miValueConst); |
739 | const CMICmnMIValueResult miValueResult("pending", miValueList); |
740 | bOk = bOk && miValueTuple.Add(miValueResult); |
741 | } |
742 | if (vrBrkPtInfo.m_bHaveArgOptionThreadGrp) |
743 | { |
744 | const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strOptThrdGrp); |
745 | const CMICmnMIValueList miValueList(miValueConst); |
746 | const CMICmnMIValueResult miValueResult("thread-groups", miValueList); |
747 | bOk = bOk && miValueTuple.Add(miValueResult); |
748 | } |
749 | // "times=" |
750 | const CMICmnMIValueConst miValueConstB(CMIUtilString::Format("%d", vrBrkPtInfo.m_nTimes)); |
751 | const CMICmnMIValueResult miValueResultB("times", miValueConstB); |
752 | bOk = bOk && miValueTuple.Add(miValueResultB); |
753 | // "thread=" |
754 | if (vrBrkPtInfo.m_bBrkPtThreadId) |
755 | { |
756 | const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_nBrkPtThreadId)); |
757 | const CMICmnMIValueResult miValueResult("thread", miValueConst); |
758 | bOk = bOk && miValueTuple.Add(miValueResult); |
759 | } |
760 | // "cond=" |
761 | if (vrBrkPtInfo.m_bCondition) |
762 | { |
763 | const CMICmnMIValueConst miValueConst(vrBrkPtInfo.m_strCondition); |
764 | const CMICmnMIValueResult miValueResult("cond", miValueConst); |
765 | bOk = bOk && miValueTuple.Add(miValueResult); |
766 | } |
767 | // "ignore=" |
768 | if (vrBrkPtInfo.m_nIgnore != 0) |
769 | { |
770 | const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%d", vrBrkPtInfo.m_nIgnore)); |
771 | const CMICmnMIValueResult miValueResult("ignore", miValueConst); |
772 | bOk = bOk && miValueTuple.Add(miValueResult); |
773 | } |
774 | // "original-location=" |
775 | const CMICmnMIValueConst miValueConstC(vrBrkPtInfo.m_strOrigLoc); |
776 | const CMICmnMIValueResult miValueResultC("original-location", miValueConstC); |
777 | bOk = bOk && miValueTuple.Add(miValueResultC); |
Value stored to 'bOk' is never read | |
778 | |
779 | vwrMiValueTuple = miValueTuple; |
780 | |
781 | return MIstatus::success; |
782 | } |
783 | |
784 | //++ ------------------------------------------------------------------------------------ |
785 | // Details: Retrieve breakpoint information and write into the given breakpoint information |
786 | // object. Note not all possible information is retrieved and so the information |
787 | // object may need to be filled in with more information after calling this |
788 | // function. Mainly breakpoint location information of information that is |
789 | // unlikely to change. |
790 | // Type: Method. |
791 | // Args: vBrkPt - (R) LLDB break point object. |
792 | // vrBrkPtInfo - (W) Break point information object. |
793 | // Return: MIstatus::success - Functional succeeded. |
794 | // MIstatus::failure - Functional failed. |
795 | // Throws: None. |
796 | //-- |
797 | bool |
798 | CMICmnLLDBDebugSessionInfo::GetBrkPtInfo(const lldb::SBBreakpoint &vBrkPt, SBrkPtInfo &vrwBrkPtInfo) const |
799 | { |
800 | lldb::SBBreakpoint &rBrkPt = const_cast<lldb::SBBreakpoint &>(vBrkPt); |
801 | lldb::SBBreakpointLocation brkPtLoc = rBrkPt.GetLocationAtIndex(0); |
802 | lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress(); |
803 | lldb::SBSymbolContext symbolCntxt = brkPtAddr.GetSymbolContext(lldb::eSymbolContextEverything); |
804 | const MIchar *pUnkwn = "??"; |
805 | lldb::SBModule rModule = symbolCntxt.GetModule(); |
806 | const MIchar *pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn; |
807 | MIunused(pModule)(void) pModule;; |
808 | const MIchar *pFile = pUnkwn; |
809 | const MIchar *pFn = pUnkwn; |
810 | const MIchar *pFilePath = pUnkwn; |
811 | size_t nLine = 0; |
812 | lldb::addr_t nAddr = brkPtAddr.GetLoadAddress(GetTarget()); |
813 | if (nAddr == LLDB_INVALID_ADDRESS(18446744073709551615UL)) |
814 | nAddr = brkPtAddr.GetFileAddress(); |
815 | |
816 | lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit(); |
817 | if (rCmplUnit.IsValid()) |
818 | { |
819 | lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec(); |
820 | pFile = rFileSpec.GetFilename(); |
821 | pFilePath = rFileSpec.GetDirectory(); |
822 | lldb::SBFunction rFn = symbolCntxt.GetFunction(); |
823 | if (rFn.IsValid()) |
824 | pFn = rFn.GetName(); |
825 | lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry(); |
826 | if (rLnEntry.GetLine() > 0) |
827 | nLine = rLnEntry.GetLine(); |
828 | } |
829 | |
830 | vrwBrkPtInfo.m_id = vBrkPt.GetID(); |
831 | vrwBrkPtInfo.m_strType = "breakpoint"; |
832 | vrwBrkPtInfo.m_pc = nAddr; |
833 | vrwBrkPtInfo.m_fnName = pFn; |
834 | vrwBrkPtInfo.m_fileName = pFile; |
835 | vrwBrkPtInfo.m_path = pFilePath; |
836 | vrwBrkPtInfo.m_nLine = nLine; |
837 | vrwBrkPtInfo.m_nTimes = vBrkPt.GetHitCount(); |
838 | |
839 | return MIstatus::success; |
840 | } |
841 | |
842 | //++ ------------------------------------------------------------------------------------ |
843 | // Details: Get current debugger. |
844 | // Type: Method. |
845 | // Args: None. |
846 | // Return: lldb::SBDebugger - current debugger. |
847 | // Throws: None. |
848 | //-- |
849 | lldb::SBDebugger & |
850 | CMICmnLLDBDebugSessionInfo::GetDebugger() const |
851 | { |
852 | return CMICmnLLDBDebugger::Instance().GetTheDebugger(); |
853 | } |
854 | |
855 | //++ ------------------------------------------------------------------------------------ |
856 | // Details: Get current listener. |
857 | // Type: Method. |
858 | // Args: None. |
859 | // Return: lldb::SBListener - current listener. |
860 | // Throws: None. |
861 | //-- |
862 | lldb::SBListener & |
863 | CMICmnLLDBDebugSessionInfo::GetListener() const |
864 | { |
865 | return CMICmnLLDBDebugger::Instance().GetTheListener(); |
866 | } |
867 | |
868 | //++ ------------------------------------------------------------------------------------ |
869 | // Details: Get current target. |
870 | // Type: Method. |
871 | // Args: None. |
872 | // Return: lldb::SBTarget - current target. |
873 | // Throws: None. |
874 | //-- |
875 | lldb::SBTarget |
876 | CMICmnLLDBDebugSessionInfo::GetTarget() const |
877 | { |
878 | return GetDebugger().GetSelectedTarget(); |
879 | } |
880 | |
881 | //++ ------------------------------------------------------------------------------------ |
882 | // Details: Get current process. |
883 | // Type: Method. |
884 | // Args: None. |
885 | // Return: lldb::SBProcess - current process. |
886 | // Throws: None. |
887 | //-- |
888 | lldb::SBProcess |
889 | CMICmnLLDBDebugSessionInfo::GetProcess() const |
890 | { |
891 | return GetTarget().GetProcess(); |
892 | } |