File: | tools/lldb/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp |
Location: | line 1145, column 3 |
Description: | Value stored to 'bOk' is never read |
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 | //-- |
58 | CMICmnLLDBDebuggerHandleEvents::CMICmnLLDBDebuggerHandleEvents( void ) |
59 | { |
60 | } |
61 | |
62 | //++ ------------------------------------------------------------------------------------ |
63 | // Details: CMICmnLLDBDebuggerHandleEvents destructor. |
64 | // Type: Overridable. |
65 | // Args: None. |
66 | // Return: None. |
67 | // Throws: None. |
68 | //-- |
69 | CMICmnLLDBDebuggerHandleEvents::~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 | //-- |
82 | bool 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 | //-- |
102 | bool 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 | //-- |
126 | bool 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 | //-- |
160 | bool 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 | //-- |
206 | bool 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 | //-- |
272 | bool 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 | //-- |
293 | bool 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 | //-- |
360 | bool 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 | //-- |
457 | bool 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 | //-- |
504 | bool 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 | //-- |
537 | bool 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 | //-- |
556 | bool 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 | //-- |
608 | bool 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 | //-- |
693 | bool 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 | //-- |
737 | bool 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 | //-- |
799 | bool 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 | //-- |
909 | bool 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 | //-- |
955 | bool 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 | //-- |
981 | bool 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 | //-- |
1083 | bool 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 | //-- |
1161 | bool 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 | //-- |
1229 | bool 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 | //-- |
1251 | bool 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 | //-- |
1293 | bool 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 | //-- |
1327 | bool 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 | //-- |
1360 | bool 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 | //-- |
1388 | bool 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 | //-- |
1496 | bool 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 | //-- |
1510 | bool 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 | //-- |
1524 | bool 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 | //-- |
1538 | bool CMICmnLLDBDebuggerHandleEvents::TextToStderr( const CMIUtilString & vrTxt ) |
1539 | { |
1540 | return CMICmnStreamStderr::TextToStderr( vrTxt ); |
1541 | } |