File: | tools/lldb/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp |
Location: | line 1253, column 2 |
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 | //++ |
11 | // File: MICmnLLDBDebugSessionInfo.cpp |
12 | // |
13 | // Overview: CMICmnLLDBDebugSessionInfo implementation. |
14 | // |
15 | // Environment: Compilers: Visual C++ 12. |
16 | // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 |
17 | // Libraries: See MIReadmetxt. |
18 | // |
19 | // Copyright: None. |
20 | //-- |
21 | |
22 | // Third party headers: |
23 | #include <lldb/API/SBThread.h> |
24 | #ifdef _WIN32 |
25 | #include <io.h> // For the ::_access() |
26 | #else |
27 | #include <unistd.h> // For the ::access() |
28 | #endif // _WIN32 |
29 | #include <lldb/API/SBBreakpointLocation.h> |
30 | |
31 | // In-house headers: |
32 | #include "MICmnLLDBDebugSessionInfo.h" |
33 | #include "MICmnLLDBDebugger.h" |
34 | #include "MICmnResources.h" |
35 | #include "MICmnMIResultRecord.h" |
36 | #include "MICmnMIValueConst.h" |
37 | #include "MICmnMIValueList.h" |
38 | #include "MICmnMIValueTuple.h" |
39 | #include "MICmdData.h" |
40 | #include "MICmnLLDBUtilSBValue.h" |
41 | |
42 | //++ ------------------------------------------------------------------------------------ |
43 | // Details: CMICmnLLDBDebugSessionInfo constructor. |
44 | // Type: Method. |
45 | // Args: None. |
46 | // Return: None. |
47 | // Throws: None. |
48 | //-- |
49 | CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo( void ) |
50 | : m_rLldbDebugger( CMICmnLLDBDebugger::Instance().GetTheDebugger() ) |
51 | , m_rLlldbListener( CMICmnLLDBDebugger::Instance().GetTheListener() ) |
52 | , m_nBrkPointCntMax( INT32_MAX(2147483647) ) |
53 | , m_currentSelectedThread( LLDB_INVALID_THREAD_ID0 ) |
54 | , m_constStrSharedDataKeyWkDir( "Working Directory" ) |
55 | , m_constStrSharedDataSolibPath( "Solib Path" ) |
56 | { |
57 | } |
58 | |
59 | //++ ------------------------------------------------------------------------------------ |
60 | // Details: CMICmnLLDBDebugSessionInfo destructor. |
61 | // Type: Overridable. |
62 | // Args: None. |
63 | // Return: None. |
64 | // Throws: None. |
65 | //-- |
66 | CMICmnLLDBDebugSessionInfo::~CMICmnLLDBDebugSessionInfo( void ) |
67 | { |
68 | Shutdown(); |
69 | } |
70 | |
71 | //++ ------------------------------------------------------------------------------------ |
72 | // Details: Initialize resources for *this object. |
73 | // Type: Method. |
74 | // Args: None. |
75 | // Return: MIstatus::success - Functionality succeeded. |
76 | // MIstatus::failure - Functionality failed. |
77 | // Throws: None. |
78 | //-- |
79 | bool CMICmnLLDBDebugSessionInfo::Initialize( void ) |
80 | { |
81 | m_clientUsageRefCnt++; |
82 | |
83 | if( m_bInitialized ) |
84 | return MIstatus::success; |
85 | |
86 | m_currentSelectedThread = LLDB_INVALID_THREAD_ID0; |
87 | CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero(); |
88 | |
89 | m_bInitialized = MIstatus::success; |
90 | |
91 | return m_bInitialized; |
92 | } |
93 | |
94 | //++ ------------------------------------------------------------------------------------ |
95 | // Details: Release resources for *this object. |
96 | // Type: Method. |
97 | // Args: None. |
98 | // Return: MIstatus::success - Functionality succeeded. |
99 | // MIstatus::failure - Functionality failed. |
100 | // Throws: None. |
101 | //-- |
102 | bool CMICmnLLDBDebugSessionInfo::Shutdown( void ) |
103 | { |
104 | if( --m_clientUsageRefCnt > 0 ) |
105 | return MIstatus::success; |
106 | |
107 | if( !m_bInitialized ) |
108 | return MIstatus::success; |
109 | |
110 | bool bOk = MIstatus::success; |
111 | CMIUtilString errMsg; |
112 | |
113 | // Tidy up |
114 | bOk = SharedDataDestroy(); |
115 | if( !bOk ) |
116 | { |
117 | errMsg = CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE )CMICmnResources::Instance().GetString( IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE ).c_str() ); |
118 | errMsg += "\n"; |
119 | } |
120 | m_vecActiveThreadId.clear(); |
121 | CMICmnLLDBDebugSessionInfoVarObj::VarObjClear(); |
122 | |
123 | m_bInitialized = false; |
124 | |
125 | return MIstatus::success; |
126 | } |
127 | |
128 | //++ ------------------------------------------------------------------------------------ |
129 | // Details: Command instances can create and share data between other instances of commands. |
130 | // Data can also be assigned by a command and retrieved by LLDB event handler. |
131 | // This function takes down those resources build up over the use of the commands. |
132 | // This function should be called when the creation and running of command has |
133 | // stopped i.e. application shutdown. |
134 | // Type: Method. |
135 | // Args: None. |
136 | // Return: MIstatus::success - Functional succeeded. |
137 | // MIstatus::failure - Functional failed. |
138 | // Throws: None. |
139 | //-- |
140 | bool CMICmnLLDBDebugSessionInfo::SharedDataDestroy( void ) |
141 | { |
142 | m_mapIdToSessionData.Clear(); |
143 | m_vecVarObj.clear(); |
144 | m_mapBrkPtIdToBrkPtInfo.clear(); |
145 | |
146 | return MIstatus::success; |
147 | } |
148 | |
149 | //++ ------------------------------------------------------------------------------------ |
150 | // Details: Record information about a LLDB break point so that is can be recalled in other |
151 | // commands or LLDB event handling functions. |
152 | // Type: Method. |
153 | // Args: vBrkPtId - (R) LLDB break point ID. |
154 | // vrBrkPtInfo - (R) Break point information object. |
155 | // Return: MIstatus::success - Functional succeeded. |
156 | // MIstatus::failure - Functional failed. |
157 | // Throws: None. |
158 | //-- |
159 | bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfo( const MIuint vnBrkPtId, const SBrkPtInfo & vrBrkPtInfo ) |
160 | { |
161 | MapPairBrkPtIdToBrkPtInfo_t pr( vnBrkPtId, vrBrkPtInfo ); |
162 | m_mapBrkPtIdToBrkPtInfo.insert( pr ); |
163 | |
164 | return MIstatus::success; |
165 | } |
166 | |
167 | //++ ------------------------------------------------------------------------------------ |
168 | // Details: Retrieve information about a LLDB break point previous recorded either by |
169 | // commands or LLDB event handling functions. |
170 | // Type: Method. |
171 | // Args: vBrkPtId - (R) LLDB break point ID. |
172 | // vrwBrkPtInfo - (W) Break point information object. |
173 | // Return: MIstatus::success - Functional succeeded. |
174 | // MIstatus::failure - Functional failed. |
175 | // Throws: None. |
176 | //-- |
177 | bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoGet( const MIuint vnBrkPtId, SBrkPtInfo & vrwBrkPtInfo ) const |
178 | { |
179 | const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId ); |
180 | if( it != m_mapBrkPtIdToBrkPtInfo.end() ) |
181 | { |
182 | vrwBrkPtInfo = (*it).second; |
183 | return MIstatus::success; |
184 | } |
185 | |
186 | return MIstatus::failure; |
187 | } |
188 | |
189 | //++ ------------------------------------------------------------------------------------ |
190 | // Details: Delete information about a specific LLDB break point object. This function |
191 | // should be called when a LLDB break point is deleted. |
192 | // Type: Method. |
193 | // Args: vBrkPtId - (R) LLDB break point ID. |
194 | // Return: MIstatus::success - Functional succeeded. |
195 | // MIstatus::failure - Functional failed. |
196 | // Throws: None. |
197 | //-- |
198 | bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete( const MIuint vnBrkPtId ) |
199 | { |
200 | const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId ); |
201 | if( it != m_mapBrkPtIdToBrkPtInfo.end() ) |
202 | { |
203 | m_mapBrkPtIdToBrkPtInfo.erase( it ); |
204 | return MIstatus::success; |
205 | } |
206 | |
207 | return MIstatus::failure; |
208 | } |
209 | |
210 | //++ ------------------------------------------------------------------------------------ |
211 | // Details: Retrieve the specified thread's frame information. |
212 | // Type: Method. |
213 | // Args: vCmdData - (R) A command's information. |
214 | // vThreadIdx - (R) Thread index. |
215 | // vwrThreadFrames - (W) Frame data. |
216 | // Return: MIstatus::success - Functional succeeded. |
217 | // MIstatus::failure - Functional failed. |
218 | // Throws: None. |
219 | //-- |
220 | bool CMICmnLLDBDebugSessionInfo::GetThreadFrames( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMIUtilString & vwrThreadFrames ) |
221 | { |
222 | lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx ); |
223 | const uint32_t nFrames = thread.GetNumFrames(); |
224 | if( nFrames == 0 ) |
225 | { |
226 | // MI print "frame={}" |
227 | CMICmnMIValueTuple miValueTuple; |
228 | CMICmnMIValueResult miValueResult( "frame", miValueTuple ); |
229 | vwrThreadFrames = miValueResult.GetString(); |
230 | return MIstatus::success; |
231 | } |
232 | |
233 | // MI print "frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}, ..." |
234 | CMIUtilString strListCommaSeperated; |
235 | for( MIuint nLevel = 0; nLevel < nFrames; nLevel++ ) |
236 | { |
237 | lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel ); |
238 | lldb::addr_t pc = 0; |
239 | CMIUtilString fnName; |
240 | CMIUtilString fileName; |
241 | CMIUtilString path; |
242 | MIuint nLine = 0; |
243 | if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) ) |
244 | return MIstatus::failure; |
245 | |
246 | // Function args |
247 | CMICmnMIValueList miValueList( true ); |
248 | const MIuint maskVarTypes = 0x1000; |
249 | if( !MIResponseFormVariableInfo( frame, maskVarTypes, miValueList ) ) |
250 | return MIstatus::failure; |
251 | |
252 | const MIchar * pUnknown = "??"; |
253 | if( fnName != pUnknown ) |
254 | { |
255 | std::replace( fnName.begin(), fnName.end(), ')', ' ' ); |
256 | std::replace( fnName.begin(), fnName.end(), '(', ' ' ); |
257 | std::replace( fnName.begin(), fnName.end(), '\'', ' ' ); |
258 | } |
259 | |
260 | CMICmnMIValueTuple miValueTuple; |
261 | const CMIUtilString strLevel( CMIUtilString::Format( "%d", nLevel ) ); |
262 | const CMICmnMIValueConst miValueConst( strLevel ); |
263 | const CMICmnMIValueResult miValueResult( "level", miValueConst ); |
264 | miValueTuple.Add( miValueResult ); |
265 | if( !MIResponseFormFrameInfo2( pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple ) ) |
266 | return MIstatus::failure; |
267 | |
268 | const CMICmnMIValueResult miValueResult2( "frame", miValueTuple ); |
269 | if( nLevel != 0 ) |
270 | strListCommaSeperated += ","; |
271 | strListCommaSeperated += miValueResult2.GetString(); |
272 | } |
273 | |
274 | vwrThreadFrames = strListCommaSeperated; |
275 | |
276 | return MIstatus::success; |
277 | } |
278 | |
279 | // Todo: Refactor maybe to so only one function with this name, but not just yet |
280 | //++ ------------------------------------------------------------------------------------ |
281 | // Details: Retrieve the specified thread's frame information. |
282 | // Type: Method. |
283 | // Args: vCmdData - (R) A command's information. |
284 | // vThreadIdx - (R) Thread index. |
285 | // vwrThreadFrames - (W) Frame data. |
286 | // Return: MIstatus::success - Functional succeeded. |
287 | // MIstatus::failure - Functional failed. |
288 | // Throws: None. |
289 | //-- |
290 | bool CMICmnLLDBDebugSessionInfo::GetThreadFrames2( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMIUtilString & vwrThreadFrames ) |
291 | { |
292 | lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx ); |
293 | const uint32_t nFrames = thread.GetNumFrames(); |
294 | if( nFrames == 0 ) |
295 | { |
296 | // MI print "frame={}" |
297 | CMICmnMIValueTuple miValueTuple; |
298 | CMICmnMIValueResult miValueResult( "frame", miValueTuple ); |
299 | vwrThreadFrames = miValueResult.GetString(); |
300 | return MIstatus::success; |
301 | } |
302 | |
303 | // MI print "frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"},frame={level=\"%d\",addr=\"0x%08llx\",func=\"%s\",args=[%s],file=\"%s\",fullname=\"%s\",line=\"%d\"}, ..." |
304 | CMIUtilString strListCommaSeperated; |
305 | for( MIuint nLevel = 0; nLevel < nFrames; nLevel++ ) |
306 | { |
307 | lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel ); |
308 | lldb::addr_t pc = 0; |
309 | CMIUtilString fnName; |
310 | CMIUtilString fileName; |
311 | CMIUtilString path; |
312 | MIuint nLine = 0; |
313 | if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) ) |
314 | return MIstatus::failure; |
315 | |
316 | // Function args |
317 | CMICmnMIValueList miValueList( true ); |
318 | const MIuint maskVarTypes = 0x1000; |
319 | if( !MIResponseFormVariableInfo2( frame, maskVarTypes, miValueList ) ) |
320 | return MIstatus::failure; |
321 | |
322 | const MIchar * pUnknown = "??"; |
323 | if( fnName != pUnknown ) |
324 | { |
325 | std::replace( fnName.begin(), fnName.end(), ')', ' ' ); |
326 | std::replace( fnName.begin(), fnName.end(), '(', ' ' ); |
327 | std::replace( fnName.begin(), fnName.end(), '\'', ' ' ); |
328 | } |
329 | |
330 | CMICmnMIValueTuple miValueTuple; |
331 | const CMIUtilString strLevel( CMIUtilString::Format( "%d", nLevel ) ); |
332 | const CMICmnMIValueConst miValueConst( strLevel ); |
333 | const CMICmnMIValueResult miValueResult( "level", miValueConst ); |
334 | miValueTuple.Add( miValueResult ); |
335 | if( !MIResponseFormFrameInfo2( pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple ) ) |
336 | return MIstatus::failure; |
337 | |
338 | const CMICmnMIValueResult miValueResult2( "frame", miValueTuple ); |
339 | if( nLevel != 0 ) |
340 | strListCommaSeperated += ","; |
341 | strListCommaSeperated += miValueResult2.GetString(); |
342 | } |
343 | |
344 | vwrThreadFrames = strListCommaSeperated; |
345 | |
346 | return MIstatus::success; |
347 | } |
348 | |
349 | //++ ------------------------------------------------------------------------------------ |
350 | // Details: Return the resolved file's path for the given file. |
351 | // Type: Method. |
352 | // Args: vCmdData - (R) A command's information. |
353 | // vPath - (R) Original path. |
354 | // vwrResolvedPath - (W) Resolved path. |
355 | // Return: MIstatus::success - Functional succeeded. |
356 | // MIstatus::failure - Functional failed. |
357 | // Throws: None. |
358 | //-- |
359 | bool CMICmnLLDBDebugSessionInfo::ResolvePath( const SMICmdData & vCmdData, const CMIUtilString & vPath, CMIUtilString & vwrResolvedPath ) |
360 | { |
361 | // ToDo: Verify this code as it does not work as vPath is always empty |
362 | |
363 | CMIUtilString strResolvedPath; |
364 | if( !SharedDataRetrieve< CMIUtilString >( m_constStrSharedDataKeyWkDir, strResolvedPath ) ) |
365 | { |
366 | vwrResolvedPath = ""; |
367 | 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(), m_constStrSharedDataKeyWkDir.c_str() ) ); |
368 | return MIstatus::failure; |
369 | } |
370 | |
371 | vwrResolvedPath = vPath; |
372 | |
373 | return ResolvePath( strResolvedPath, vwrResolvedPath ); |
374 | } |
375 | |
376 | //++ ------------------------------------------------------------------------------------ |
377 | // Details: Return the resolved file's path for the given file. |
378 | // Type: Method. |
379 | // Args: vstrUnknown - (R) String assigned to path when resolved path is empty. |
380 | // vwrResolvedPath - (RW) The original path overwritten with resolved path. |
381 | // Return: MIstatus::success - Functional succeeded. |
382 | // MIstatus::failure - Functional failed. |
383 | // Throws: None. |
384 | //-- |
385 | bool CMICmnLLDBDebugSessionInfo::ResolvePath( const CMIUtilString & vstrUnknown, CMIUtilString & vwrResolvedPath ) |
386 | { |
387 | if( vwrResolvedPath.size() < 1 ) |
388 | { |
389 | vwrResolvedPath = vstrUnknown; |
390 | return MIstatus::success; |
391 | } |
392 | |
393 | bool bOk = MIstatus::success; |
394 | |
395 | CMIUtilString::VecString_t vecPathFolders; |
396 | const MIuint nSplits = vwrResolvedPath.Split( "/", vecPathFolders ); MIunused( nSplits )(void) nSplits;; |
397 | MIuint nFoldersBack = 1; // 1 is just the file (last element of vector) |
398 | while( bOk && (vecPathFolders.size() >= nFoldersBack) ) |
399 | { |
400 | CMIUtilString strTestPath; |
401 | MIuint nFoldersToAdd = nFoldersBack; |
402 | while( nFoldersToAdd > 0 ) |
403 | { |
404 | strTestPath += "/"; |
405 | strTestPath += vecPathFolders[ vecPathFolders.size() - nFoldersToAdd ]; |
406 | nFoldersToAdd--; |
407 | } |
408 | bool bYesAccessible = false; |
409 | bOk = AccessPath( strTestPath, bYesAccessible ); |
410 | if( bYesAccessible ) |
411 | { |
412 | vwrResolvedPath = strTestPath; |
413 | return MIstatus::success; |
414 | } |
415 | else |
416 | nFoldersBack++; |
417 | } |
418 | |
419 | // No files exist in the union of working directory and debuginfo path |
420 | // Simply use the debuginfo path and let the IDE handle it. |
421 | |
422 | return bOk; |
423 | } |
424 | |
425 | //++ ------------------------------------------------------------------------------------ |
426 | // Details: Determine the given file path exists or not. |
427 | // Type: Method. |
428 | // Args: vPath - (R) File name path. |
429 | // vwbYesAccessible - (W) True - file exists, false = does not exist. |
430 | // Return: MIstatus::success - Functional succeeded. |
431 | // MIstatus::failure - Functional failed. |
432 | // Throws: None. |
433 | //-- |
434 | bool CMICmnLLDBDebugSessionInfo::AccessPath( const CMIUtilString & vPath, bool & vwbYesAccessible ) |
435 | { |
436 | #ifdef _WIN32 |
437 | vwbYesAccessible = (::_access( vPath.c_str(), 0 ) == 0); |
438 | #else |
439 | vwbYesAccessible = (::access( vPath.c_str(), 0 ) == 0); |
440 | #endif // _WIN32 |
441 | |
442 | return MIstatus::success; |
443 | } |
444 | |
445 | //++ ------------------------------------------------------------------------------------ |
446 | // Details: Form MI partial response by appending more MI value type objects to the |
447 | // tuple type object past in. |
448 | // Type: Method. |
449 | // Args: vCmdData - (R) A command's information. |
450 | // vrThread - (R) LLDB thread object. |
451 | // vwrMIValueTuple - (W) MI value tuple object. |
452 | // Return: MIstatus::success - Functional succeeded. |
453 | // MIstatus::failure - Functional failed. |
454 | // Throws: None. |
455 | //-- |
456 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple ) |
457 | { |
458 | lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread ); |
459 | |
460 | CMIUtilString strFrames; |
461 | if( !GetThreadFrames( vCmdData, rThread.GetIndexID(), strFrames ) ) |
462 | return MIstatus::failure; |
463 | |
464 | const bool bSuspended = rThread.IsSuspended(); |
465 | const lldb::StopReason eReason = rThread.GetStopReason(); |
466 | const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); |
467 | const CMIUtilString strState( (bSuspended || bValidReason) ? "stopped" : "running" ); |
468 | |
469 | // Add "id" |
470 | const CMIUtilString strId( CMIUtilString::Format( "%d", rThread.GetIndexID() ) ); |
471 | const CMICmnMIValueConst miValueConst1( strId ); |
472 | const CMICmnMIValueResult miValueResult1( "id", miValueConst1 ); |
473 | if( !vwrMIValueTuple.Add( miValueResult1 ) ) |
474 | return MIstatus::failure; |
475 | |
476 | // Add "target-id" |
477 | const MIchar * pThreadName = rThread.GetName(); |
478 | const MIuint len = (pThreadName != nullptr) ? CMIUtilString( pThreadName ).length() : 0; |
479 | const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && CMIUtilString::IsAllValidAlphaAndNumeric( *pThreadName ) ); // 32 is arbitary number |
480 | const MIchar * pThrdFmt = bHaveName ? "%s" : "Thread %d"; |
481 | CMIUtilString strThread; |
482 | if( bHaveName ) |
483 | strThread = CMIUtilString::Format( pThrdFmt, pThreadName ); |
484 | else |
485 | strThread = CMIUtilString::Format( pThrdFmt, rThread.GetIndexID() ); |
486 | const CMICmnMIValueConst miValueConst2( strThread ); |
487 | const CMICmnMIValueResult miValueResult2( "target-id", miValueConst2 ); |
488 | if( !vwrMIValueTuple.Add( miValueResult2 ) ) |
489 | return MIstatus::failure; |
490 | |
491 | // Add "frame" |
492 | const CMICmnMIValueConst miValueConst3( strFrames, true ); |
493 | if( !vwrMIValueTuple.Add( miValueConst3, false ) ) |
494 | return MIstatus::failure; |
495 | |
496 | // Add "state" |
497 | const CMICmnMIValueConst miValueConst4( strState ); |
498 | const CMICmnMIValueResult miValueResult4( "state", miValueConst4 ); |
499 | if( !vwrMIValueTuple.Add( miValueResult4 ) ) |
500 | return MIstatus::failure; |
501 | |
502 | return MIstatus::success; |
503 | } |
504 | |
505 | // Todo: Refactor maybe to so only one function with this name, but not just yet |
506 | //++ ------------------------------------------------------------------------------------ |
507 | // Details: Form MI partial response by appending more MI value type objects to the |
508 | // tuple type object past in. |
509 | // Type: Method. |
510 | // Args: vCmdData - (R) A command's information. |
511 | // vrThread - (R) LLDB thread object. |
512 | // vwrMIValueTuple - (W) MI value tuple object. |
513 | // Return: MIstatus::success - Functional succeeded. |
514 | // MIstatus::failure - Functional failed. |
515 | // Throws: None. |
516 | //-- |
517 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo3( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple ) |
518 | { |
519 | lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread ); |
520 | |
521 | CMIUtilString strFrames; |
522 | if( !GetThreadFrames2( vCmdData, rThread.GetIndexID(), strFrames ) ) |
523 | return MIstatus::failure; |
524 | |
525 | const bool bSuspended = rThread.IsSuspended(); |
526 | const lldb::StopReason eReason = rThread.GetStopReason(); |
527 | const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); |
528 | const CMIUtilString strState( (bSuspended || bValidReason) ? "stopped" : "running" ); |
529 | |
530 | // Add "id" |
531 | const CMIUtilString strId( CMIUtilString::Format( "%d", rThread.GetIndexID() ) ); |
532 | const CMICmnMIValueConst miValueConst1( strId ); |
533 | const CMICmnMIValueResult miValueResult1( "id", miValueConst1 ); |
534 | if( !vwrMIValueTuple.Add( miValueResult1 ) ) |
535 | return MIstatus::failure; |
536 | |
537 | // Add "target-id" |
538 | const MIchar * pThreadName = rThread.GetName(); |
539 | const MIuint len = (pThreadName != nullptr) ? CMIUtilString( pThreadName ).length() : 0; |
540 | const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && CMIUtilString::IsAllValidAlphaAndNumeric( *pThreadName ) ); // 32 is arbitary number |
541 | const MIchar * pThrdFmt = bHaveName ? "%s" : "Thread %d"; |
542 | CMIUtilString strThread; |
543 | if( bHaveName ) |
544 | strThread = CMIUtilString::Format( pThrdFmt, pThreadName ); |
545 | else |
546 | strThread = CMIUtilString::Format( pThrdFmt, rThread.GetIndexID() ); |
547 | const CMICmnMIValueConst miValueConst2( strThread ); |
548 | const CMICmnMIValueResult miValueResult2( "target-id", miValueConst2 ); |
549 | if( !vwrMIValueTuple.Add( miValueResult2 ) ) |
550 | return MIstatus::failure; |
551 | |
552 | // Add "frame" |
553 | const CMICmnMIValueConst miValueConst3( strFrames, true ); |
554 | if( !vwrMIValueTuple.Add( miValueConst3, false ) ) |
555 | return MIstatus::failure; |
556 | |
557 | // Add "state" |
558 | const CMICmnMIValueConst miValueConst4( strState ); |
559 | const CMICmnMIValueResult miValueResult4( "state", miValueConst4 ); |
560 | if( !vwrMIValueTuple.Add( miValueResult4 ) ) |
561 | return MIstatus::failure; |
562 | |
563 | return MIstatus::success; |
564 | } |
565 | |
566 | // Todo: Refactor maybe to so only one function with this name, but not just yet |
567 | //++ ------------------------------------------------------------------------------------ |
568 | // Details: Form MI partial response by appending more MI value type objects to the |
569 | // tuple type object past in. |
570 | // Type: Method. |
571 | // Args: vCmdData - (R) A command's information. |
572 | // vrThread - (R) LLDB thread object. |
573 | // vwrMIValueTuple - (W) MI value tuple object. |
574 | // Return: MIstatus::success - Functional succeeded. |
575 | // MIstatus::failure - Functional failed. |
576 | // Throws: None. |
577 | //-- |
578 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple ) |
579 | { |
580 | lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread ); |
581 | |
582 | const bool bSuspended = rThread.IsSuspended(); |
583 | const lldb::StopReason eReason = rThread.GetStopReason(); |
584 | const bool bValidReason = !((eReason == lldb::eStopReasonNone) || (eReason == lldb::eStopReasonInvalid)); |
585 | const CMIUtilString strState( (bSuspended || bValidReason) ? "stopped" : "running" ); |
586 | |
587 | // Add "id" |
588 | const CMIUtilString strId( CMIUtilString::Format( "%d", rThread.GetIndexID() ) ); |
589 | const CMICmnMIValueConst miValueConst1( strId ); |
590 | const CMICmnMIValueResult miValueResult1( "id", miValueConst1 ); |
591 | if( !vwrMIValueTuple.Add( miValueResult1 ) ) |
592 | return MIstatus::failure; |
593 | |
594 | // Add "target-id" |
595 | const MIchar * pThreadName = rThread.GetName(); |
596 | const MIuint len = (pThreadName != nullptr) ? CMIUtilString( pThreadName ).length() : 0; |
597 | const bool bHaveName = ((pThreadName != nullptr) && (len > 0) && (len < 32) && CMIUtilString::IsAllValidAlphaAndNumeric( *pThreadName ) ); // 32 is arbitary number |
598 | const MIchar * pThrdFmt = bHaveName ? "%s" : "Thread %d"; |
599 | CMIUtilString strThread; |
600 | if( bHaveName ) |
601 | strThread = CMIUtilString::Format( pThrdFmt, pThreadName ); |
602 | else |
603 | strThread = CMIUtilString::Format( pThrdFmt, rThread.GetIndexID() ); |
604 | const CMICmnMIValueConst miValueConst2( strThread ); |
605 | const CMICmnMIValueResult miValueResult2( "target-id", miValueConst2 ); |
606 | if( !vwrMIValueTuple.Add( miValueResult2 ) ) |
607 | return MIstatus::failure; |
608 | |
609 | // Add "state" |
610 | const CMICmnMIValueConst miValueConst4( strState ); |
611 | const CMICmnMIValueResult miValueResult4( "state", miValueConst4 ); |
612 | if( !vwrMIValueTuple.Add( miValueResult4 ) ) |
613 | return MIstatus::failure; |
614 | |
615 | return MIstatus::success; |
616 | } |
617 | |
618 | // Todo: Refactor maybe to so only one function with this name, but not just yet |
619 | //++ ------------------------------------------------------------------------------------ |
620 | // Details: Form MI partial response by appending more MI value type objects to the |
621 | // tuple type object past in. |
622 | // Type: Method. |
623 | // Args: vrFrame - (R) LLDB thread object. |
624 | // vMaskVarTypes - (R) 0x1000 = arguments, |
625 | // 0x0100 = locals, |
626 | // 0x0010 = statics, |
627 | // 0x0001 = in scope only. |
628 | // vwrMIValueList - (W) MI value list object. |
629 | // Return: MIstatus::success - Functional succeeded. |
630 | // MIstatus::failure - Functional failed. |
631 | // Throws: None. |
632 | //-- |
633 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList ) |
634 | { |
635 | bool bOk = MIstatus::success; |
636 | lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame ); |
637 | |
638 | const bool bArg = (vMaskVarTypes & 0x1000); |
639 | const bool bLocals = (vMaskVarTypes & 0x0100); |
640 | const bool bStatics = (vMaskVarTypes & 0x0010); |
641 | const bool bInScopeOnly = (vMaskVarTypes & 0x0001); |
642 | lldb::SBValueList listArg = rFrame.GetVariables( bArg, bLocals, bStatics, bInScopeOnly ); |
643 | const MIuint nArgs = listArg.GetSize(); |
644 | for( MIuint i = 0; bOk && (i < nArgs); i++ ) |
645 | { |
646 | lldb::SBValue value = listArg.GetValueAtIndex( i ); |
647 | const CMICmnLLDBUtilSBValue utilValue( value ); |
648 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
649 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
650 | CMICmnMIValueTuple miValueTuple( miValueResult ); |
651 | const CMICmnMIValueConst miValueConst2( utilValue.GetValue() ); |
652 | const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
653 | miValueTuple.Add( miValueResult2 ); |
654 | bOk = vwrMiValueList.Add( miValueTuple ); |
655 | } |
656 | |
657 | return bOk; |
658 | } |
659 | |
660 | //++ ------------------------------------------------------------------------------------ |
661 | // Details: Form MI partial response by appending more MI value type objects to the |
662 | // tuple type object past in. |
663 | // Type: Method. |
664 | // Args: vrFrame - (R) LLDB thread object. |
665 | // vMaskVarTypes - (R) 0x1000 = arguments, |
666 | // 0x0100 = locals, |
667 | // 0x0010 = statics, |
668 | // 0x0001 = in scope only. |
669 | // vwrMIValueList - (W) MI value list object. |
670 | // Return: MIstatus::success - Functional succeeded. |
671 | // MIstatus::failure - Functional failed. |
672 | // Throws: None. |
673 | //-- |
674 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList ) |
675 | { |
676 | bool bOk = MIstatus::success; |
677 | lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame ); |
678 | |
679 | const bool bArg = (vMaskVarTypes & 0x1000); |
680 | const bool bLocals = (vMaskVarTypes & 0x0100); |
681 | const bool bStatics = (vMaskVarTypes & 0x0010); |
682 | const bool bInScopeOnly = (vMaskVarTypes & 0x0001); |
683 | const MIuint nMaxRecusiveDepth = 10; |
684 | MIuint nCurrentRecursiveDepth = 0; |
685 | lldb::SBValueList listArg = rFrame.GetVariables( bArg, bLocals, bStatics, bInScopeOnly ); |
686 | const MIuint nArgs = listArg.GetSize(); |
687 | for( MIuint i = 0; bOk && (i < nArgs); i++ ) |
688 | { |
689 | lldb::SBValue value = listArg.GetValueAtIndex( i ); |
690 | bOk = GetVariableInfo( nMaxRecusiveDepth, value, false, vwrMiValueList, nCurrentRecursiveDepth ); |
691 | } |
692 | |
693 | return bOk; |
694 | } |
695 | |
696 | // *** Do not refactor this function to be one function with same name as it can break more than |
697 | // *** than one stack type command |
698 | //++ ------------------------------------------------------------------------------------ |
699 | // Details: Form MI partial response by appending more MI value type objects to the |
700 | // tuple type object past in. |
701 | // Type: Method. |
702 | // Args: vrFrame - (R) LLDB thread object. |
703 | // vMaskVarTypes - (R) 0x1000 = arguments, |
704 | // 0x0100 = locals, |
705 | // 0x0010 = statics, |
706 | // 0x0001 = in scope only. |
707 | // vwrMIValueList - (W) MI value list object. |
708 | // Return: MIstatus::success - Functional succeeded. |
709 | // MIstatus::failure - Functional failed. |
710 | // Throws: None. |
711 | //-- |
712 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo3( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList ) |
713 | { |
714 | bool bOk = MIstatus::success; |
715 | lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame ); |
716 | |
717 | const bool bArg = (vMaskVarTypes & 0x1000); |
718 | const bool bLocals = (vMaskVarTypes & 0x0100); |
719 | const bool bStatics = (vMaskVarTypes & 0x0010); |
720 | const bool bInScopeOnly = (vMaskVarTypes & 0x0001); |
721 | const MIuint nMaxRecusiveDepth = 10; |
722 | MIuint nCurrentRecursiveDepth = 0; |
723 | lldb::SBValueList listArg = rFrame.GetVariables( bArg, bLocals, bStatics, bInScopeOnly ); |
724 | const MIuint nArgs = listArg.GetSize(); |
725 | for( MIuint i = 0; bOk && (i < nArgs); i++ ) |
726 | { |
727 | lldb::SBValue value = listArg.GetValueAtIndex( i ); |
728 | bOk = GetVariableInfo2( nMaxRecusiveDepth, value, false, vwrMiValueList, nCurrentRecursiveDepth ); |
729 | } |
730 | |
731 | return bOk; |
732 | } |
733 | |
734 | // *** Do not refactor this function to be one function with same name as it can break more than |
735 | // *** than one stack type command |
736 | //++ ------------------------------------------------------------------------------------ |
737 | // Details: Extract the value's name and value or recurse into child value object. |
738 | // Type: Method. |
739 | // Args: vnMaxDepth - (R) The max recursive depth for this function. |
740 | // vrValue - (R) LLDB value object. |
741 | // vbIsChildValue - (R) True = Value object is a child of a higher Value object, |
742 | // - False = Value object not a child. |
743 | // vwrMIValueList - (W) MI value list object. |
744 | // vnDepth - (RW) The current recursive depth of this function. |
745 | // // Return: MIstatus::success - Functional succeeded. |
746 | // MIstatus::failure - Functional failed. |
747 | // Throws: None. |
748 | //-- |
749 | bool CMICmnLLDBDebugSessionInfo::GetVariableInfo( const MIuint vnMaxDepth, const lldb::SBValue & vrValue, const bool vbIsChildValue, CMICmnMIValueList & vwrMiValueList, MIuint & vrwnDepth ) |
750 | { |
751 | // *** Update GetVariableInfo2() with any code changes here *** |
752 | |
753 | // Check recursive depth |
754 | if( vrwnDepth >= vnMaxDepth ) |
755 | return MIstatus::success; |
756 | |
757 | bool bOk = MIstatus::success; |
758 | lldb::SBValue & rValue = const_cast< lldb::SBValue & >( vrValue ); |
759 | const CMICmnLLDBUtilSBValue utilValue( vrValue, true ); |
760 | CMICmnMIValueTuple miValueTuple; |
761 | const MIchar * pName = rValue.GetName(); MIunused( pName )(void) pName;; |
762 | const bool bIsPointerType = rValue.GetType().IsPointerType(); |
763 | const MIuint nChildren = rValue.GetNumChildren(); |
764 | if( nChildren == 0 ) |
765 | { |
766 | if( vbIsChildValue ) |
767 | { |
768 | if( utilValue.IsCharType() ) |
769 | { |
770 | // For char types and try to form text string |
771 | const CMICmnMIValueConst miValueConst( utilValue.GetValue().c_str(), true ); |
772 | miValueTuple.Add( miValueConst, true ); |
773 | } |
774 | else |
775 | { |
776 | // For composite types |
777 | const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%s = %s", utilValue.GetName().c_str(), utilValue.GetValue().c_str() ), true ); |
778 | miValueTuple.Add( miValueConst, true ); |
779 | } |
780 | return vwrMiValueList.Add( CMICmnMIValueConst( miValueTuple.ExtractContentNoBrackets(), true ) ); |
781 | } |
782 | else |
783 | { |
784 | // Basic types |
785 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
786 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
787 | miValueTuple.Add( miValueResult ); |
788 | const CMICmnMIValueConst miValueConst2( utilValue.GetValue() ); |
789 | const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
790 | miValueTuple.Add( miValueResult2 ); |
791 | return vwrMiValueList.Add( miValueTuple ); |
792 | } |
793 | } |
794 | else if( bIsPointerType && utilValue.IsChildCharType() ) |
795 | { |
796 | // Append string text to the parent value information |
797 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
798 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
799 | miValueTuple.Add( miValueResult ); |
800 | |
801 | const CMIUtilString & rText( utilValue.GetChildValueCString() ); |
802 | if( rText.empty() ) |
803 | { |
804 | const CMICmnMIValueConst miValueConst( utilValue.GetValue() ); |
805 | const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
806 | miValueTuple.Add( miValueResult ); |
807 | } |
808 | else |
809 | { |
810 | if( utilValue.IsValueUnknown() ) |
811 | { |
812 | const CMICmnMIValueConst miValueConst( rText ); |
813 | const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
814 | miValueTuple.Add( miValueResult ); |
815 | } |
816 | else |
817 | { |
818 | // Note code that has const in will not show the text suffix to the string pointer |
819 | // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this |
820 | // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this |
821 | const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%s %s", utilValue.GetValue().c_str(), rText.c_str() ) ); |
822 | const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
823 | miValueTuple.Add( miValueResult ); |
824 | } |
825 | } |
826 | return vwrMiValueList.Add( miValueTuple ); |
827 | } |
828 | else if( bIsPointerType ) |
829 | { |
830 | if( vbIsChildValue ) |
831 | { |
832 | // For composite types |
833 | const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%s = %s", utilValue.GetName().c_str(), utilValue.GetValue().c_str() ), true ); |
834 | miValueTuple.Add( miValueConst, true ); |
835 | return vwrMiValueList.Add( CMICmnMIValueConst( miValueTuple.ExtractContentNoBrackets(), true ) ); |
836 | } |
837 | else |
838 | { |
839 | // Basic types |
840 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
841 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
842 | miValueTuple.Add( miValueResult ); |
843 | const CMICmnMIValueConst miValueConst2( utilValue.GetValue() ); |
844 | const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
845 | miValueTuple.Add( miValueResult2 ); |
846 | return vwrMiValueList.Add( miValueTuple ); |
847 | } |
848 | } |
849 | else |
850 | { |
851 | // Build parent child composite types |
852 | CMICmnMIValueList miValueList( true ); |
853 | for( MIuint i = 0; bOk && (i < nChildren); i++ ) |
854 | { |
855 | lldb::SBValue member = rValue.GetChildAtIndex( i ); |
856 | bOk = GetVariableInfo( vnMaxDepth, member, true, miValueList, ++vrwnDepth ); |
857 | } |
858 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
859 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
860 | miValueTuple.Add( miValueResult ); |
861 | const CMICmnMIValueConst miValueConst2( CMIUtilString::Format( "{%s}", miValueList.ExtractContentNoBrackets().c_str() ) ); |
862 | const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
863 | miValueTuple.Add( miValueResult2 ); |
864 | return vwrMiValueList.Add( miValueTuple ); |
865 | } |
866 | } |
867 | |
868 | // *** Do not refactor this function to be one function with same name as it can break more than |
869 | // *** than one stack type command |
870 | //++ ------------------------------------------------------------------------------------ |
871 | // Details: Extract the value's name and value or recurse into child value object. |
872 | // Type: Method. |
873 | // Args: vnMaxDepth - (R) The max recursive depth for this function. |
874 | // vrValue - (R) LLDB value object. |
875 | // vbIsChildValue - (R) True = Value object is a child of a higher Value object, |
876 | // - False = Value object not a child. |
877 | // vwrMIValueList - (W) MI value list object. |
878 | // vnDepth - (RW) The current recursive depth of this function. |
879 | // // Return: MIstatus::success - Functional succeeded. |
880 | // MIstatus::failure - Functional failed. |
881 | // Throws: None. |
882 | //-- |
883 | bool CMICmnLLDBDebugSessionInfo::GetVariableInfo2( const MIuint vnMaxDepth, const lldb::SBValue & vrValue, const bool vbIsChildValue, CMICmnMIValueList & vwrMiValueList, MIuint & vrwnDepth ) |
884 | { |
885 | // *** Update GetVariableInfo() with any code changes here *** |
886 | |
887 | // Check recursive depth |
888 | if( vrwnDepth >= vnMaxDepth ) |
889 | return MIstatus::success; |
890 | |
891 | bool bOk = MIstatus::success; |
892 | lldb::SBValue & rValue = const_cast< lldb::SBValue & >( vrValue ); |
893 | const CMICmnLLDBUtilSBValue utilValue( vrValue, true ); |
894 | CMICmnMIValueTuple miValueTuple; |
895 | const MIchar * pName = rValue.GetName(); MIunused( pName )(void) pName;; |
896 | const MIuint nChildren = rValue.GetNumChildren(); |
897 | if( nChildren == 0 ) |
898 | { |
899 | if( vbIsChildValue && utilValue.IsCharType() ) |
900 | { |
901 | // For char types and try to form text string |
902 | const CMICmnMIValueConst miValueConst( utilValue.GetValue().c_str(), true ); |
903 | miValueTuple.Add( miValueConst, true ); |
904 | return vwrMiValueList.Add( CMICmnMIValueConst( miValueTuple.ExtractContentNoBrackets(), true ) ); |
905 | } |
906 | else |
907 | { |
908 | // Basic types |
909 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
910 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
911 | miValueTuple.Add( miValueResult ); |
912 | const CMICmnMIValueConst miValueConst2( utilValue.GetValue() ); |
913 | const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
914 | miValueTuple.Add( miValueResult2 ); |
915 | return vwrMiValueList.Add( miValueTuple ); |
916 | } |
917 | } |
918 | else if( utilValue.IsChildCharType() ) |
919 | { |
920 | // Append string text to the parent value information |
921 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
922 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
923 | miValueTuple.Add( miValueResult ); |
924 | |
925 | const CMIUtilString & rText( utilValue.GetChildValueCString() ); |
926 | if( rText.empty() ) |
927 | { |
928 | const CMICmnMIValueConst miValueConst( utilValue.GetValue() ); |
929 | const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
930 | miValueTuple.Add( miValueResult ); |
931 | } |
932 | else |
933 | { |
934 | if( utilValue.IsValueUnknown() ) |
935 | { |
936 | const CMICmnMIValueConst miValueConst( rText ); |
937 | const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
938 | miValueTuple.Add( miValueResult ); |
939 | } |
940 | else |
941 | { |
942 | // Note code that has const in will not show the text suffix to the string pointer |
943 | // i.e. const char * pMyStr = "blah"; ==> "0x00007000"" <-- Eclipse shows this |
944 | // but char * pMyStr = "blah"; ==> "0x00007000" "blah"" <-- Eclipse shows this |
945 | const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%s %s", utilValue.GetValue().c_str(), rText.c_str() ) ); |
946 | const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
947 | miValueTuple.Add( miValueResult ); |
948 | } |
949 | } |
950 | return vwrMiValueList.Add( miValueTuple ); |
951 | } |
952 | else |
953 | { |
954 | // Build parent child composite types |
955 | CMICmnMIValueList miValueList( true ); |
956 | for( MIuint i = 0; bOk && (i < nChildren); i++ ) |
957 | { |
958 | lldb::SBValue member = rValue.GetChildAtIndex( i ); |
959 | bOk = GetVariableInfo( vnMaxDepth, member, true, miValueList, ++vrwnDepth ); |
960 | } |
961 | const CMICmnMIValueConst miValueConst( utilValue.GetName() ); |
962 | const CMICmnMIValueResult miValueResult( "name", miValueConst ); |
963 | miValueTuple.Add( miValueResult ); |
964 | const CMICmnMIValueConst miValueConst2( CMIUtilString::Format( "{%s}", miValueList.ExtractContentNoBrackets().c_str() ) ); |
965 | const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
966 | miValueTuple.Add( miValueResult2 ); |
967 | return vwrMiValueList.Add( miValueTuple ); |
968 | } |
969 | } |
970 | |
971 | //++ ------------------------------------------------------------------------------------ |
972 | // Details: Form MI partial response by appending more MI value type objects to the |
973 | // tuple type object past in. |
974 | // Type: Method. |
975 | // Args: vrThread - (R) LLDB thread object. |
976 | // vwrMIValueTuple - (W) MI value tuple object. |
977 | // Return: MIstatus::success - Functional succeeded. |
978 | // MIstatus::failure - Functional failed. |
979 | // Throws: None. |
980 | //-- |
981 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::SBThread & vrThread, const MIuint vnLevel, CMICmnMIValueTuple & vwrMiValueTuple ) |
982 | { |
983 | lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread ); |
984 | |
985 | lldb::SBFrame frame = rThread.GetFrameAtIndex( vnLevel ); |
986 | lldb::addr_t pc = 0; |
987 | CMIUtilString fnName; |
988 | CMIUtilString fileName; |
989 | CMIUtilString path; |
990 | MIuint nLine = 0; |
991 | if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) ) |
992 | return MIstatus::failure; |
993 | |
994 | // MI print "{level=\"0\",addr=\"0x%08llx\",func=\"%s\",file=\"%s\",fullname=\"%s\",line=\"%d\"}" |
995 | const CMIUtilString strLevel( CMIUtilString::Format( "%d", vnLevel ) ); |
996 | const CMICmnMIValueConst miValueConst( strLevel ); |
997 | const CMICmnMIValueResult miValueResult( "level", miValueConst ); |
998 | CMICmnMIValueTuple miValueTuple( miValueResult ); |
999 | if( !MIResponseFormFrameInfo( pc, fnName, fileName, path, nLine, miValueTuple ) ) |
1000 | return MIstatus::failure; |
1001 | |
1002 | vwrMiValueTuple = miValueTuple; |
1003 | |
1004 | return MIstatus::success; |
1005 | } |
1006 | |
1007 | //++ ------------------------------------------------------------------------------------ |
1008 | // Details: Retrieve the frame information from LLDB frame object. |
1009 | // Type: Method. |
1010 | // Args: vrFrame - (R) LLDB thread object. |
1011 | // vPc - (W) Address number. |
1012 | // vFnName - (W) Function name. |
1013 | // vFileName - (W) File name text. |
1014 | // vPath - (W) Full file name and path text. |
1015 | // vnLine - (W) File line number. |
1016 | // Return: MIstatus::success - Functional succeeded. |
1017 | // MIstatus::failure - Functional failed. |
1018 | // Throws: None. |
1019 | //-- |
1020 | bool CMICmnLLDBDebugSessionInfo::GetFrameInfo( const lldb::SBFrame & vrFrame, lldb::addr_t & vwPc, CMIUtilString & vwFnName, CMIUtilString & vwFileName, CMIUtilString & vwPath, MIuint & vwnLine ) |
1021 | { |
1022 | lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame ); |
1023 | |
1024 | static char pBuffer[ MAX_PATH4096 ]; |
1025 | const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath( &pBuffer[ 0 ], sizeof( pBuffer ) ); MIunused( nBytes )(void) nBytes;; |
1026 | CMIUtilString strResolvedPath( &pBuffer[ 0 ] ); |
1027 | const MIchar * pUnkwn = "??"; |
1028 | if( !ResolvePath( pUnkwn, strResolvedPath ) ) |
1029 | return MIstatus::failure; |
1030 | vwPath = strResolvedPath; |
1031 | |
1032 | vwPc = rFrame.GetPC(); |
1033 | |
1034 | const MIchar * pFnName = rFrame.GetFunctionName(); |
1035 | vwFnName = (pFnName != nullptr) ? pFnName : pUnkwn; |
1036 | |
1037 | const MIchar * pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename(); |
1038 | vwFileName = (pFileName != nullptr) ? pFileName : pUnkwn; |
1039 | |
1040 | vwnLine = rFrame.GetLineEntry().GetLine(); |
1041 | |
1042 | return MIstatus::success; |
1043 | } |
1044 | |
1045 | //++ ------------------------------------------------------------------------------------ |
1046 | // Details: Form MI partial response by appending more MI value type objects to the |
1047 | // tuple type object past in. |
1048 | // Type: Method. |
1049 | // Args: vPc - (R) Address number. |
1050 | // vFnName - (R) Function name. |
1051 | // vFileName - (R) File name text. |
1052 | // vPath - (R) Full file name and path text. |
1053 | // vnLine - (R) File line number. |
1054 | // vwrMIValueTuple - (W) MI value tuple object. |
1055 | // Return: MIstatus::success - Functional succeeded. |
1056 | // MIstatus::failure - Functional failed. |
1057 | // Throws: None. |
1058 | //-- |
1059 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple ) |
1060 | { |
1061 | const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vPc ) ); |
1062 | const CMICmnMIValueConst miValueConst2( strAddr ); |
1063 | const CMICmnMIValueResult miValueResult2( "addr", miValueConst2 ); |
1064 | if( !vwrMiValueTuple.Add( miValueResult2 ) ) |
1065 | return MIstatus::failure; |
1066 | const CMICmnMIValueConst miValueConst3( vFnName ); |
1067 | const CMICmnMIValueResult miValueResult3( "func", miValueConst3 ); |
1068 | if( !vwrMiValueTuple.Add( miValueResult3 ) ) |
1069 | return MIstatus::failure; |
1070 | const CMICmnMIValueConst miValueConst5( vFileName ); |
1071 | const CMICmnMIValueResult miValueResult5( "file", miValueConst5 ); |
1072 | if( !vwrMiValueTuple.Add( miValueResult5 ) ) |
1073 | return MIstatus::failure; |
1074 | const CMICmnMIValueConst miValueConst6( vPath ); |
1075 | const CMICmnMIValueResult miValueResult6( "fullname", miValueConst6 ); |
1076 | if( !vwrMiValueTuple.Add( miValueResult6 ) ) |
1077 | return MIstatus::failure; |
1078 | const CMIUtilString strLine( CMIUtilString::Format( "%d", vnLine ) ); |
1079 | const CMICmnMIValueConst miValueConst7( strLine ); |
1080 | const CMICmnMIValueResult miValueResult7( "line", miValueConst7 ); |
1081 | if( !vwrMiValueTuple.Add( miValueResult7 ) ) |
1082 | return MIstatus::failure; |
1083 | |
1084 | return MIstatus::success; |
1085 | } |
1086 | |
1087 | // Todo: Refactor maybe to so only one function with this name, but not just yet |
1088 | //++ ------------------------------------------------------------------------------------ |
1089 | // Details: Form MI partial response by appending more MI value type objects to the |
1090 | // tuple type object past in. |
1091 | // Type: Method. |
1092 | // Args: vPc - (R) Address number. |
1093 | // vArgInfo - (R) Args information in MI response form. |
1094 | // vFnName - (R) Function name. |
1095 | // vFileName - (R) File name text. |
1096 | // vPath - (R) Full file name and path text. |
1097 | // vnLine - (R) File line number. |
1098 | // vwrMIValueTuple - (W) MI value tuple object. |
1099 | // Return: MIstatus::success - Functional succeeded. |
1100 | // MIstatus::failure - Functional failed. |
1101 | // Throws: None. |
1102 | //-- |
1103 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo2( const lldb::addr_t vPc, const CMIUtilString & vArgInfo, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple ) |
1104 | { |
1105 | const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vPc ) ); |
1106 | const CMICmnMIValueConst miValueConst2( strAddr ); |
1107 | const CMICmnMIValueResult miValueResult2( "addr", miValueConst2 ); |
1108 | if( !vwrMiValueTuple.Add( miValueResult2 ) ) |
1109 | return MIstatus::failure; |
1110 | const CMICmnMIValueConst miValueConst3( vFnName ); |
1111 | const CMICmnMIValueResult miValueResult3( "func", miValueConst3 ); |
1112 | if( !vwrMiValueTuple.Add( miValueResult3 ) ) |
1113 | return MIstatus::failure; |
1114 | const CMICmnMIValueConst miValueConst4( vArgInfo, true ); |
1115 | const CMICmnMIValueResult miValueResult4( "args", miValueConst4 ); |
1116 | if( !vwrMiValueTuple.Add( miValueResult4 ) ) |
1117 | return MIstatus::failure; |
1118 | const CMICmnMIValueConst miValueConst5( vFileName ); |
1119 | const CMICmnMIValueResult miValueResult5( "file", miValueConst5 ); |
1120 | if( !vwrMiValueTuple.Add( miValueResult5 ) ) |
1121 | return MIstatus::failure; |
1122 | const CMICmnMIValueConst miValueConst6( vPath ); |
1123 | const CMICmnMIValueResult miValueResult6( "fullname", miValueConst6 ); |
1124 | if( !vwrMiValueTuple.Add( miValueResult6 ) ) |
1125 | return MIstatus::failure; |
1126 | const CMIUtilString strLine( CMIUtilString::Format( "%d", vnLine ) ); |
1127 | const CMICmnMIValueConst miValueConst7( strLine ); |
1128 | const CMICmnMIValueResult miValueResult7( "line", miValueConst7 ); |
1129 | if( !vwrMiValueTuple.Add( miValueResult7 ) ) |
1130 | return MIstatus::failure; |
1131 | |
1132 | return MIstatus::success; |
1133 | } |
1134 | |
1135 | //++ ------------------------------------------------------------------------------------ |
1136 | // Details: Form MI partial response by appending more MI value type objects to the |
1137 | // tuple type object past in. |
1138 | // Type: Method. |
1139 | // Args: vrBrkPtInfo - (R) Break point information object. |
1140 | // vwrMIValueTuple - (W) MI value tuple object. |
1141 | // Return: MIstatus::success - Functional succeeded. |
1142 | // MIstatus::failure - Functional failed. |
1143 | // Throws: None. |
1144 | //-- |
1145 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple ) |
1146 | { |
1147 | const CMIUtilString strAddr( CMIUtilString::Format( "0x%08llx", vrBrkPtInfo.m_pc ) ); |
1148 | const CMICmnMIValueConst miValueConst2( strAddr ); |
1149 | const CMICmnMIValueResult miValueResult2( "addr", miValueConst2 ); |
1150 | if( !vwrMiValueTuple.Add( miValueResult2 ) ) |
1151 | return MIstatus::failure; |
1152 | const CMICmnMIValueConst miValueConst3( vrBrkPtInfo.m_fnName ); |
1153 | const CMICmnMIValueResult miValueResult3( "func", miValueConst3 ); |
1154 | if( !vwrMiValueTuple.Add( miValueResult3 ) ) |
1155 | return MIstatus::failure; |
1156 | const CMICmnMIValueConst miValueConst5( vrBrkPtInfo.m_fileName ); |
1157 | const CMICmnMIValueResult miValueResult5( "file", miValueConst5 ); |
1158 | if( !vwrMiValueTuple.Add( miValueResult5 ) ) |
1159 | return MIstatus::failure; |
1160 | const CMIUtilString strN5 = CMIUtilString::Format( "%s/%s", vrBrkPtInfo.m_path.c_str(), vrBrkPtInfo.m_fileName.c_str() ); |
1161 | const CMICmnMIValueConst miValueConst6( strN5 ); |
1162 | const CMICmnMIValueResult miValueResult6( "fullname", miValueConst6 ); |
1163 | if( !vwrMiValueTuple.Add( miValueResult6 ) ) |
1164 | return MIstatus::failure; |
1165 | const CMIUtilString strLine( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nLine ) ); |
1166 | const CMICmnMIValueConst miValueConst7( strLine ); |
1167 | const CMICmnMIValueResult miValueResult7( "line", miValueConst7 ); |
1168 | if( !vwrMiValueTuple.Add( miValueResult7 ) ) |
1169 | return MIstatus::failure; |
1170 | |
1171 | return MIstatus::success; |
1172 | } |
1173 | |
1174 | //++ ------------------------------------------------------------------------------------ |
1175 | // Details: Form MI partial response by appending more MI value type objects to the |
1176 | // tuple type object past in. |
1177 | // Type: Method. |
1178 | // Args: vrBrkPtInfo - (R) Break point information object. |
1179 | // vwrMIValueTuple - (W) MI value tuple object. |
1180 | // Return: MIstatus::success - Functional succeeded. |
1181 | // MIstatus::failure - Functional failed. |
1182 | // Throws: None. |
1183 | //-- |
1184 | bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple ) |
1185 | { |
1186 | // MI print "=breakpoint-modified,bkpt={number=\"%d\",type=\"breakpoint\",disp=\"%s\",enabled=\"%c\",addr=\"0x%08x\", func=\"%s\",file=\"%s\",fullname=\"%s/%s\",line=\"%d\",times=\"%d\",original-location=\"%s\"}" |
1187 | |
1188 | // "number=" |
1189 | const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_id ) ); |
1190 | const CMICmnMIValueResult miValueResult( "number", miValueConst ); |
1191 | CMICmnMIValueTuple miValueTuple( miValueResult ); |
1192 | // "type=" |
1193 | const CMICmnMIValueConst miValueConst2( vrBrkPtInfo.m_strType ); |
1194 | const CMICmnMIValueResult miValueResult2( "type", miValueConst2 ); |
1195 | bool bOk = miValueTuple.Add( miValueResult2 ); |
1196 | // "disp=" |
1197 | const CMICmnMIValueConst miValueConst3( vrBrkPtInfo.m_bDisp ? "del" : "keep" ); |
1198 | const CMICmnMIValueResult miValueResult3( "disp", miValueConst3 ); |
1199 | bOk = bOk && miValueTuple.Add( miValueResult3 ); |
1200 | // "enabled=" |
1201 | const CMICmnMIValueConst miValueConst4( vrBrkPtInfo.m_bEnabled ? "y" : "n" ); |
1202 | const CMICmnMIValueResult miValueResult4( "enabled", miValueConst4 ); |
1203 | bOk = bOk && miValueTuple.Add( miValueResult4 ); |
1204 | // "addr=" |
1205 | // "func=" |
1206 | // "file=" |
1207 | // "fullname=" |
1208 | // "line=" |
1209 | bOk = bOk && MIResponseFormBrkPtFrameInfo( vrBrkPtInfo, miValueTuple ); |
1210 | // "pending=" |
1211 | if( vrBrkPtInfo.m_bPending ) |
1212 | { |
1213 | const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strOrigLoc ); |
1214 | const CMICmnMIValueList miValueList( miValueConst ); |
1215 | const CMICmnMIValueResult miValueResult( "pending", miValueList ); |
1216 | bOk = bOk && miValueTuple.Add( miValueResult ); |
1217 | } |
1218 | if( vrBrkPtInfo.m_bHaveArgOptionThreadGrp ) |
1219 | { |
1220 | const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strOptThrdGrp ); |
1221 | const CMICmnMIValueList miValueList( miValueConst ); |
1222 | const CMICmnMIValueResult miValueResult( "thread-groups", miValueList ); |
1223 | bOk = bOk && miValueTuple.Add( miValueResult ); |
1224 | } |
1225 | // "times=" |
1226 | const CMICmnMIValueConst miValueConstB( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nTimes ) ); |
1227 | const CMICmnMIValueResult miValueResultB( "times", miValueConstB ); |
1228 | bOk = bOk && miValueTuple.Add( miValueResultB ); |
1229 | // "thread=" |
1230 | if( vrBrkPtInfo.m_bBrkPtThreadId ) |
1231 | { |
1232 | const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nBrkPtThreadId ) ); |
1233 | const CMICmnMIValueResult miValueResult( "thread", miValueConst ); |
1234 | bOk = bOk && miValueTuple.Add( miValueResult ); |
1235 | } |
1236 | // "cond=" |
1237 | if( vrBrkPtInfo.m_bCondition ) |
1238 | { |
1239 | const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strCondition ); |
1240 | const CMICmnMIValueResult miValueResult( "cond", miValueConst ); |
1241 | bOk = bOk && miValueTuple.Add( miValueResult ); |
1242 | } |
1243 | // "ignore=" |
1244 | if( vrBrkPtInfo.m_nIgnore != 0 ) |
1245 | { |
1246 | const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nIgnore ) ); |
1247 | const CMICmnMIValueResult miValueResult( "ignore", miValueConst ); |
1248 | bOk = bOk && miValueTuple.Add( miValueResult ); |
1249 | } |
1250 | // "original-location=" |
1251 | const CMICmnMIValueConst miValueConstC( vrBrkPtInfo.m_strOrigLoc ); |
1252 | const CMICmnMIValueResult miValueResultC( "original-location", miValueConstC ); |
1253 | bOk = bOk && miValueTuple.Add( miValueResultC ); |
Value stored to 'bOk' is never read | |
1254 | |
1255 | vwrMiValueTuple = miValueTuple; |
1256 | |
1257 | return MIstatus::success; |
1258 | } |
1259 | |
1260 | //++ ------------------------------------------------------------------------------------ |
1261 | // Details: Retrieve breakpoint information and write into the given breakpoint information |
1262 | // object. Note not all possible information is retrieved and so the information |
1263 | // object may need to be filled in with more information after calling this |
1264 | // function. Mainly breakpoint location information of information that is |
1265 | // unlikely to change. |
1266 | // Type: Method. |
1267 | // Args: vBrkPt - (R) LLDB break point object. |
1268 | // vrBrkPtInfo - (W) Break point information object. |
1269 | // Return: MIstatus::success - Functional succeeded. |
1270 | // MIstatus::failure - Functional failed. |
1271 | // Throws: None. |
1272 | //-- |
1273 | bool CMICmnLLDBDebugSessionInfo::GetBrkPtInfo( const lldb::SBBreakpoint & vBrkPt, SBrkPtInfo & vrwBrkPtInfo ) const |
1274 | { |
1275 | lldb::SBBreakpoint & rBrkPt = const_cast< lldb::SBBreakpoint & >( vBrkPt ); |
1276 | lldb::SBBreakpointLocation brkPtLoc = rBrkPt.GetLocationAtIndex( 0 ); |
1277 | lldb::SBAddress brkPtAddr = brkPtLoc.GetAddress(); |
1278 | lldb::SBSymbolContext symbolCntxt = brkPtAddr.GetSymbolContext( lldb::eSymbolContextEverything ); |
1279 | const MIchar * pUnkwn = "??"; |
1280 | lldb::SBModule rModule = symbolCntxt.GetModule(); |
1281 | const MIchar * pModule = rModule.IsValid() ? rModule.GetFileSpec().GetFilename() : pUnkwn; MIunused( pModule )(void) pModule;; |
1282 | const MIchar * pFile = pUnkwn; |
1283 | const MIchar * pFn = pUnkwn; |
1284 | const MIchar * pFilePath = pUnkwn; |
1285 | size_t nLine = 0; |
1286 | const size_t nAddr = brkPtAddr.GetLoadAddress( m_lldbTarget ); |
1287 | |
1288 | lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit(); |
1289 | if( rCmplUnit.IsValid() ) |
1290 | { |
1291 | lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec(); |
1292 | pFile = rFileSpec.GetFilename(); |
1293 | pFilePath = rFileSpec.GetDirectory(); |
1294 | lldb::SBFunction rFn = symbolCntxt.GetFunction(); |
1295 | if( rFn.IsValid() ) |
1296 | pFn = rFn.GetName(); |
1297 | lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry(); |
1298 | if( rLnEntry.GetLine() > 0 ) |
1299 | nLine = rLnEntry.GetLine(); |
1300 | } |
1301 | |
1302 | vrwBrkPtInfo.m_id = vBrkPt.GetID(); |
1303 | vrwBrkPtInfo.m_strType = "breakpoint"; |
1304 | vrwBrkPtInfo.m_pc = nAddr; |
1305 | vrwBrkPtInfo.m_fnName = pFn; |
1306 | vrwBrkPtInfo.m_fileName = pFile; |
1307 | vrwBrkPtInfo.m_path = pFilePath; |
1308 | vrwBrkPtInfo.m_nLine = nLine; |
1309 | vrwBrkPtInfo.m_nTimes = vBrkPt.GetHitCount(); |
1310 | |
1311 | return MIstatus::success; |
1312 | } |