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