1 //===-- MICmnLLDBDebugSessionInfo.cpp ---------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // File: MICmnLLDBDebugSessionInfo.cpp
13 // Overview: CMICmnLLDBDebugSessionInfo implementation.
15 // Environment: Compilers: Visual C++ 12.
16 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 // Libraries: See MIReadmetxt.
22 // Third party headers:
23 #include <lldb/API/SBThread.h>
25 #include <io.h> // For the ::_access()
27 #include <unistd.h> // For the ::access()
29 #include <lldb/API/SBBreakpointLocation.h>
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"
42 //++ ------------------------------------------------------------------------------------
43 // Details: CMICmnLLDBDebugSessionInfo constructor.
49 CMICmnLLDBDebugSessionInfo::CMICmnLLDBDebugSessionInfo( void )
50 : m_rLldbDebugger( CMICmnLLDBDebugger::Instance().GetTheDebugger() )
51 , m_rLlldbListener( CMICmnLLDBDebugger::Instance().GetTheListener() )
52 , m_nBrkPointCntMax( INT32_MAX )
53 , m_currentSelectedThread( LLDB_INVALID_THREAD_ID )
54 , m_constStrSharedDataKeyWkDir( "Working Directory" )
55 , m_constStrSharedDataSolibPath( "Solib Path" )
59 //++ ------------------------------------------------------------------------------------
60 // Details: CMICmnLLDBDebugSessionInfo destructor.
66 CMICmnLLDBDebugSessionInfo::~CMICmnLLDBDebugSessionInfo( void )
71 //++ ------------------------------------------------------------------------------------
72 // Details: Initialize resources for *this object.
75 // Return: MIstatus::success - Functionality succeeded.
76 // MIstatus::failure - Functionality failed.
79 bool CMICmnLLDBDebugSessionInfo::Initialize( void )
81 m_clientUsageRefCnt++;
84 return MIstatus::success;
86 m_currentSelectedThread = LLDB_INVALID_THREAD_ID;
87 CMICmnLLDBDebugSessionInfoVarObj::VarObjIdResetToZero();
89 m_bInitialized = MIstatus::success;
91 return m_bInitialized;
94 //++ ------------------------------------------------------------------------------------
95 // Details: Release resources for *this object.
98 // Return: MIstatus::success - Functionality succeeded.
99 // MIstatus::failure - Functionality failed.
102 bool CMICmnLLDBDebugSessionInfo::Shutdown( void )
104 if( --m_clientUsageRefCnt > 0 )
105 return MIstatus::success;
107 if( !m_bInitialized )
108 return MIstatus::success;
110 bool bOk = MIstatus::success;
111 CMIUtilString errMsg;
114 bOk = SharedDataDestroy();
117 errMsg = CMIUtilString::Format( MIRSRC( IDS_DBGSESSION_ERR_SHARED_DATA_RELEASE ) );
120 m_vecActiveThreadId.clear();
121 CMICmnLLDBDebugSessionInfoVarObj::VarObjClear();
123 m_bInitialized = false;
125 return MIstatus::success;
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.
136 // Return: MIstatus::success - Functional succeeded.
137 // MIstatus::failure - Functional failed.
140 bool CMICmnLLDBDebugSessionInfo::SharedDataDestroy( void )
142 m_mapIdToSessionData.Clear();
144 m_mapBrkPtIdToBrkPtInfo.clear();
146 return MIstatus::success;
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.
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.
159 bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfo( const MIuint vnBrkPtId, const SBrkPtInfo & vrBrkPtInfo )
161 MapPairBrkPtIdToBrkPtInfo_t pr( vnBrkPtId, vrBrkPtInfo );
162 m_mapBrkPtIdToBrkPtInfo.insert( pr );
164 return MIstatus::success;
167 //++ ------------------------------------------------------------------------------------
168 // Details: Retrieve information about a LLDB break point previous recorded either by
169 // commands or LLDB event handling functions.
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.
177 bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoGet( const MIuint vnBrkPtId, SBrkPtInfo & vrwBrkPtInfo ) const
179 const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId );
180 if( it != m_mapBrkPtIdToBrkPtInfo.end() )
182 vrwBrkPtInfo = (*it).second;
183 return MIstatus::success;
186 return MIstatus::failure;
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.
193 // Args: vBrkPtId - (R) LLDB break point ID.
194 // Return: MIstatus::success - Functional succeeded.
195 // MIstatus::failure - Functional failed.
198 bool CMICmnLLDBDebugSessionInfo::RecordBrkPtInfoDelete( const MIuint vnBrkPtId )
200 const MapBrkPtIdToBrkPtInfo_t::const_iterator it = m_mapBrkPtIdToBrkPtInfo.find( vnBrkPtId );
201 if( it != m_mapBrkPtIdToBrkPtInfo.end() )
203 m_mapBrkPtIdToBrkPtInfo.erase( it );
204 return MIstatus::success;
207 return MIstatus::failure;
210 //++ ------------------------------------------------------------------------------------
211 // Details: Retrieve the specified thread's frame information.
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.
220 bool CMICmnLLDBDebugSessionInfo::GetThreadFrames( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMIUtilString & vwrThreadFrames )
222 lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx );
223 const uint32_t nFrames = thread.GetNumFrames();
226 // MI print "frame={}"
227 CMICmnMIValueTuple miValueTuple;
228 CMICmnMIValueResult miValueResult( "frame", miValueTuple );
229 vwrThreadFrames = miValueResult.GetString();
230 return MIstatus::success;
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++ )
237 lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel );
239 CMIUtilString fnName;
240 CMIUtilString fileName;
243 if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
244 return MIstatus::failure;
247 CMICmnMIValueList miValueList( true );
248 const MIuint maskVarTypes = 0x1000;
249 if( !MIResponseFormVariableInfo( frame, maskVarTypes, miValueList ) )
250 return MIstatus::failure;
252 const MIchar * pUnknown = "??";
253 if( fnName != pUnknown )
255 std::replace( fnName.begin(), fnName.end(), ')', ' ' );
256 std::replace( fnName.begin(), fnName.end(), '(', ' ' );
257 std::replace( fnName.begin(), fnName.end(), '\'', ' ' );
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;
268 const CMICmnMIValueResult miValueResult2( "frame", miValueTuple );
270 strListCommaSeperated += ",";
271 strListCommaSeperated += miValueResult2.GetString();
274 vwrThreadFrames = strListCommaSeperated;
276 return MIstatus::success;
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.
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.
290 bool CMICmnLLDBDebugSessionInfo::GetThreadFrames2( const SMICmdData & vCmdData, const MIuint vThreadIdx, CMIUtilString & vwrThreadFrames )
292 lldb::SBThread thread = m_lldbProcess.GetThreadByIndexID( vThreadIdx );
293 const uint32_t nFrames = thread.GetNumFrames();
296 // MI print "frame={}"
297 CMICmnMIValueTuple miValueTuple;
298 CMICmnMIValueResult miValueResult( "frame", miValueTuple );
299 vwrThreadFrames = miValueResult.GetString();
300 return MIstatus::success;
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++ )
307 lldb::SBFrame frame = thread.GetFrameAtIndex( nLevel );
309 CMIUtilString fnName;
310 CMIUtilString fileName;
313 if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
314 return MIstatus::failure;
317 CMICmnMIValueList miValueList( true );
318 const MIuint maskVarTypes = 0x1000;
319 if( !MIResponseFormVariableInfo2( frame, maskVarTypes, miValueList ) )
320 return MIstatus::failure;
322 const MIchar * pUnknown = "??";
323 if( fnName != pUnknown )
325 std::replace( fnName.begin(), fnName.end(), ')', ' ' );
326 std::replace( fnName.begin(), fnName.end(), '(', ' ' );
327 std::replace( fnName.begin(), fnName.end(), '\'', ' ' );
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;
338 const CMICmnMIValueResult miValueResult2( "frame", miValueTuple );
340 strListCommaSeperated += ",";
341 strListCommaSeperated += miValueResult2.GetString();
344 vwrThreadFrames = strListCommaSeperated;
346 return MIstatus::success;
349 //++ ------------------------------------------------------------------------------------
350 // Details: Return the resolved file's path for the given file.
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.
359 bool CMICmnLLDBDebugSessionInfo::ResolvePath( const SMICmdData & vCmdData, const CMIUtilString & vPath, CMIUtilString & vwrResolvedPath )
361 // ToDo: Verify this code as it does not work as vPath is always empty
363 CMIUtilString strResolvedPath;
364 if( !SharedDataRetrieve< CMIUtilString >( m_constStrSharedDataKeyWkDir, strResolvedPath ) )
366 vwrResolvedPath = "";
367 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_SHARED_DATA_NOT_FOUND ), vCmdData.strMiCmd.c_str(), m_constStrSharedDataKeyWkDir.c_str() ) );
368 return MIstatus::failure;
371 vwrResolvedPath = vPath;
373 return ResolvePath( strResolvedPath, vwrResolvedPath );
376 //++ ------------------------------------------------------------------------------------
377 // Details: Return the resolved file's path for the given file.
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.
385 bool CMICmnLLDBDebugSessionInfo::ResolvePath( const CMIUtilString & vstrUnknown, CMIUtilString & vwrResolvedPath )
387 if( vwrResolvedPath.size() < 1 )
389 vwrResolvedPath = vstrUnknown;
390 return MIstatus::success;
393 bool bOk = MIstatus::success;
395 CMIUtilString::VecString_t vecPathFolders;
396 const MIuint nSplits = vwrResolvedPath.Split( "/", vecPathFolders ); MIunused( nSplits );
397 MIuint nFoldersBack = 1; // 1 is just the file (last element of vector)
398 while( bOk && (vecPathFolders.size() >= nFoldersBack) )
400 CMIUtilString strTestPath;
401 MIuint nFoldersToAdd = nFoldersBack;
402 while( nFoldersToAdd > 0 )
405 strTestPath += vecPathFolders[ vecPathFolders.size() - nFoldersToAdd ];
408 bool bYesAccessible = false;
409 bOk = AccessPath( strTestPath, bYesAccessible );
412 vwrResolvedPath = strTestPath;
413 return MIstatus::success;
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.
425 //++ ------------------------------------------------------------------------------------
426 // Details: Determine the given file path exists or not.
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.
434 bool CMICmnLLDBDebugSessionInfo::AccessPath( const CMIUtilString & vPath, bool & vwbYesAccessible )
437 vwbYesAccessible = (::_access( vPath.c_str(), 0 ) == 0);
439 vwbYesAccessible = (::access( vPath.c_str(), 0 ) == 0);
442 return MIstatus::success;
445 //++ ------------------------------------------------------------------------------------
446 // Details: Form MI partial response by appending more MI value type objects to the
447 // tuple type object past in.
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.
456 bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple )
458 lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread );
460 CMIUtilString strFrames;
461 if( !GetThreadFrames( vCmdData, rThread.GetIndexID(), strFrames ) )
462 return MIstatus::failure;
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" );
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;
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;
483 strThread = CMIUtilString::Format( pThrdFmt, pThreadName );
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;
492 const CMICmnMIValueConst miValueConst3( strFrames, true );
493 if( !vwrMIValueTuple.Add( miValueConst3, false ) )
494 return MIstatus::failure;
497 const CMICmnMIValueConst miValueConst4( strState );
498 const CMICmnMIValueResult miValueResult4( "state", miValueConst4 );
499 if( !vwrMIValueTuple.Add( miValueResult4 ) )
500 return MIstatus::failure;
502 return MIstatus::success;
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.
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.
517 bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo3( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple )
519 lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread );
521 CMIUtilString strFrames;
522 if( !GetThreadFrames2( vCmdData, rThread.GetIndexID(), strFrames ) )
523 return MIstatus::failure;
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" );
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;
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;
544 strThread = CMIUtilString::Format( pThrdFmt, pThreadName );
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;
553 const CMICmnMIValueConst miValueConst3( strFrames, true );
554 if( !vwrMIValueTuple.Add( miValueConst3, false ) )
555 return MIstatus::failure;
558 const CMICmnMIValueConst miValueConst4( strState );
559 const CMICmnMIValueResult miValueResult4( "state", miValueConst4 );
560 if( !vwrMIValueTuple.Add( miValueResult4 ) )
561 return MIstatus::failure;
563 return MIstatus::success;
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.
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.
578 bool CMICmnLLDBDebugSessionInfo::MIResponseFormThreadInfo2( const SMICmdData & vCmdData, const lldb::SBThread & vrThread, CMICmnMIValueTuple & vwrMIValueTuple )
580 lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread );
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" );
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;
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;
601 strThread = CMIUtilString::Format( pThrdFmt, pThreadName );
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;
610 const CMICmnMIValueConst miValueConst4( strState );
611 const CMICmnMIValueResult miValueResult4( "state", miValueConst4 );
612 if( !vwrMIValueTuple.Add( miValueResult4 ) )
613 return MIstatus::failure;
615 return MIstatus::success;
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.
623 // Args: vrFrame - (R) LLDB thread object.
624 // vMaskVarTypes - (R) 0x1000 = arguments,
627 // 0x0001 = in scope only.
628 // vwrMIValueList - (W) MI value list object.
629 // Return: MIstatus::success - Functional succeeded.
630 // MIstatus::failure - Functional failed.
633 bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo2( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList )
635 bool bOk = MIstatus::success;
636 lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame );
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++ )
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 );
660 //++ ------------------------------------------------------------------------------------
661 // Details: Form MI partial response by appending more MI value type objects to the
662 // tuple type object past in.
664 // Args: vrFrame - (R) LLDB thread object.
665 // vMaskVarTypes - (R) 0x1000 = arguments,
668 // 0x0001 = in scope only.
669 // vwrMIValueList - (W) MI value list object.
670 // Return: MIstatus::success - Functional succeeded.
671 // MIstatus::failure - Functional failed.
674 bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList )
676 bool bOk = MIstatus::success;
677 lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame );
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++ )
689 lldb::SBValue value = listArg.GetValueAtIndex( i );
690 bOk = GetVariableInfo( nMaxRecusiveDepth, value, false, vwrMiValueList, nCurrentRecursiveDepth );
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.
702 // Args: vrFrame - (R) LLDB thread object.
703 // vMaskVarTypes - (R) 0x1000 = arguments,
706 // 0x0001 = in scope only.
707 // vwrMIValueList - (W) MI value list object.
708 // Return: MIstatus::success - Functional succeeded.
709 // MIstatus::failure - Functional failed.
712 bool CMICmnLLDBDebugSessionInfo::MIResponseFormVariableInfo3( const lldb::SBFrame & vrFrame, const MIuint vMaskVarTypes, CMICmnMIValueList & vwrMiValueList )
714 bool bOk = MIstatus::success;
715 lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame );
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++ )
727 lldb::SBValue value = listArg.GetValueAtIndex( i );
728 bOk = GetVariableInfo2( nMaxRecusiveDepth, value, false, vwrMiValueList, nCurrentRecursiveDepth );
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.
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.
749 bool CMICmnLLDBDebugSessionInfo::GetVariableInfo( const MIuint vnMaxDepth, const lldb::SBValue & vrValue, const bool vbIsChildValue, CMICmnMIValueList & vwrMiValueList, MIuint & vrwnDepth )
751 // *** Update GetVariableInfo2() with any code changes here ***
753 // Check recursive depth
754 if( vrwnDepth >= vnMaxDepth )
755 return MIstatus::success;
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 );
762 const bool bIsPointerType = rValue.GetType().IsPointerType();
763 const MIuint nChildren = rValue.GetNumChildren();
768 if( utilValue.IsCharType() )
770 // For char types and try to form text string
771 const CMICmnMIValueConst miValueConst( utilValue.GetValue().c_str(), true );
772 miValueTuple.Add( miValueConst, true );
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 );
780 return vwrMiValueList.Add( CMICmnMIValueConst( miValueTuple.ExtractContentNoBrackets(), true ) );
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 );
794 else if( bIsPointerType && utilValue.IsChildCharType() )
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 );
801 const CMIUtilString & rText( utilValue.GetChildValueCString() );
804 const CMICmnMIValueConst miValueConst( utilValue.GetValue() );
805 const CMICmnMIValueResult miValueResult( "value", miValueConst );
806 miValueTuple.Add( miValueResult );
810 if( utilValue.IsValueUnknown() )
812 const CMICmnMIValueConst miValueConst( rText );
813 const CMICmnMIValueResult miValueResult( "value", miValueConst );
814 miValueTuple.Add( miValueResult );
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 );
826 return vwrMiValueList.Add( miValueTuple );
828 else if( bIsPointerType )
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 ) );
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 );
851 // Build parent child composite types
852 CMICmnMIValueList miValueList( true );
853 for( MIuint i = 0; bOk && (i < nChildren); i++ )
855 lldb::SBValue member = rValue.GetChildAtIndex( i );
856 bOk = GetVariableInfo( vnMaxDepth, member, true, miValueList, ++vrwnDepth );
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 );
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.
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.
883 bool CMICmnLLDBDebugSessionInfo::GetVariableInfo2( const MIuint vnMaxDepth, const lldb::SBValue & vrValue, const bool vbIsChildValue, CMICmnMIValueList & vwrMiValueList, MIuint & vrwnDepth )
885 // *** Update GetVariableInfo() with any code changes here ***
887 // Check recursive depth
888 if( vrwnDepth >= vnMaxDepth )
889 return MIstatus::success;
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 );
896 const MIuint nChildren = rValue.GetNumChildren();
899 if( vbIsChildValue && utilValue.IsCharType() )
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 ) );
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 );
918 else if( utilValue.IsChildCharType() )
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 );
925 const CMIUtilString & rText( utilValue.GetChildValueCString() );
928 const CMICmnMIValueConst miValueConst( utilValue.GetValue() );
929 const CMICmnMIValueResult miValueResult( "value", miValueConst );
930 miValueTuple.Add( miValueResult );
934 if( utilValue.IsValueUnknown() )
936 const CMICmnMIValueConst miValueConst( rText );
937 const CMICmnMIValueResult miValueResult( "value", miValueConst );
938 miValueTuple.Add( miValueResult );
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 );
950 return vwrMiValueList.Add( miValueTuple );
954 // Build parent child composite types
955 CMICmnMIValueList miValueList( true );
956 for( MIuint i = 0; bOk && (i < nChildren); i++ )
958 lldb::SBValue member = rValue.GetChildAtIndex( i );
959 bOk = GetVariableInfo( vnMaxDepth, member, true, miValueList, ++vrwnDepth );
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 );
971 //++ ------------------------------------------------------------------------------------
972 // Details: Form MI partial response by appending more MI value type objects to the
973 // tuple type object past in.
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.
981 bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::SBThread & vrThread, const MIuint vnLevel, CMICmnMIValueTuple & vwrMiValueTuple )
983 lldb::SBThread & rThread = const_cast< lldb::SBThread & >( vrThread );
985 lldb::SBFrame frame = rThread.GetFrameAtIndex( vnLevel );
987 CMIUtilString fnName;
988 CMIUtilString fileName;
991 if( !GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
992 return MIstatus::failure;
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;
1002 vwrMiValueTuple = miValueTuple;
1004 return MIstatus::success;
1007 //++ ------------------------------------------------------------------------------------
1008 // Details: Retrieve the frame information from LLDB frame object.
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.
1020 bool CMICmnLLDBDebugSessionInfo::GetFrameInfo( const lldb::SBFrame & vrFrame, lldb::addr_t & vwPc, CMIUtilString & vwFnName, CMIUtilString & vwFileName, CMIUtilString & vwPath, MIuint & vwnLine )
1022 lldb::SBFrame & rFrame = const_cast< lldb::SBFrame & >( vrFrame );
1024 static char pBuffer[ MAX_PATH ];
1025 const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath( &pBuffer[ 0 ], sizeof( pBuffer ) ); MIunused( nBytes );
1026 CMIUtilString strResolvedPath( &pBuffer[ 0 ] );
1027 const MIchar * pUnkwn = "??";
1028 if( !ResolvePath( pUnkwn, strResolvedPath ) )
1029 return MIstatus::failure;
1030 vwPath = strResolvedPath;
1032 vwPc = rFrame.GetPC();
1034 const MIchar * pFnName = rFrame.GetFunctionName();
1035 vwFnName = (pFnName != nullptr) ? pFnName : pUnkwn;
1037 const MIchar * pFileName = rFrame.GetLineEntry().GetFileSpec().GetFilename();
1038 vwFileName = (pFileName != nullptr) ? pFileName : pUnkwn;
1040 vwnLine = rFrame.GetLineEntry().GetLine();
1042 return MIstatus::success;
1045 //++ ------------------------------------------------------------------------------------
1046 // Details: Form MI partial response by appending more MI value type objects to the
1047 // tuple type object past in.
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.
1059 bool CMICmnLLDBDebugSessionInfo::MIResponseFormFrameInfo( const lldb::addr_t vPc, const CMIUtilString & vFnName, const CMIUtilString & vFileName, const CMIUtilString & vPath, const MIuint vnLine, CMICmnMIValueTuple & vwrMiValueTuple )
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;
1084 return MIstatus::success;
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.
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.
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 )
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;
1132 return MIstatus::success;
1135 //++ ------------------------------------------------------------------------------------
1136 // Details: Form MI partial response by appending more MI value type objects to the
1137 // tuple type object past in.
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.
1145 bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtFrameInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple )
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;
1171 return MIstatus::success;
1174 //++ ------------------------------------------------------------------------------------
1175 // Details: Form MI partial response by appending more MI value type objects to the
1176 // tuple type object past in.
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.
1184 bool CMICmnLLDBDebugSessionInfo::MIResponseFormBrkPtInfo( const SBrkPtInfo & vrBrkPtInfo, CMICmnMIValueTuple & vwrMiValueTuple )
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\"}"
1189 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_id ) );
1190 const CMICmnMIValueResult miValueResult( "number", miValueConst );
1191 CMICmnMIValueTuple miValueTuple( miValueResult );
1193 const CMICmnMIValueConst miValueConst2( vrBrkPtInfo.m_strType );
1194 const CMICmnMIValueResult miValueResult2( "type", miValueConst2 );
1195 bool bOk = miValueTuple.Add( miValueResult2 );
1197 const CMICmnMIValueConst miValueConst3( vrBrkPtInfo.m_bDisp ? "del" : "keep" );
1198 const CMICmnMIValueResult miValueResult3( "disp", miValueConst3 );
1199 bOk = bOk && miValueTuple.Add( miValueResult3 );
1201 const CMICmnMIValueConst miValueConst4( vrBrkPtInfo.m_bEnabled ? "y" : "n" );
1202 const CMICmnMIValueResult miValueResult4( "enabled", miValueConst4 );
1203 bOk = bOk && miValueTuple.Add( miValueResult4 );
1209 bOk = bOk && MIResponseFormBrkPtFrameInfo( vrBrkPtInfo, miValueTuple );
1211 if( vrBrkPtInfo.m_bPending )
1213 const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strOrigLoc );
1214 const CMICmnMIValueList miValueList( miValueConst );
1215 const CMICmnMIValueResult miValueResult( "pending", miValueList );
1216 bOk = bOk && miValueTuple.Add( miValueResult );
1218 if( vrBrkPtInfo.m_bHaveArgOptionThreadGrp )
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 );
1226 const CMICmnMIValueConst miValueConstB( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nTimes ) );
1227 const CMICmnMIValueResult miValueResultB( "times", miValueConstB );
1228 bOk = bOk && miValueTuple.Add( miValueResultB );
1230 if( vrBrkPtInfo.m_bBrkPtThreadId )
1232 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nBrkPtThreadId ) );
1233 const CMICmnMIValueResult miValueResult( "thread", miValueConst );
1234 bOk = bOk && miValueTuple.Add( miValueResult );
1237 if( vrBrkPtInfo.m_bCondition )
1239 const CMICmnMIValueConst miValueConst( vrBrkPtInfo.m_strCondition );
1240 const CMICmnMIValueResult miValueResult( "cond", miValueConst );
1241 bOk = bOk && miValueTuple.Add( miValueResult );
1244 if( vrBrkPtInfo.m_nIgnore != 0 )
1246 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%d", vrBrkPtInfo.m_nIgnore ) );
1247 const CMICmnMIValueResult miValueResult( "ignore", miValueConst );
1248 bOk = bOk && miValueTuple.Add( miValueResult );
1250 // "original-location="
1251 const CMICmnMIValueConst miValueConstC( vrBrkPtInfo.m_strOrigLoc );
1252 const CMICmnMIValueResult miValueResultC( "original-location", miValueConstC );
1253 bOk = bOk && miValueTuple.Add( miValueResultC );
1255 vwrMiValueTuple = miValueTuple;
1257 return MIstatus::success;
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.
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.
1273 bool CMICmnLLDBDebugSessionInfo::GetBrkPtInfo( const lldb::SBBreakpoint & vBrkPt, SBrkPtInfo & vrwBrkPtInfo ) const
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 );
1282 const MIchar * pFile = pUnkwn;
1283 const MIchar * pFn = pUnkwn;
1284 const MIchar * pFilePath = pUnkwn;
1286 const size_t nAddr = brkPtAddr.GetLoadAddress( m_lldbTarget );
1288 lldb::SBCompileUnit rCmplUnit = symbolCntxt.GetCompileUnit();
1289 if( rCmplUnit.IsValid() )
1291 lldb::SBFileSpec rFileSpec = rCmplUnit.GetFileSpec();
1292 pFile = rFileSpec.GetFilename();
1293 pFilePath = rFileSpec.GetDirectory();
1294 lldb::SBFunction rFn = symbolCntxt.GetFunction();
1296 pFn = rFn.GetName();
1297 lldb::SBLineEntry rLnEntry = symbolCntxt.GetLineEntry();
1298 if( rLnEntry.GetLine() > 0 )
1299 nLine = rLnEntry.GetLine();
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();
1311 return MIstatus::success;