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