Bug Summary

File:tools/lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp
Location:line 1145, column 3
Description:Value stored to 'bOk' is never read

Annotated Source Code

1//===-- MICmnLLDBDebuggerHandleEvents.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: MICmnLLDBDebuggerHandleEvents.cpp
12//
13// Overview: CMICmnLLDBDebuggerHandleEvents 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/SBEvent.h>
24#include <lldb/API/SBProcess.h>
25#include <lldb/API/SBBreakpoint.h>
26#include <lldb/API/SBStream.h>
27#include <lldb/API/SBThread.h>
28#include <lldb/API/SBCommandInterpreter.h>
29#include <lldb/API/SBCommandReturnObject.h>
30#ifdef _WIN32
31 #include <io.h> // For the ::_access()
32#else
33 #include <unistd.h> // For the ::access()
34#endif // _WIN32
35#include <limits.h>
36
37// In-house headers:
38#include "MICmnLLDBDebuggerHandleEvents.h"
39#include "MICmnResources.h"
40#include "MICmnLog.h"
41#include "MICmnLLDBDebugSessionInfo.h"
42#include "MICmnMIResultRecord.h"
43#include "MICmnMIValueConst.h"
44#include "MICmnMIValueList.h"
45#include "MICmnMIOutOfBandRecord.h"
46#include "MICmnStreamStdout.h"
47#include "MICmnStreamStderr.h"
48#include "MIUtilDebug.h"
49#include "MIDriver.h"
50
51//++ ------------------------------------------------------------------------------------
52// Details: CMICmnLLDBDebuggerHandleEvents constructor.
53// Type: Method.
54// Args: None.
55// Return: None.
56// Throws: None.
57//--
58CMICmnLLDBDebuggerHandleEvents::CMICmnLLDBDebuggerHandleEvents( void )
59{
60}
61
62//++ ------------------------------------------------------------------------------------
63// Details: CMICmnLLDBDebuggerHandleEvents destructor.
64// Type: Overridable.
65// Args: None.
66// Return: None.
67// Throws: None.
68//--
69CMICmnLLDBDebuggerHandleEvents::~CMICmnLLDBDebuggerHandleEvents( void )
70{
71 Shutdown();
72}
73
74//++ ------------------------------------------------------------------------------------
75// Details: Initialize resources for *this broardcaster object.
76// Type: Method.
77// Args: None.
78// Return: MIstatus::success - Functionality succeeded.
79// MIstatus::failure - Functionality failed.
80// Throws: None.
81//--
82bool CMICmnLLDBDebuggerHandleEvents::Initialize( void )
83{
84 m_clientUsageRefCnt++;
85
86 if( m_bInitialized )
87 return MIstatus::success;
88
89 m_bInitialized = MIstatus::success;
90
91 return m_bInitialized;
92}
93
94//++ ------------------------------------------------------------------------------------
95// Details: Release resources for *this broardcaster object.
96// Type: Method.
97// Args: None.
98// Return: MIstatus::success - Functionality succeeded.
99// MIstatus::failure - Functionality failed.
100// Throws: None.
101//--
102bool CMICmnLLDBDebuggerHandleEvents::Shutdown( void )
103{
104 if( --m_clientUsageRefCnt > 0 )
105 return MIstatus::success;
106
107 if( !m_bInitialized )
108 return MIstatus::success;
109
110 m_bInitialized = false;
111
112 return MIstatus::success;
113}
114
115//++ ------------------------------------------------------------------------------------
116// Details: Interpret the event object to asscertain the action to take or information to
117// to form and put in a MI Out-of-band record object which is given to stdout.
118// Type: Method.
119// Args: vEvent - (R) An LLDB broadcast event.
120// vrbHandledEvent - (W) True - event handled, false = not handled.
121// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
122// Return: MIstatus::success - Functionality succeeded.
123// MIstatus::failure - Functionality failed.
124// Throws: None.
125//--
126bool CMICmnLLDBDebuggerHandleEvents::HandleEvent( const lldb::SBEvent & vEvent, bool & vrbHandledEvent, bool & vrbExitAppEvent )
127{
128 bool bOk = MIstatus::success;
129 vrbHandledEvent = false;
130 vrbExitAppEvent = false;
131
132 if( lldb::SBProcess::EventIsProcessEvent( vEvent ) )
133 {
134 vrbHandledEvent = true;
135 bOk = HandleEventSBProcess( vEvent, vrbExitAppEvent );
136 }
137 else if( lldb::SBBreakpoint::EventIsBreakpointEvent( vEvent ) )
138 {
139 vrbHandledEvent = true;
140 bOk = HandleEventSBBreakPoint( vEvent );
141 }
142 else if( lldb::SBThread::EventIsThreadEvent( vEvent ) )
143 {
144 vrbHandledEvent = true;
145 bOk = HandleEventSBThread( vEvent );
146 }
147
148 return bOk;
149}
150
151//++ ------------------------------------------------------------------------------------
152// Details: Handle a LLDB SBProcess event.
153// Type: Method.
154// Args: vEvent - (R) An LLDB broadcast event.
155// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
156// Return: MIstatus::success - Functionality succeeded.
157// MIstatus::failure - Functionality failed.
158// Throws: None.
159//--
160bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBProcess( const lldb::SBEvent & vEvent, bool & vrbExitAppEvent )
161{
162 bool bOk = MIstatus::success;
163
164 const MIchar * pEventType = "";
165 const MIuint nEventType = vEvent.GetType();
166 switch( nEventType )
167 {
168 case lldb::SBProcess::eBroadcastBitInterrupt:
169 pEventType = "eBroadcastBitInterrupt";
170 break;
171 case lldb::SBProcess::eBroadcastBitProfileData:
172 pEventType = "eBroadcastBitProfileData";
173 break;
174 case lldb::SBProcess::eBroadcastBitStateChanged:
175 pEventType = "eBroadcastBitStateChanged";
176 bOk = HandleProcessEventBroadcastBitStateChanged( vEvent, vrbExitAppEvent );
177 break;
178 case lldb::SBProcess::eBroadcastBitSTDERR:
179 pEventType = "eBroadcastBitSTDERR";
180 bOk = GetProcessStderr();
181 break;
182 case lldb::SBProcess::eBroadcastBitSTDOUT:
183 pEventType = "eBroadcastBitSTDOUT";
184 bOk = GetProcessStdout();
185 break;
186 default:
187 {
188 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
, "SBProcess", (MIuint) nEventType ) );
189 SetErrorDescription( msg );
190 return MIstatus::failure;
191 }
192 }
193 m_pLog->WriteLog( CMIUtilString::Format( "##### An SB Process event occurred: %s", pEventType ) );
194
195 return bOk;
196}
197
198//++ ------------------------------------------------------------------------------------
199// Details: Handle a LLDB SBBreakpoint event.
200// Type: Method.
201// Args: vEvent - (R) An LLDB broadcast event.
202// Return: MIstatus::success - Functionality succeeded.
203// MIstatus::failure - Functionality failed.
204// Throws: None.
205//--
206bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakPoint( const lldb::SBEvent & vEvent )
207{
208 bool bOk = MIstatus::success;
209
210 const MIchar * pEventType ="";
211 const lldb::BreakpointEventType eEvent = lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent( vEvent );
212 switch( eEvent )
213 {
214 case lldb::eBreakpointEventTypeThreadChanged:
215 pEventType = "eBreakpointEventTypeThreadChanged";
216 break;
217 case lldb::eBreakpointEventTypeLocationsRemoved:
218 pEventType = "eBreakpointEventTypeLocationsRemoved";
219 break;
220 case lldb::eBreakpointEventTypeInvalidType:
221 pEventType = "eBreakpointEventTypeInvalidType";
222 break;
223 case lldb::eBreakpointEventTypeLocationsAdded:
224 pEventType = "eBreakpointEventTypeLocationsAdded";
225 bOk = HandleEventSBBreakpointLocationsAdded( vEvent );
226 break;
227 case lldb::eBreakpointEventTypeAdded:
228 pEventType = "eBreakpointEventTypeAdded";
229 bOk = HandleEventSBBreakpointAdded( vEvent );
230 break;
231 case lldb::eBreakpointEventTypeRemoved:
232 pEventType = "eBreakpointEventTypeRemoved";
233 bOk = HandleEventSBBreakpointCmn( vEvent );
234 break;
235 case lldb::eBreakpointEventTypeLocationsResolved:
236 pEventType = "eBreakpointEventTypeLocationsResolved";
237 break;
238 case lldb::eBreakpointEventTypeEnabled:
239 pEventType ="eBreakpointEventTypeEnabled";
240 bOk = HandleEventSBBreakpointCmn( vEvent );
241 break;
242 case lldb::eBreakpointEventTypeDisabled:
243 pEventType = "eBreakpointEventTypeDisabled";
244 bOk = HandleEventSBBreakpointCmn( vEvent );
245 break;
246 case lldb::eBreakpointEventTypeCommandChanged:
247 pEventType = "eBreakpointEventTypeCommandChanged";
248 bOk = HandleEventSBBreakpointCmn( vEvent );
249 break;
250 case lldb::eBreakpointEventTypeConditionChanged:
251 pEventType ="eBreakpointEventTypeConditionChanged";
252 bOk = HandleEventSBBreakpointCmn( vEvent );
253 break;
254 case lldb::eBreakpointEventTypeIgnoreChanged:
255 pEventType = "eBreakpointEventTypeIgnoreChanged";
256 bOk = HandleEventSBBreakpointCmn( vEvent );
257 break;
258 }
259 m_pLog->WriteLog( CMIUtilString::Format( "##### An SB Breakpoint event occurred: %s", pEventType ) );
260
261 return bOk;
262}
263
264//++ ------------------------------------------------------------------------------------
265// Details: Handle a LLDB SBBreakpoint event.
266// Type: Method.
267// Args: vEvent - (R) An LLDB broadcast event.
268// Return: MIstatus::success - Functionality succeeded.
269// MIstatus::failure - Functionality failed.
270// Throws: None.
271//--
272bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointLocationsAdded( const lldb::SBEvent & vEvent )
273{
274 const MIuint nLoc = lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent( vEvent );
275 if( nLoc == 0 )
276 return MIstatus::success;
277
278 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent( vEvent );
279 const CMIUtilString plural( (nLoc == 1) ? "" : "s" );
280 const CMIUtilString msg( CMIUtilString::Format( "%d location%s added to breakpoint %d", nLoc, plural.c_str(), brkPt.GetID() ) );
281
282 return TextToStdout( msg );
283}
284
285//++ ------------------------------------------------------------------------------------
286// Details: Handle a LLDB SBBreakpoint event.
287// Type: Method.
288// Args: vEvent - (R) An LLDB broadcast event.
289// Return: MIstatus::success - Functionality succeeded.
290// MIstatus::failure - Functionality failed.
291// Throws: None.
292//--
293bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointCmn( const lldb::SBEvent & vEvent )
294{
295 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent( vEvent );
296 if( !brkPt.IsValid() )
297 return MIstatus::success;
298
299 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
300 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
301 if( !rSessionInfo.GetBrkPtInfo( brkPt, sBrkPtInfo ) )
302 {
303 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET
).c_str()
, "HandleEventSBBreakpointCmn()", brkPt.GetID() ) );
304 return MIstatus::failure;
305 }
306
307 // CODETAG_LLDB_BREAKPOINT_CREATION
308 // This is in a worker thread
309 // Add more breakpoint information or overwrite existing information
310 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
311 if( !rSessionInfo.RecordBrkPtInfoGet( brkPt.GetID(), sBrkPtInfoRec ) )
312 {
313 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_BRKPT_NOTFOUND
).c_str()
, "HandleEventSBBreakpointCmn()", brkPt.GetID() ) );
314 return MIstatus::failure;
315 }
316 sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
317 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
318 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
319 sBrkPtInfo.m_strOptThrdGrp = "";
320 sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
321 sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
322 sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
323 sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
324 sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
325 sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
326 sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
327 sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
328
329 // 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\"}"
330 CMICmnMIValueTuple miValueTuple;
331 if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) )
332 {
333 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE
).c_str()
, "HandleEventSBBreakpointCmn()" ) );
334 return MIstatus::failure;
335 }
336
337 const CMICmnMIValueResult miValueResultC( "bkpt", miValueTuple );
338 const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResultC );
339 const bool bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord );
340
341 return bOk;
342}
343
344//++ ------------------------------------------------------------------------------------
345// Details: Handle a LLDB SBBreakpoint added event.
346// Add more breakpoint information or overwrite existing information.
347// Normally a break point session info objects exists by now when an MI command
348// was issued to insert a break so the retrieval would normally always succeed
349// however should a user type "b main" into a console then LLDB will create a
350// breakpoint directly, hence no MI command, hence no previous record of the
351// breakpoint so RecordBrkPtInfoGet() will fail. We still get the event though
352// so need to create a breakpoint info object here and send appropriate MI
353// response.
354// Type: Method.
355// Args: vEvent - (R) An LLDB broadcast event.
356// Return: MIstatus::success - Functionality succeeded.
357// MIstatus::failure - Functionality failed.
358// Throws: None.
359//--
360bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBBreakpointAdded( const lldb::SBEvent & vEvent )
361{
362 lldb::SBBreakpoint brkPt = lldb::SBBreakpoint::GetBreakpointFromEvent( vEvent );
363 if( !brkPt.IsValid() )
364 return MIstatus::success;
365
366 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
367 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfo;
368 if( !rSessionInfo.GetBrkPtInfo( brkPt, sBrkPtInfo ) )
369 {
370 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_GET
).c_str()
, "HandleEventSBBreakpointAdded()", brkPt.GetID() ) );
371 return MIstatus::failure;
372 }
373
374 // CODETAG_LLDB_BREAKPOINT_CREATION
375 // This is in a worker thread
376 CMICmnLLDBDebugSessionInfo::SBrkPtInfo sBrkPtInfoRec;
377 const bool bBrkPtExistAlready = rSessionInfo.RecordBrkPtInfoGet( brkPt.GetID(), sBrkPtInfoRec );
378 if( bBrkPtExistAlready )
379 {
380 // Update breakpoint information object
381 sBrkPtInfo.m_bDisp = sBrkPtInfoRec.m_bDisp;
382 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
383 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
384 sBrkPtInfo.m_strOptThrdGrp.clear();
385 sBrkPtInfo.m_nTimes = brkPt.GetHitCount();
386 sBrkPtInfo.m_strOrigLoc = sBrkPtInfoRec.m_strOrigLoc;
387 sBrkPtInfo.m_nIgnore = sBrkPtInfoRec.m_nIgnore;
388 sBrkPtInfo.m_bPending = sBrkPtInfoRec.m_bPending;
389 sBrkPtInfo.m_bCondition = sBrkPtInfoRec.m_bCondition;
390 sBrkPtInfo.m_strCondition = sBrkPtInfoRec.m_strCondition;
391 sBrkPtInfo.m_bBrkPtThreadId = sBrkPtInfoRec.m_bBrkPtThreadId;
392 sBrkPtInfo.m_nBrkPtThreadId = sBrkPtInfoRec.m_nBrkPtThreadId;
393 }
394 else
395 {
396 // Create a breakpoint information object
397 sBrkPtInfo.m_bDisp = brkPt.IsOneShot();
398 sBrkPtInfo.m_bEnabled = brkPt.IsEnabled();
399 sBrkPtInfo.m_bHaveArgOptionThreadGrp = false;
400 sBrkPtInfo.m_strOptThrdGrp.clear();
401 sBrkPtInfo.m_strOrigLoc = CMIUtilString::Format( "%s:%d", sBrkPtInfo.m_fileName.c_str(), sBrkPtInfo.m_nLine );
402 sBrkPtInfo.m_nIgnore = brkPt.GetIgnoreCount();
403 sBrkPtInfo.m_bPending = false;
404 const MIchar * pStrCondition = brkPt.GetCondition();
405 sBrkPtInfo.m_bCondition = (pStrCondition != nullptr) ? true : false;
406 sBrkPtInfo.m_strCondition = (pStrCondition != nullptr) ? pStrCondition : "??";
407 sBrkPtInfo.m_bBrkPtThreadId = (brkPt.GetThreadID() != 0) ? true : false;
408 sBrkPtInfo.m_nBrkPtThreadId = brkPt.GetThreadID();
409 }
410
411 CMICmnMIValueTuple miValueTuple;
412 if( !rSessionInfo.MIResponseFormBrkPtInfo( sBrkPtInfo, miValueTuple ) )
413 {
414 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE
).c_str()
, "HandleEventSBBreakpointAdded()" ) );
415 return MIstatus::failure;
416 }
417
418 bool bOk = MIstatus::success;
419 if( bBrkPtExistAlready )
420 {
421 // 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\"}"
422 const CMICmnMIValueResult miValueResult( "bkpt", miValueTuple );
423 const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointModified, miValueResult );
424 bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord );
425 }
426 else
427 {
428 // CODETAG_LLDB_BRKPT_ID_MAX
429 if( brkPt.GetID() > (lldb::break_id_t) rSessionInfo.m_nBrkPointCntMax )
430 {
431 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED )CMICmnResources::Instance().GetString( IDS_CMD_ERR_BRKPT_CNT_EXCEEDED
).c_str()
, "HandleEventSBBreakpointAdded()", rSessionInfo.m_nBrkPointCntMax, sBrkPtInfo.m_id ) );
432 return MIstatus::failure;
433 }
434 if( !rSessionInfo.RecordBrkPtInfo( brkPt.GetID(), sBrkPtInfo ) )
435 {
436 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_BRKPT_INFO_SET
).c_str()
, "HandleEventSBBreakpointAdded()", sBrkPtInfo.m_id ) );
437 return MIstatus::failure;
438 }
439
440 // MI print "=breakpoint-created,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\"}"
441 const CMICmnMIValueResult miValueResult( "bkpt", miValueTuple );
442 const CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_BreakPointCreated, miValueResult );
443 bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord );
444 }
445
446 return bOk;
447}
448
449//++ ------------------------------------------------------------------------------------
450// Details: Handle a LLDB SBThread event.
451// Type: Method.
452// Args: vEvent - (R) An LLDB broadcast event.
453// Return: MIstatus::success - Functionality succeeded.
454// MIstatus::failure - Functionality failed.
455// Throws: None.
456//--
457bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThread( const lldb::SBEvent & vEvent )
458{
459 if( !ChkForStateChanges() )
460 return MIstatus::failure;
461
462 bool bOk = MIstatus::success;
463 const MIchar * pEventType = "";
464 const MIuint nEventType = vEvent.GetType();
465 switch( nEventType )
466 {
467 case lldb::SBThread::eBroadcastBitStackChanged:
468 pEventType = "eBroadcastBitStackChanged";
469 bOk = HandleEventSBThreadBitStackChanged( vEvent );
470 break;
471 case lldb::SBThread::eBroadcastBitThreadSuspended:
472 pEventType = "eBroadcastBitThreadSuspended";
473 bOk = HandleEventSBThreadSuspended( vEvent );
474 break;
475 case lldb::SBThread::eBroadcastBitThreadResumed:
476 pEventType = "eBroadcastBitThreadResumed";
477 break;
478 case lldb::SBThread::eBroadcastBitSelectedFrameChanged:
479 pEventType = "eBroadcastBitSelectedFrameChanged";
480 break;
481 case lldb::SBThread::eBroadcastBitThreadSelected:
482 pEventType = "eBroadcastBitThreadSelected";
483 break;
484 default:
485 {
486 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
, "SBThread", (MIuint) nEventType ) );
487 SetErrorDescription( msg );
488 return MIstatus::failure;
489 }
490 }
491 m_pLog->WriteLog( CMIUtilString::Format( "##### An SBThread event occurred: %s", pEventType ) );
492
493 return bOk;
494}
495
496//++ ------------------------------------------------------------------------------------
497// Details: Handle a LLDB SBThread event.
498// Type: Method.
499// Args: vEvent - (R) An LLDB broadcast event.
500// Return: MIstatus::success - Functionality succeeded.
501// MIstatus::failure - Functionality failed.
502// Throws: None.
503//--
504bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadSuspended( const lldb::SBEvent & vEvent )
505{
506 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent( vEvent );
507 if( !thread.IsValid() )
508 return MIstatus::success;
509
510 const lldb::StopReason eStopReason = thread.GetStopReason();
511 if( eStopReason != lldb::eStopReasonSignal )
512 return MIstatus::success;
513
514 // MI print "@thread=%d,signal=%lld"
515 const MIuint64 nId = thread.GetStopReasonDataAtIndex( 0 );
516 const CMIUtilString strThread( CMIUtilString::Format( "%d", thread.GetThreadID() ) );
517 const CMICmnMIValueConst miValueConst( strThread );
518 const CMICmnMIValueResult miValueResult( "thread", miValueConst );
519 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Thread, miValueResult );
520 const CMIUtilString strSignal( CMIUtilString::Format( "%lld", nId ) );
521 const CMICmnMIValueConst miValueConst2( strSignal );
522 const CMICmnMIValueResult miValueResult2( "signal", miValueConst2 );
523 bool bOk = miOutOfBandRecord.Add( miValueResult2 );
524 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord );
525
526 return bOk;
527}
528
529//++ ------------------------------------------------------------------------------------
530// Details: Handle a LLDB SBThread event.
531// Type: Method.
532// Args: vEvent - (R) An LLDB broadcast event.
533// Return: MIstatus::success - Functionality succeeded.
534// MIstatus::failure - Functionality failed.
535// Throws: None.
536//--
537bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBThreadBitStackChanged( const lldb::SBEvent & vEvent )
538{
539 lldb::SBThread thread = lldb::SBThread::GetThreadFromEvent( vEvent );
540 if( !thread.IsValid() )
541 return MIstatus::success;
542
543 lldb::SBStream streamOut;
544 const bool bOk = thread.GetStatus( streamOut );
545 return bOk && TextToStdout( streamOut.GetData() );
546}
547
548//++ ------------------------------------------------------------------------------------
549// Details: Handle a LLDB SBCommandInterpreter event.
550// Type: Method.
551// Args: vEvent - (R) An LLDB command interpreter event.
552// Return: MIstatus::success - Functionality succeeded.
553// MIstatus::failure - Functionality failed.
554// Throws: None.
555//--
556bool CMICmnLLDBDebuggerHandleEvents::HandleEventSBCommandInterpreter( const lldb::SBEvent & vEvent )
557{
558 // This function is not used
559 // *** This function is under development
560
561 const MIchar * pEventType = "";
562 const MIuint nEventType = vEvent.GetType();
563 switch( nEventType )
564 {
565 case lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit:
566 pEventType ="eBroadcastBitThreadShouldExit";
567 // ToDo: IOR: Reminder to maybe handle this here
568 //const MIuint nEventType = event.GetType();
569 //if( nEventType & lldb::SBCommandInterpreter::eBroadcastBitThreadShouldExit )
570 //{
571 // m_pClientDriver->SetExitApplicationFlag();
572 // vrbYesExit = true;
573 // return MIstatus::success;
574 //} break;
575 case lldb::SBCommandInterpreter::eBroadcastBitResetPrompt:
576 pEventType = "eBroadcastBitResetPrompt";
577 break;
578 case lldb::SBCommandInterpreter::eBroadcastBitQuitCommandReceived:
579 pEventType = "eBroadcastBitQuitCommandReceived";
580 break;
581 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousOutputData:
582 pEventType = "eBroadcastBitAsynchronousOutputData";
583 break;
584 case lldb::SBCommandInterpreter::eBroadcastBitAsynchronousErrorData:
585 pEventType = "eBroadcastBitAsynchronousErrorData";
586 break;
587 default:
588 {
589 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
, "SBCommandInterpreter", (MIuint) nEventType ) );
590 SetErrorDescription( msg );
591 return MIstatus::failure;
592 }
593 }
594 m_pLog->WriteLog( CMIUtilString::Format( "##### An SBCommandInterpreter event occurred: %s", pEventType ) );
595
596 return MIstatus::success;
597}
598
599//++ ------------------------------------------------------------------------------------
600// Details: Handle SBProcess event eBroadcastBitStateChanged.
601// Type: Method.
602// Args: vEvent - (R) An LLDB event object.
603// vrbExitAppEvent - (W) True - Received LLDB exit app event, false = did not.
604// Return: MIstatus::success - Functionality succeeded.
605// MIstatus::failure - Functionality failed.
606// Throws: None.
607//--
608bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged( const lldb::SBEvent & vEvent, bool & vrbExitAppEvent )
609{
610 bool bOk = ChkForStateChanges();
611 bOk = bOk && GetProcessStdout();
612 bOk = bOk && GetProcessStderr();
613 if( !bOk )
614 return MIstatus::failure;
615
616 // Something changed in the process; get the event and report the process's current
617 // status and location
618 const lldb::StateType eEventState = lldb::SBProcess::GetStateFromEvent( vEvent );
619 if( eEventState == lldb::eStateInvalid )
620 return MIstatus::success;
621
622 lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent( vEvent );
623 if( !process.IsValid() )
624 {
625 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_PROCESS_INVALID
).c_str()
, "SBProcess", "HandleProcessEventBroadcastBitStateChanged()" ) );
626 SetErrorDescription( msg );
627 return MIstatus::failure;
628 }
629
630 bool bShouldBrk = true;
631 const MIchar * pEventType = "";
632 switch( eEventState )
633 {
634 case lldb::eStateUnloaded:
635 pEventType = "eStateUnloaded";
636 break;
637 case lldb::eStateConnected:
638 pEventType = "eStateConnected";
639 break;
640 case lldb::eStateAttaching:
641 pEventType = "eStateAttaching";
642 break;
643 case lldb::eStateLaunching:
644 pEventType ="eStateLaunching";
645 break;
646 case lldb::eStateStopped:
647 pEventType = "eStateStopped";
648 bOk = HandleProcessEventStateStopped( bShouldBrk );
649 if( bShouldBrk )
650 break;
651 case lldb::eStateCrashed:
652 case lldb::eStateSuspended:
653 pEventType = "eStateSuspended";
654 bOk = HandleProcessEventStateSuspended( vEvent );
655 break;
656 case lldb::eStateRunning:
657 pEventType = "eStateRunning";
658 bOk = HandleProcessEventStateRunning();
659 break;
660 case lldb::eStateStepping:
661 pEventType = "eStateStepping";
662 break;
663 case lldb::eStateDetached:
664 pEventType = "eStateDetached";
665 break;
666 case lldb::eStateExited:
667 pEventType = "eStateExited";
668 vrbExitAppEvent = true;
669 bOk = HandleProcessEventStateExited();
670 break;
671 default:
672 {
673 const CMIUtilString msg( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_UNKNOWN_EVENT
).c_str()
, "SBProcess BroadcastBitStateChanged", (MIuint) eEventState ) );
674 SetErrorDescription( msg );
675 return MIstatus::failure;
676 }
677 }
678
679 // ToDo: Remove when finished coding application
680 m_pLog->WriteLog( CMIUtilString::Format( "##### An SB Process event BroadcastBitStateChanged occurred: %s", pEventType ) );
681
682 return bOk;
683}
684
685//++ ------------------------------------------------------------------------------------
686// Details: Asynchronous event handler for LLDB Process state suspended.
687// Type: Method.
688// Args: vEvent - (R) An LLDB event object.
689// Return: MIstatus::success - Functionality succeeded.
690// MIstatus::failure - Functionality failed.
691// Throws: None.
692//--
693bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateSuspended( const lldb::SBEvent & vEvent )
694{
695 // Make sure the program hasn't been auto-restarted:
696 if( lldb::SBProcess::GetRestartedFromEvent( vEvent ) )
697 return MIstatus::success;
698
699 bool bOk = MIstatus::success;
700 lldb::SBDebugger & rDebugger = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger;
701 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
702 lldb::SBTarget target = rProcess.GetTarget();
703 if( rDebugger.GetSelectedTarget() == target )
704 {
705 if( !UpdateSelectedThread() )
706 return MIstatus::failure;
707
708 lldb::SBCommandReturnObject result;
709 const lldb::ReturnStatus status = rDebugger.GetCommandInterpreter().HandleCommand( "process status", result, false ); MIunused( status )(void) status;;
710 bOk = TextToStderr( result.GetError() );
711 bOk = bOk && TextToStdout( result.GetOutput() );
712 }
713 else
714 {
715 lldb::SBStream streamOut;
716 const MIuint nTargetIndex = rDebugger.GetIndexOfTarget( target );
717 if( nTargetIndex != UINT_MAX(2147483647 *2U +1U) )
718 streamOut.Printf( "Target %d: (", nTargetIndex );
719 else
720 streamOut.Printf( "Target <unknown index>: (" );
721 target.GetDescription( streamOut, lldb::eDescriptionLevelBrief );
722 streamOut.Printf( ") stopped.\n" );
723 bOk = TextToStdout( streamOut.GetData() );
724 }
725
726 return bOk;
727}
728
729//++ ------------------------------------------------------------------------------------
730// Details: Print to stdout MI formatted text to indicate process stopped.
731// Type: Method.
732// Args: vwrbShouldBrk - (W) True = Yes break, false = do not.
733// Return: MIstatus::success - Functionality succeeded.
734// MIstatus::failure - Functionality failed.
735// Throws: None.
736//--
737bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateStopped( bool & vwrbShouldBrk )
738{
739 if( !UpdateSelectedThread() )
740 return MIstatus::failure;
741
742 const MIchar * pEventType = "";
743 bool bOk = MIstatus::success;
744 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
745 const lldb::StopReason eStoppedReason = rProcess.GetSelectedThread().GetStopReason();
746 switch( eStoppedReason )
747 {
748 case lldb::eStopReasonInvalid:
749 pEventType = "eStopReasonInvalid";
750 vwrbShouldBrk = false;
751 break;
752 case lldb::eStopReasonNone:
753 pEventType = "eStopReasonNone";
754 break;
755 case lldb::eStopReasonTrace:
756 pEventType = "eStopReasonTrace";
757 bOk = HandleProcessEventStopReasonTrace();
758 break;
759 case lldb::eStopReasonBreakpoint:
760 pEventType = "eStopReasonBreakpoint";
761 bOk = HandleProcessEventStopReasonBreakpoint();
762 break;
763 case lldb::eStopReasonWatchpoint:
764 pEventType = "eStopReasonWatchpoint";
765 break;
766 case lldb::eStopReasonSignal:
767 pEventType = "eStopReasonSignal";
768 bOk = HandleProcessEventStopSignal( vwrbShouldBrk );
769 break;
770 case lldb::eStopReasonException:
771 pEventType ="eStopReasonException";
772 break;
773 case lldb::eStopReasonExec:
774 pEventType = "eStopReasonExec";
775 break;
776 case lldb::eStopReasonPlanComplete:
777 pEventType = "eStopReasonPlanComplete";
778 bOk = HandleProcessEventStopReasonTrace();
779 break;
780 case lldb::eStopReasonThreadExiting:
781 pEventType = "eStopReasonThreadExiting";
782 break;
783 }
784
785 // ToDo: Remove when finished coding application
786 m_pLog->WriteLog( CMIUtilString::Format( "##### An SB Process event stop state occurred: %s", pEventType ) );
787
788 return bOk;
789}
790
791//++ ------------------------------------------------------------------------------------
792// Details: Asynchronous event handler for LLDB Process stop signal.
793// Type: Method.
794// Args: vwrbShouldBrk - (W) True = Yes break, false = do not.
795// Return: MIstatus::success - Functionality succeeded.
796// MIstatus::failure - Functionality failed.
797// Throws: None.
798//--
799bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopSignal( bool & vwrbShouldBrk )
800{
801 bool bOk = MIstatus::success;
802
803 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
804 const MIuint64 nStopReason = rProcess.GetSelectedThread().GetStopReasonDataAtIndex( 0 );
805 switch( nStopReason )
806 {
807 case 2: // Terminal interrupt signal. SIGINT
808 {
809 // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGNINT\",signal-meaning=\"Interrupt\",frame={%s}"
810 const CMICmnMIValueConst miValueConst( "signal-received" );
811 const CMICmnMIValueResult miValueResult( "reason", miValueConst );
812 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
813 const CMICmnMIValueConst miValueConst2( "SIGINT" );
814 const CMICmnMIValueResult miValueResult2( "signal-name", miValueConst2 );
815 bOk = miOutOfBandRecord.Add( miValueResult2 );
816 const CMICmnMIValueConst miValueConst3( "Interrupt" );
817 const CMICmnMIValueResult miValueResult3( "signal-meaning", miValueConst3 );
818 bOk = bOk && miOutOfBandRecord.Add( miValueResult3 );
819 CMICmnMIValueTuple miValueTuple;
820 bOk = bOk && MiHelpGetCurrentThreadFrame( miValueTuple );
821 const CMICmnMIValueResult miValueResult5( "frame", miValueTuple );
822 bOk = bOk && miOutOfBandRecord.Add( miValueResult5 );
823 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord );
824 bOk = bOk && TextToStdout( "(gdb)" );
825 }
826 break;
827 case 11: // Invalid memory reference. SIGSEGV
828 {
829 // MI print "*stopped,reason=\"signal-received\",signal-name=\"SIGSEGV\",signal-meaning=\"Segmentation fault\",thread-id=\"%d\",frame={%s}"
830 const CMICmnMIValueConst miValueConst( "signal-received" );
831 const CMICmnMIValueResult miValueResult( "reason", miValueConst );
832 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
833 const CMICmnMIValueConst miValueConst2( "SIGSEGV" );
834 const CMICmnMIValueResult miValueResult2( "signal-name", miValueConst2 );
835 bOk = miOutOfBandRecord.Add( miValueResult2 );
836 const CMICmnMIValueConst miValueConst3( "Segmentation fault" );
837 const CMICmnMIValueResult miValueResult3( "signal-meaning", miValueConst3 );
838 bOk = bOk && miOutOfBandRecord.Add( miValueResult3 );
839 const CMIUtilString strThreadId( CMIUtilString::Format( "%d", rProcess.GetSelectedThread().GetIndexID() ) );
840 const CMICmnMIValueConst miValueConst4( strThreadId );
841 const CMICmnMIValueResult miValueResult4( "thread-id", miValueConst4 );
842 bOk = bOk && miOutOfBandRecord.Add( miValueResult4 );
843 CMICmnMIValueTuple miValueTuple;
844 bOk = bOk && MiHelpGetCurrentThreadFrame( miValueTuple );
845 const CMICmnMIValueResult miValueResult5( "frame", miValueTuple );
846 bOk = bOk && miOutOfBandRecord.Add( miValueResult5 );
847 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord );
848 // Note no "(gdb)" output here
849 }
850 break;
851 case 19:
852 if( rProcess.IsValid() )
853 rProcess.Continue();
854 break;
855 case 5: // Trace/breakpoint trap. SIGTRAP
856 {
857 lldb::SBThread thread = rProcess.GetSelectedThread();
858 const MIuint nFrames = thread.GetNumFrames();
859 if( nFrames > 0 )
860 {
861 lldb::SBFrame frame = thread.GetFrameAtIndex( 0 );
862 const char * pFnName = frame.GetFunctionName();
863 if( pFnName != nullptr )
864 {
865 const CMIUtilString fnName = CMIUtilString( pFnName );
866 static const CMIUtilString threadCloneFn = CMIUtilString( "__pthread_clone" );
867
868 if( CMIUtilString::Compare( threadCloneFn, fnName ) )
869 {
870 if( rProcess.IsValid() )
871 {
872 rProcess.Continue();
873 vwrbShouldBrk = true;
874 break;
875 }
876 }
877 }
878 }
879 }
880 default:
881 {
882 // MI print "*stopped,reason=\"signal-received\",signal=\"%lld\",stopped-threads=\"all\""
883 const CMICmnMIValueConst miValueConst( "signal-received" );
884 const CMICmnMIValueResult miValueResult( "reason", miValueConst );
885 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
886 const CMIUtilString strReason( CMIUtilString::Format( "%lld", nStopReason ) );
887 const CMICmnMIValueConst miValueConst2( strReason );
888 const CMICmnMIValueResult miValueResult2( "signal", miValueConst2 );
889 bOk = miOutOfBandRecord.Add( miValueResult2 );
890 const CMICmnMIValueConst miValueConst3( "all" );
891 const CMICmnMIValueResult miValueResult3( "stopped-threads", miValueConst3 );
892 bOk = bOk && miOutOfBandRecord.Add( miValueResult3 );
893 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord );
894 bOk = bOk && TextToStdout( "(gdb)" );
895 }
896 } // switch( nStopReason )
897
898 return bOk;
899}
900
901//++ ------------------------------------------------------------------------------------
902// Details: Form partial MI response in a MI value tuple object.
903// Type: Method.
904// Args: vwrMiValueTuple - (W) MI value tuple object.
905// Return: MIstatus::success - Functionality succeeded.
906// MIstatus::failure - Functionality failed.
907// Throws: None.
908//--
909bool CMICmnLLDBDebuggerHandleEvents::MiHelpGetCurrentThreadFrame( CMICmnMIValueTuple & vwrMiValueTuple )
910{
911 CMIUtilString strThreadFrame;
912 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
913 lldb::SBThread thread = rProcess.GetSelectedThread();
914 const MIuint nFrame = thread.GetNumFrames();
915 if( nFrame == 0 )
916 {
917 // MI print "addr=\"??\",func=\"??\",file=\"??\",fullname=\"??\",line=\"??\""
918 const CMICmnMIValueConst miValueConst( "??" );
919 const CMICmnMIValueResult miValueResult( "addr", miValueConst );
920 CMICmnMIValueTuple miValueTuple( miValueResult );
921 const CMICmnMIValueResult miValueResult2( "func", miValueConst );
922 miValueTuple.Add( miValueResult2 );
923 const CMICmnMIValueResult miValueResult4( "file", miValueConst );
924 miValueTuple.Add( miValueResult4 );
925 const CMICmnMIValueResult miValueResult5( "fullname", miValueConst );
926 miValueTuple.Add( miValueResult5 );
927 const CMICmnMIValueResult miValueResult6( "line", miValueConst );
928 miValueTuple.Add( miValueResult6 );
929
930 vwrMiValueTuple = miValueTuple;
931
932 return MIstatus::success;
933 }
934
935 CMICmnMIValueTuple miValueTuple;
936 if( !CMICmnLLDBDebugSessionInfo::Instance().MIResponseFormFrameInfo( thread, 0, miValueTuple ) )
937 {
938 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_FORM_MI_RESPONSE
).c_str()
, "MiHelpGetCurrentThreadFrame()" ) );
939 return MIstatus::failure;
940 }
941
942 vwrMiValueTuple = miValueTuple;
943
944 return MIstatus::success;
945}
946
947//++ ------------------------------------------------------------------------------------
948// Details: Asynchronous event handler for LLDB Process stop reason breakpoint.
949// Type: Method.
950// Args: None.
951// Return: MIstatus::success - Functionality succeeded.
952// MIstatus::failure - Functionality failed.
953// Throws: None.
954//--
955bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonBreakpoint( void )
956{
957 // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
958 if( !CMIDriver::Instance().SetDriverStateRunningNotDebugging() )
959 {
960 const CMIUtilString & rErrMsg( CMIDriver::Instance().GetErrorDescription() );
961 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_SETNEWDRIVERSTATE
).c_str()
, "HandleProcessEventStopReasonBreakpoint()", rErrMsg.c_str() ) );
962 return MIstatus::failure;
963 }
964
965 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
966 const MIuint64 brkPtId = rProcess.GetSelectedThread().GetStopReasonDataAtIndex( 0 );
967 lldb::SBBreakpoint brkPt = CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget.GetBreakpointAtIndex( (MIuint) brkPtId );
968
969 return MiStoppedAtBreakPoint( brkPtId, brkPt );
970}
971
972//++ ------------------------------------------------------------------------------------
973// Details: Form the MI Out-of-band response for stopped reason on hitting a break point.
974// Type: Method.
975// Args: vBrkPtId - (R) The LLDB break point's ID
976// vBrkPt - (R) THe LLDB break point object.
977// Return: MIstatus::success - Functionality succeeded.
978// MIstatus::failure - Functionality failed.
979// Throws: None.
980//--
981bool CMICmnLLDBDebuggerHandleEvents::MiStoppedAtBreakPoint( const MIuint64 vBrkPtId, const lldb::SBBreakpoint & vBrkPt )
982{
983 bool bOk = MIstatus::success;
984
985 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
986 lldb::SBThread thread = rProcess.GetSelectedThread();
987 const MIuint nFrame = thread.GetNumFrames();
988 if( nFrame == 0 )
989 {
990 // MI print "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={},thread-id=\"%d\",stopped-threads=\"all\""
991 const CMICmnMIValueConst miValueConst( "breakpoint-hit" );
992 const CMICmnMIValueResult miValueResult( "reason", miValueConst );
993 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
994 const CMICmnMIValueConst miValueConst2( "del" );
995 const CMICmnMIValueResult miValueResult2( "disp", miValueConst2 );
996 bOk = miOutOfBandRecord.Add( miValueResult2 );
997 const CMIUtilString strBkp( CMIUtilString::Format( "%d", vBrkPtId ) );
998 const CMICmnMIValueConst miValueConst3( strBkp );
999 CMICmnMIValueResult miValueResult3( "bkptno", miValueConst3 );
1000 bOk = bOk && miOutOfBandRecord.Add( miValueResult3 );
1001 const CMICmnMIValueConst miValueConst4( "{}" );
1002 const CMICmnMIValueResult miValueResult4( "frame", miValueConst4 );
1003 bOk = bOk && miOutOfBandRecord.Add( miValueResult4 );
1004 const CMIUtilString strThreadId( CMIUtilString::Format( "%d", vBrkPt.GetThreadIndex() ) );
1005 const CMICmnMIValueConst miValueConst5( strThreadId );
1006 const CMICmnMIValueResult miValueResult5( "thread-id", miValueConst5 );
1007 bOk = bOk && miOutOfBandRecord.Add( miValueResult5 );
1008 const CMICmnMIValueConst miValueConst6( "all" );
1009 const CMICmnMIValueResult miValueResult6( "stopped-threads", miValueConst6 );
1010 bOk = bOk && miOutOfBandRecord.Add( miValueResult6 );
1011 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord );
1012 bOk = bOk && TextToStdout( "(gdb)" );
1013 return bOk;
1014 }
1015
1016 CMICmnLLDBDebugSessionInfo & rSession = CMICmnLLDBDebugSessionInfo::Instance();
1017
1018 lldb::SBFrame frame = thread.GetFrameAtIndex( 0 );
1019 lldb::addr_t pc = 0;
1020 CMIUtilString fnName;
1021 CMIUtilString fileName;
1022 CMIUtilString path;
1023 MIuint nLine = 0;
1024 if( !rSession.GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
1025 {
1026 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET
).c_str()
, "MiStoppedAtBreakPoint()" ) );
1027 return MIstatus::failure;
1028 }
1029
1030 // MI print "*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"%d\",frame={addr=\"0x%08x\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1031 const CMICmnMIValueConst miValueConst( "breakpoint-hit" );
1032 const CMICmnMIValueResult miValueResult( "reason", miValueConst );
1033 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
1034 const CMICmnMIValueConst miValueConstA( "del" );
1035 const CMICmnMIValueResult miValueResultA( "disp", miValueConstA );
1036 bOk = miOutOfBandRecord.Add( miValueResultA );
1037 const CMIUtilString strBkp( CMIUtilString::Format( "%d", vBrkPtId ) );
1038 const CMICmnMIValueConst miValueConstB( strBkp );
1039 CMICmnMIValueResult miValueResultB( "bkptno", miValueConstB );
1040 bOk = bOk && miOutOfBandRecord.Add( miValueResultB );
1041
1042 // frame={addr=\"0x%08x\",func=\"%s\",args=[],file=\"%s\",fullname=\"%s\",line=\"%d\"}
1043 if( bOk )
1044 {
1045 CMICmnMIValueList miValueList( true );
1046 const MIuint maskVarTypes = 0x1000;
1047 bOk = rSession.MIResponseFormVariableInfo2( frame, maskVarTypes, miValueList );
1048
1049 CMICmnMIValueTuple miValueTuple;
1050 bOk = bOk && rSession.MIResponseFormFrameInfo2( pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple );
1051 const CMICmnMIValueResult miValueResult8( "frame", miValueTuple );
1052 bOk = bOk && miOutOfBandRecord.Add( miValueResult8 );
1053 }
1054
1055 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1056 if( bOk )
1057 {
1058 const CMIUtilString strThreadId( CMIUtilString::Format( "%d", thread.GetIndexID() ) );
1059 const CMICmnMIValueConst miValueConst8( strThreadId );
1060 const CMICmnMIValueResult miValueResult8( "thread-id", miValueConst8 );
1061 bOk = miOutOfBandRecord.Add( miValueResult8 );
1062 }
1063 if( bOk )
1064 {
1065 const CMICmnMIValueConst miValueConst9( "all" );
1066 const CMICmnMIValueResult miValueResult9( "stopped-threads", miValueConst9 );
1067 bOk = miOutOfBandRecord.Add( miValueResult9 );
1068 bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord );
1069 bOk = bOk && TextToStdout( "(gdb)" );
1070 }
1071
1072 return MIstatus::success;
1073}
1074
1075//++ ------------------------------------------------------------------------------------
1076// Details: Asynchronous event handler for LLDB Process stop reason trace.
1077// Type: Method.
1078// Args: None.
1079// Return: MIstatus::success - Functionality succeeded.
1080// MIstatus::failure - Functionality failed.
1081// Throws: None.
1082//--
1083bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStopReasonTrace( void )
1084{
1085 bool bOk = true;
1086 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
1087 lldb::SBThread thread = rProcess.GetSelectedThread();
1088 const MIuint nFrame = thread.GetNumFrames();
1089 if( nFrame == 0 )
1090 {
1091 // MI print "*stopped,reason=\"trace\",stopped-threads=\"all\""
1092 const CMICmnMIValueConst miValueConst( "trace" );
1093 const CMICmnMIValueResult miValueResult( "reason", miValueConst );
1094 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
1095 const CMICmnMIValueConst miValueConst2( "all" );
1096 const CMICmnMIValueResult miValueResult2( "stopped-threads", miValueConst2 );
1097 bOk = miOutOfBandRecord.Add( miValueResult2 );
1098 bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord );
1099 bOk = bOk && TextToStdout( "(gdb)" );
1100 return bOk;
1101 }
1102
1103 CMICmnLLDBDebugSessionInfo & rSession = CMICmnLLDBDebugSessionInfo::Instance();
1104
1105 // MI print "*stopped,reason=\"end-stepping-range\",frame={addr=\"0x%08x\",func=\"%s\",args=[\"%s\"],file=\"%s\",fullname=\"%s\",line=\"%d\"},thread-id=\"%d\",stopped-threads=\"all\""
1106 lldb::SBFrame frame = thread.GetFrameAtIndex( 0 );
1107 lldb::addr_t pc = 0;
1108 CMIUtilString fnName;
1109 CMIUtilString fileName;
1110 CMIUtilString path;
1111 MIuint nLine = 0;
1112 if( !rSession.GetFrameInfo( frame, pc, fnName, fileName, path, nLine ) )
1113 {
1114 SetErrorDescription( CMIUtilString::Format( MIRSRC( IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET )CMICmnResources::Instance().GetString( IDS_LLDBOUTOFBAND_ERR_FRAME_INFO_GET
).c_str()
, "HandleProcessEventStopReasonTrace()" ) );
1115 return MIstatus::failure;
1116 }
1117
1118 // Function args
1119 CMICmnMIValueList miValueList( true );
1120 const MIuint maskVarTypes = 0x1000;
1121 if( !rSession.MIResponseFormVariableInfo2( frame, maskVarTypes, miValueList ) )
1122 return MIstatus::failure;
1123 CMICmnMIValueTuple miValueTuple;
1124 if( !rSession.MIResponseFormFrameInfo2( pc, miValueList.GetString(), fnName, fileName, path, nLine, miValueTuple ) )
1125 return MIstatus::failure;
1126
1127 const CMICmnMIValueConst miValueConst( "end-stepping-range" );
1128 const CMICmnMIValueResult miValueResult( "reason", miValueConst );
1129 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult );
1130 const CMICmnMIValueResult miValueResult2( "frame", miValueTuple );
1131 bOk = miOutOfBandRecord.Add( miValueResult2 );
1132
1133 // Add to MI thread-id=\"%d\",stopped-threads=\"all\"
1134 if( bOk )
1135 {
1136 const CMIUtilString strThreadId( CMIUtilString::Format( "%d", thread.GetIndexID() ) );
1137 const CMICmnMIValueConst miValueConst8( strThreadId );
1138 const CMICmnMIValueResult miValueResult8( "thread-id", miValueConst8 );
1139 bOk = miOutOfBandRecord.Add( miValueResult8 );
1140 }
1141 if( bOk )
1142 {
1143 const CMICmnMIValueConst miValueConst9( "all" );
1144 const CMICmnMIValueResult miValueResult9( "stopped-threads", miValueConst9 );
1145 bOk = miOutOfBandRecord.Add( miValueResult9 );
Value stored to 'bOk' is never read
1146 bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord );
1147 bOk = bOk && TextToStdout( "(gdb)" );
1148 }
1149
1150 return bOk;
1151}
1152
1153//++ ------------------------------------------------------------------------------------
1154// Details: Asynchronous function update selected thread.
1155// Type: Method.
1156// Args: None.
1157// Return: MIstatus::success - Functionality succeeded.
1158// MIstatus::failure - Functionality failed.
1159// Throws: None.
1160//--
1161bool CMICmnLLDBDebuggerHandleEvents::UpdateSelectedThread( void )
1162{
1163 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger.GetSelectedTarget().GetProcess();
1164 if( !process.IsValid() )
1165 return MIstatus::success;
1166
1167 lldb::SBThread currentThread = process.GetSelectedThread();
1168 lldb::SBThread thread;
1169 const lldb::StopReason eCurrentThreadStoppedReason = currentThread.GetStopReason();
1170 if( !currentThread.IsValid() || (eCurrentThreadStoppedReason == lldb::eStopReasonInvalid) || (eCurrentThreadStoppedReason == lldb::eStopReasonNone) )
1171 {
1172 // Prefer a thread that has just completed its plan over another thread as current thread
1173 lldb::SBThread planThread;
1174 lldb::SBThread otherThread;
1175 const size_t nThread = process.GetNumThreads();
1176 for( MIuint i = 0; i < nThread; i++ )
1177 {
1178 // GetThreadAtIndex() uses a base 0 index
1179 // GetThreadByIndexID() uses a base 1 index
1180 thread = process.GetThreadAtIndex( i );
1181 const lldb::StopReason eThreadStopReason = thread.GetStopReason();
1182 switch( eThreadStopReason )
1183 {
1184 case lldb::eStopReasonTrace:
1185 case lldb::eStopReasonBreakpoint:
1186 case lldb::eStopReasonWatchpoint:
1187 case lldb::eStopReasonSignal:
1188 case lldb::eStopReasonException:
1189 if( !otherThread.IsValid() )
1190 otherThread = thread;
1191 break;
1192 case lldb::eStopReasonPlanComplete:
1193 if( !planThread.IsValid() )
1194 planThread = thread;
1195 break;
1196 case lldb::eStopReasonInvalid:
1197 case lldb::eStopReasonNone:
1198 default:
1199 break;
1200 }
1201 }
1202 if( planThread.IsValid() )
1203 process.SetSelectedThread( planThread );
1204 else if( otherThread.IsValid() )
1205 process.SetSelectedThread( otherThread );
1206 else
1207 {
1208 if( currentThread.IsValid() )
1209 thread = currentThread;
1210 else
1211 thread = process.GetThreadAtIndex( 0 );
1212
1213 if( thread.IsValid() )
1214 process.SetSelectedThread( thread );
1215 }
1216 } // if( !currentThread.IsValid() || (eCurrentThreadStoppedReason == lldb::eStopReasonInvalid) || (eCurrentThreadStoppedReason == lldb::eStopReasonNone) )
1217
1218 return MIstatus::success;
1219}
1220
1221//++ ------------------------------------------------------------------------------------
1222// Details: Print to stdout "*running,thread-id=\"all\"", "(gdb)".
1223// Type: Method.
1224// Args: None.
1225// Return: MIstatus::success - Functionality succeeded.
1226// MIstatus::failure - Functionality failed.
1227// Throws: None.
1228//--
1229bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateRunning( void )
1230{
1231 CMICmnMIValueConst miValueConst( "all" );
1232 CMICmnMIValueResult miValueResult( "thread-id", miValueConst );
1233 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_Running, miValueResult );
1234 bool bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord );
1235 bOk = bOk && TextToStdout( "(gdb)" );
1236
1237 return bOk;
1238}
1239
1240//++ ------------------------------------------------------------------------------------
1241// Details: Print to stdout "=thread-exited,id=\"%ld\",group-id=\"i1\"",
1242// "=thread-group-exited,id=\"i1\",exit-code=\"0\""),
1243// "*stopped,reason=\"exited-normally\"",
1244// "(gdb)"
1245// Type: Method.
1246// Args: None.
1247// Return: MIstatus::success - Functionality succeeded.
1248// MIstatus::failure - Functionality failed.
1249// Throws: None.
1250//--
1251bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventStateExited( void )
1252{
1253 const CMIUtilString strId( CMIUtilString::Format( "%ld", 1 ) );
1254 CMICmnMIValueConst miValueConst( strId );
1255 CMICmnMIValueResult miValueResult( "id", miValueConst );
1256 CMICmnMIOutOfBandRecord miOutOfBandRecord( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult );
1257 CMICmnMIValueConst miValueConst2( "i1" );
1258 CMICmnMIValueResult miValueResult2( "group-id", miValueConst2 );
1259 bool bOk = miOutOfBandRecord.Add( miValueResult2 );
1260 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord );
1261 if( bOk )
1262 {
1263 CMICmnMIValueConst miValueConst3( "i1" );
1264 CMICmnMIValueResult miValueResult3( "id", miValueConst3 );
1265 CMICmnMIOutOfBandRecord miOutOfBandRecord2( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadGroupExited, miValueResult3 );
1266 CMICmnMIValueConst miValueConst2( "0" );
1267 CMICmnMIValueResult miValueResult2( "exit-code", miValueConst2 );
1268 bOk = miOutOfBandRecord2.Add( miValueResult2 );
1269 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBandRecord2 );
1270 }
1271 if( bOk )
1272 {
1273 CMICmnMIValueConst miValueConst4( "exited-normally" );
1274 CMICmnMIValueResult miValueResult4( "reason", miValueConst4 );
1275 CMICmnMIOutOfBandRecord miOutOfBandRecord3( CMICmnMIOutOfBandRecord::eOutOfBand_Stopped, miValueResult4 );
1276 bOk = MiOutOfBandRecordToStdout( miOutOfBandRecord3 );
1277 }
1278 bOk = bOk && TextToStdout( "(gdb)" );
1279
1280 return bOk;
1281}
1282
1283//++ ------------------------------------------------------------------------------------
1284// Details: Drain all stdout so we don't see any output come after we print our prompts.
1285// The process has stuff waiting for stdout; get it and write it out to the
1286// appropriate place.
1287// Type: Method.
1288// Args: None.
1289// Return: MIstatus::success - Functionality succeeded.
1290// MIstatus::failure - Functionality failed.
1291// Throws: None.
1292//--
1293bool CMICmnLLDBDebuggerHandleEvents::GetProcessStdout( void )
1294{
1295 bool bOk = MIstatus::success;
1296
1297 char c;
1298 size_t nBytes = 0;
1299 CMIUtilString text;
1300 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger.GetSelectedTarget().GetProcess();
1301 while( process.GetSTDOUT( &c, 1 ) > 0 )
1302 {
1303 CMIUtilString str;
1304 if( ConvertPrintfCtrlCodeToString( c, str ) )
1305 text += str;
1306 nBytes++;
1307 }
1308 if( nBytes > 0 )
1309 {
1310 const CMIUtilString t( CMIUtilString::Format( "~\"%s\"", text.c_str() ) );
1311 bOk = TextToStdout( t );
1312 }
1313
1314 return bOk;
1315}
1316
1317//++ ------------------------------------------------------------------------------------
1318// Details: Drain all stderr so we don't see any output come after we print our prompts.
1319// The process has stuff waiting for stderr; get it and write it out to the
1320// appropriate place.
1321// Type: Method.
1322// Args: None.
1323// Return: MIstatus::success - Functionality succeeded.
1324// MIstatus::failure - Functionality failed.
1325// Throws: None.
1326//--
1327bool CMICmnLLDBDebuggerHandleEvents::GetProcessStderr( void )
1328{
1329 bool bOk = MIstatus::success;
1330
1331 char c;
1332 size_t nBytes = 0;
1333 CMIUtilString text;
1334 lldb::SBProcess process = CMICmnLLDBDebugSessionInfo::Instance().m_rLldbDebugger.GetSelectedTarget().GetProcess();
1335 while( process.GetSTDERR( &c, 1 ) > 0 )
1336 {
1337 CMIUtilString str;
1338 if( ConvertPrintfCtrlCodeToString( c, str ) )
1339 text += str;
1340 nBytes++;
1341 }
1342 if( nBytes > 0 )
1343 {
1344 const CMIUtilString t( CMIUtilString::Format( "~\"%s\"", text.c_str() ) );
1345 bOk = TextToStdout( t );
1346 }
1347
1348 return bOk;
1349}
1350
1351//++ ------------------------------------------------------------------------------------
1352// Details: Convert text stream control codes to text equivalent.
1353// Type: Method.
1354// Args: vCtrl - (R) The control code.
1355// vwrStrEquivalent - (W) The text equivalent.
1356// Return: MIstatus::success - Functionality succeeded.
1357// MIstatus::failure - Functionality failed.
1358// Throws: None.
1359//--
1360bool CMICmnLLDBDebuggerHandleEvents::ConvertPrintfCtrlCodeToString( const MIchar vCtrl, CMIUtilString & vwrStrEquivalent )
1361{
1362 switch( vCtrl )
1363 {
1364 case '\033': vwrStrEquivalent = "\\e"; break;
1365 case '\a': vwrStrEquivalent = "\\a"; break;
1366 case '\b': vwrStrEquivalent = "\\b"; break;
1367 case '\f': vwrStrEquivalent = "\\f"; break;
1368 case '\n': vwrStrEquivalent = "\\n"; break;
1369 case '\r': vwrStrEquivalent = "\\r"; break;
1370 case '\t': vwrStrEquivalent = "\\t"; break;
1371 case '\v': vwrStrEquivalent = "\\v"; break;
1372 default:
1373 vwrStrEquivalent = CMIUtilString::Format( "%c", vCtrl );
1374 break;
1375 }
1376
1377 return MIstatus::success;
1378}
1379
1380//++ ------------------------------------------------------------------------------------
1381// Details: Asynchronous event function check for state changes.
1382// Type: Method.
1383// Args: None.
1384// Return: MIstatus::success - Functionality succeeded.
1385// MIstatus::failure - Functionality failed.
1386// Throws: None.
1387//--
1388bool CMICmnLLDBDebuggerHandleEvents::ChkForStateChanges( void )
1389{
1390 lldb::SBProcess & rProcess = CMICmnLLDBDebugSessionInfo::Instance().m_lldbProcess;
1391 if( !rProcess.IsValid() )
1392 return MIstatus::success;
1393 lldb::SBTarget & rTarget = CMICmnLLDBDebugSessionInfo::Instance().m_lldbTarget;
1394 if( !rTarget.IsValid() )
1395 return MIstatus::success;
1396
1397 bool bOk = MIstatus::success;
1398
1399 // Check for created threads
1400 const MIuint nThread = rProcess.GetNumThreads();
1401 for( MIuint i = 0; i < nThread; i++ )
1402 {
1403 // GetThreadAtIndex() uses a base 0 index
1404 // GetThreadByIndexID() uses a base 1 index
1405 lldb::SBThread thread = rProcess.GetThreadAtIndex( i );
1406 if( !thread.IsValid() )
1407 continue;
1408
1409 CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::const_iterator it = CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.begin();
1410 bool bFound = false;
1411 while( it != CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.end() )
1412 {
1413 const MIuint nThreadId = *it;
1414 if( nThreadId == i )
1415 {
1416 bFound = true;
1417 break;
1418 }
1419
1420 // Next
1421 ++it;
1422 }
1423 if( !bFound )
1424 {
1425 CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.push_back( i );
1426
1427 // Form MI "=thread-created,id=\"%d\",group-id=\"i1\""
1428 const CMIUtilString strValue( CMIUtilString::Format( "%d", thread.GetIndexID() ) );
1429 const CMICmnMIValueConst miValueConst( strValue );
1430 const CMICmnMIValueResult miValueResult( "id", miValueConst );
1431 CMICmnMIOutOfBandRecord miOutOfBand( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadCreated, miValueResult );
1432 const CMICmnMIValueConst miValueConst2( "i1" );
1433 const CMICmnMIValueResult miValueResult2( "group-id", miValueConst2 );
1434 bOk = miOutOfBand.Add( miValueResult2 );
1435 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBand );
1436 if( !bOk )
1437 return MIstatus::failure;
1438 }
1439 }
1440
1441 lldb::SBThread currentThread = rProcess.GetSelectedThread();
1442 if( currentThread.IsValid() )
1443 {
1444 const MIuint threadId = currentThread.GetIndexID();
1445 if( CMICmnLLDBDebugSessionInfo::Instance().m_currentSelectedThread != threadId )
1446 {
1447 CMICmnLLDBDebugSessionInfo::Instance().m_currentSelectedThread = threadId;
1448
1449 // Form MI "=thread-selected,id=\"%d\""
1450 const CMIUtilString strValue( CMIUtilString::Format( "%d", currentThread.GetIndexID() ) );
1451 const CMICmnMIValueConst miValueConst( strValue );
1452 const CMICmnMIValueResult miValueResult( "id", miValueConst );
1453 CMICmnMIOutOfBandRecord miOutOfBand( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadSelected, miValueResult );
1454 if( !MiOutOfBandRecordToStdout( miOutOfBand ) )
1455 return MIstatus::failure;
1456 }
1457 }
1458
1459 // Check for invalid (removed) threads
1460 CMICmnLLDBDebugSessionInfo::VecActiveThreadId_t::const_iterator it = CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.begin();
1461 while( it != CMICmnLLDBDebugSessionInfo::Instance().m_vecActiveThreadId.end() )
1462 {
1463 const MIuint nThreadId = *it;
1464 lldb::SBThread thread = rProcess.GetThreadAtIndex( nThreadId );
1465 if( !thread.IsValid() )
1466 {
1467 // Form MI "=thread-exited,id=\"%ld\",group-id=\"i1\""
1468 const CMIUtilString strValue( CMIUtilString::Format( "%ld", thread.GetIndexID() ) );
1469 const CMICmnMIValueConst miValueConst( strValue );
1470 const CMICmnMIValueResult miValueResult( "id", miValueConst );
1471 CMICmnMIOutOfBandRecord miOutOfBand( CMICmnMIOutOfBandRecord::eOutOfBand_ThreadExited, miValueResult );
1472 const CMICmnMIValueConst miValueConst2( "i1" );
1473 const CMICmnMIValueResult miValueResult2( "group-id", miValueConst2 );
1474 bOk = miOutOfBand.Add( miValueResult2 );
1475 bOk = bOk && MiOutOfBandRecordToStdout( miOutOfBand );
1476 if( !bOk )
1477 return MIstatus::failure;
1478 }
1479
1480 // Next
1481 ++it;
1482 }
1483
1484 return TextToStdout( "(gdb)" );
1485}
1486
1487//++ ------------------------------------------------------------------------------------
1488// Details: Take a fully formed MI result record and send to the stdout stream.
1489// Also output to the MI Log file.
1490// Type: Method.
1491// Args: vrMiResultRecord - (R) MI result record object.
1492// Return: MIstatus::success - Functionality succeeded.
1493// MIstatus::failure - Functionality failed.
1494// Throws: None.
1495//--
1496bool CMICmnLLDBDebuggerHandleEvents::MiResultRecordToStdout( const CMICmnMIResultRecord & vrMiResultRecord )
1497{
1498 return TextToStdout( vrMiResultRecord.GetString() );
1499}
1500
1501//++ ------------------------------------------------------------------------------------
1502// Details: Take a fully formed MI Out-of-band record and send to the stdout stream.
1503// Also output to the MI Log file.
1504// Type: Method.
1505// Args: vrMiOutOfBandRecord - (R) MI Out-of-band record object.
1506// Return: MIstatus::success - Functionality succeeded.
1507// MIstatus::failure - Functionality failed.
1508// Throws: None.
1509//--
1510bool CMICmnLLDBDebuggerHandleEvents::MiOutOfBandRecordToStdout( const CMICmnMIOutOfBandRecord & vrMiOutOfBandRecord )
1511{
1512 return TextToStdout( vrMiOutOfBandRecord.GetString() );
1513}
1514
1515//++ ------------------------------------------------------------------------------------
1516// Details: Take a text data and send to the stdout stream. Also output to the MI Log
1517// file.
1518// Type: Method.
1519// Args: vrTxt - (R) Text.
1520// Return: MIstatus::success - Functionality succeeded.
1521// MIstatus::failure - Functionality failed.
1522// Throws: None.
1523//--
1524bool CMICmnLLDBDebuggerHandleEvents::TextToStdout( const CMIUtilString & vrTxt )
1525{
1526 return CMICmnStreamStdout::TextToStdout( vrTxt );
1527}
1528
1529//++ ------------------------------------------------------------------------------------
1530// Details: Take a text data and send to the stderr stream. Also output to the MI Log
1531// file.
1532// Type: Method.
1533// Args: vrTxt - (R) Text.
1534// Return: MIstatus::success - Functionality succeeded.
1535// MIstatus::failure - Functionality failed.
1536// Throws: None.
1537//--
1538bool CMICmnLLDBDebuggerHandleEvents::TextToStderr( const CMIUtilString & vrTxt )
1539{
1540 return CMICmnStreamStderr::TextToStderr( vrTxt );
1541}