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