• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- SBListener.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBListener.h"
10 #include "SBReproducerPrivate.h"
11 #include "lldb/API/SBBroadcaster.h"
12 #include "lldb/API/SBDebugger.h"
13 #include "lldb/API/SBEvent.h"
14 #include "lldb/API/SBStream.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Utility/Broadcaster.h"
17 #include "lldb/Utility/Listener.h"
18 #include "lldb/Utility/StreamString.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
SBListener()23 SBListener::SBListener() : m_opaque_sp(), m_unused_ptr(nullptr) {
24   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBListener);
25 }
26 
SBListener(const char * name)27 SBListener::SBListener(const char *name)
28     : m_opaque_sp(Listener::MakeListener(name)), m_unused_ptr(nullptr) {
29   LLDB_RECORD_CONSTRUCTOR(SBListener, (const char *), name);
30 }
31 
SBListener(const SBListener & rhs)32 SBListener::SBListener(const SBListener &rhs)
33     : m_opaque_sp(rhs.m_opaque_sp), m_unused_ptr(nullptr) {
34   LLDB_RECORD_CONSTRUCTOR(SBListener, (const lldb::SBListener &), rhs);
35 }
36 
operator =(const lldb::SBListener & rhs)37 const lldb::SBListener &SBListener::operator=(const lldb::SBListener &rhs) {
38   LLDB_RECORD_METHOD(const lldb::SBListener &,
39                      SBListener, operator=,(const lldb::SBListener &), rhs);
40 
41   if (this != &rhs) {
42     m_opaque_sp = rhs.m_opaque_sp;
43     m_unused_ptr = nullptr;
44   }
45   return LLDB_RECORD_RESULT(*this);
46 }
47 
SBListener(const lldb::ListenerSP & listener_sp)48 SBListener::SBListener(const lldb::ListenerSP &listener_sp)
49     : m_opaque_sp(listener_sp), m_unused_ptr(nullptr) {}
50 
51 SBListener::~SBListener() = default;
52 
IsValid() const53 bool SBListener::IsValid() const {
54   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBListener, IsValid);
55   return this->operator bool();
56 }
operator bool() const57 SBListener::operator bool() const {
58   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBListener, operator bool);
59 
60   return m_opaque_sp != nullptr;
61 }
62 
AddEvent(const SBEvent & event)63 void SBListener::AddEvent(const SBEvent &event) {
64   LLDB_RECORD_METHOD(void, SBListener, AddEvent, (const lldb::SBEvent &),
65                      event);
66 
67   EventSP &event_sp = event.GetSP();
68   if (event_sp)
69     m_opaque_sp->AddEvent(event_sp);
70 }
71 
Clear()72 void SBListener::Clear() {
73   LLDB_RECORD_METHOD_NO_ARGS(void, SBListener, Clear);
74 
75   if (m_opaque_sp)
76     m_opaque_sp->Clear();
77 }
78 
StartListeningForEventClass(SBDebugger & debugger,const char * broadcaster_class,uint32_t event_mask)79 uint32_t SBListener::StartListeningForEventClass(SBDebugger &debugger,
80                                                  const char *broadcaster_class,
81                                                  uint32_t event_mask) {
82   LLDB_RECORD_METHOD(uint32_t, SBListener, StartListeningForEventClass,
83                      (lldb::SBDebugger &, const char *, uint32_t), debugger,
84                      broadcaster_class, event_mask);
85 
86   if (m_opaque_sp) {
87     Debugger *lldb_debugger = debugger.get();
88     if (!lldb_debugger)
89       return 0;
90     BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
91     return m_opaque_sp->StartListeningForEventSpec(
92         lldb_debugger->GetBroadcasterManager(), event_spec);
93   } else
94     return 0;
95 }
96 
StopListeningForEventClass(SBDebugger & debugger,const char * broadcaster_class,uint32_t event_mask)97 bool SBListener::StopListeningForEventClass(SBDebugger &debugger,
98                                             const char *broadcaster_class,
99                                             uint32_t event_mask) {
100   LLDB_RECORD_METHOD(bool, SBListener, StopListeningForEventClass,
101                      (lldb::SBDebugger &, const char *, uint32_t), debugger,
102                      broadcaster_class, event_mask);
103 
104   if (m_opaque_sp) {
105     Debugger *lldb_debugger = debugger.get();
106     if (!lldb_debugger)
107       return false;
108     BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
109     return m_opaque_sp->StopListeningForEventSpec(
110         lldb_debugger->GetBroadcasterManager(), event_spec);
111   } else
112     return false;
113 }
114 
StartListeningForEvents(const SBBroadcaster & broadcaster,uint32_t event_mask)115 uint32_t SBListener::StartListeningForEvents(const SBBroadcaster &broadcaster,
116                                              uint32_t event_mask) {
117   LLDB_RECORD_METHOD(uint32_t, SBListener, StartListeningForEvents,
118                      (const lldb::SBBroadcaster &, uint32_t), broadcaster,
119                      event_mask);
120 
121   uint32_t acquired_event_mask = 0;
122   if (m_opaque_sp && broadcaster.IsValid()) {
123     acquired_event_mask =
124         m_opaque_sp->StartListeningForEvents(broadcaster.get(), event_mask);
125   }
126 
127   return acquired_event_mask;
128 }
129 
StopListeningForEvents(const SBBroadcaster & broadcaster,uint32_t event_mask)130 bool SBListener::StopListeningForEvents(const SBBroadcaster &broadcaster,
131                                         uint32_t event_mask) {
132   LLDB_RECORD_METHOD(bool, SBListener, StopListeningForEvents,
133                      (const lldb::SBBroadcaster &, uint32_t), broadcaster,
134                      event_mask);
135 
136   if (m_opaque_sp && broadcaster.IsValid()) {
137     return m_opaque_sp->StopListeningForEvents(broadcaster.get(), event_mask);
138   }
139   return false;
140 }
141 
WaitForEvent(uint32_t timeout_secs,SBEvent & event)142 bool SBListener::WaitForEvent(uint32_t timeout_secs, SBEvent &event) {
143   LLDB_RECORD_METHOD(bool, SBListener, WaitForEvent,
144                      (uint32_t, lldb::SBEvent &), timeout_secs, event);
145 
146   bool success = false;
147 
148   if (m_opaque_sp) {
149     Timeout<std::micro> timeout(llvm::None);
150     if (timeout_secs != UINT32_MAX) {
151       assert(timeout_secs != 0); // Take this out after all calls with timeout
152                                  // set to zero have been removed....
153       timeout = std::chrono::seconds(timeout_secs);
154     }
155     EventSP event_sp;
156     if (m_opaque_sp->GetEvent(event_sp, timeout)) {
157       event.reset(event_sp);
158       success = true;
159     }
160   }
161 
162   if (!success)
163     event.reset(nullptr);
164   return success;
165 }
166 
WaitForEventForBroadcaster(uint32_t num_seconds,const SBBroadcaster & broadcaster,SBEvent & event)167 bool SBListener::WaitForEventForBroadcaster(uint32_t num_seconds,
168                                             const SBBroadcaster &broadcaster,
169                                             SBEvent &event) {
170   LLDB_RECORD_METHOD(bool, SBListener, WaitForEventForBroadcaster,
171                      (uint32_t, const lldb::SBBroadcaster &, lldb::SBEvent &),
172                      num_seconds, broadcaster, event);
173 
174   if (m_opaque_sp && broadcaster.IsValid()) {
175     Timeout<std::micro> timeout(llvm::None);
176     if (num_seconds != UINT32_MAX)
177       timeout = std::chrono::seconds(num_seconds);
178     EventSP event_sp;
179     if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
180                                             timeout)) {
181       event.reset(event_sp);
182       return true;
183     }
184   }
185   event.reset(nullptr);
186   return false;
187 }
188 
WaitForEventForBroadcasterWithType(uint32_t num_seconds,const SBBroadcaster & broadcaster,uint32_t event_type_mask,SBEvent & event)189 bool SBListener::WaitForEventForBroadcasterWithType(
190     uint32_t num_seconds, const SBBroadcaster &broadcaster,
191     uint32_t event_type_mask, SBEvent &event) {
192   LLDB_RECORD_METHOD(
193       bool, SBListener, WaitForEventForBroadcasterWithType,
194       (uint32_t, const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
195       num_seconds, broadcaster, event_type_mask, event);
196 
197   if (m_opaque_sp && broadcaster.IsValid()) {
198     Timeout<std::micro> timeout(llvm::None);
199     if (num_seconds != UINT32_MAX)
200       timeout = std::chrono::seconds(num_seconds);
201     EventSP event_sp;
202     if (m_opaque_sp->GetEventForBroadcasterWithType(
203             broadcaster.get(), event_type_mask, event_sp, timeout)) {
204       event.reset(event_sp);
205       return true;
206     }
207   }
208   event.reset(nullptr);
209   return false;
210 }
211 
PeekAtNextEvent(SBEvent & event)212 bool SBListener::PeekAtNextEvent(SBEvent &event) {
213   LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEvent, (lldb::SBEvent &),
214                      event);
215 
216   if (m_opaque_sp) {
217     event.reset(m_opaque_sp->PeekAtNextEvent());
218     return event.IsValid();
219   }
220   event.reset(nullptr);
221   return false;
222 }
223 
PeekAtNextEventForBroadcaster(const SBBroadcaster & broadcaster,SBEvent & event)224 bool SBListener::PeekAtNextEventForBroadcaster(const SBBroadcaster &broadcaster,
225                                                SBEvent &event) {
226   LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEventForBroadcaster,
227                      (const lldb::SBBroadcaster &, lldb::SBEvent &),
228                      broadcaster, event);
229 
230   if (m_opaque_sp && broadcaster.IsValid()) {
231     event.reset(m_opaque_sp->PeekAtNextEventForBroadcaster(broadcaster.get()));
232     return event.IsValid();
233   }
234   event.reset(nullptr);
235   return false;
236 }
237 
PeekAtNextEventForBroadcasterWithType(const SBBroadcaster & broadcaster,uint32_t event_type_mask,SBEvent & event)238 bool SBListener::PeekAtNextEventForBroadcasterWithType(
239     const SBBroadcaster &broadcaster, uint32_t event_type_mask,
240     SBEvent &event) {
241   LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEventForBroadcasterWithType,
242                      (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
243                      broadcaster, event_type_mask, event);
244 
245   if (m_opaque_sp && broadcaster.IsValid()) {
246     event.reset(m_opaque_sp->PeekAtNextEventForBroadcasterWithType(
247         broadcaster.get(), event_type_mask));
248     return event.IsValid();
249   }
250   event.reset(nullptr);
251   return false;
252 }
253 
GetNextEvent(SBEvent & event)254 bool SBListener::GetNextEvent(SBEvent &event) {
255   LLDB_RECORD_METHOD(bool, SBListener, GetNextEvent, (lldb::SBEvent &), event);
256 
257   if (m_opaque_sp) {
258     EventSP event_sp;
259     if (m_opaque_sp->GetEvent(event_sp, std::chrono::seconds(0))) {
260       event.reset(event_sp);
261       return true;
262     }
263   }
264   event.reset(nullptr);
265   return false;
266 }
267 
GetNextEventForBroadcaster(const SBBroadcaster & broadcaster,SBEvent & event)268 bool SBListener::GetNextEventForBroadcaster(const SBBroadcaster &broadcaster,
269                                             SBEvent &event) {
270   LLDB_RECORD_METHOD(bool, SBListener, GetNextEventForBroadcaster,
271                      (const lldb::SBBroadcaster &, lldb::SBEvent &),
272                      broadcaster, event);
273 
274   if (m_opaque_sp && broadcaster.IsValid()) {
275     EventSP event_sp;
276     if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
277                                             std::chrono::seconds(0))) {
278       event.reset(event_sp);
279       return true;
280     }
281   }
282   event.reset(nullptr);
283   return false;
284 }
285 
GetNextEventForBroadcasterWithType(const SBBroadcaster & broadcaster,uint32_t event_type_mask,SBEvent & event)286 bool SBListener::GetNextEventForBroadcasterWithType(
287     const SBBroadcaster &broadcaster, uint32_t event_type_mask,
288     SBEvent &event) {
289   LLDB_RECORD_METHOD(bool, SBListener, GetNextEventForBroadcasterWithType,
290                      (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
291                      broadcaster, event_type_mask, event);
292 
293   if (m_opaque_sp && broadcaster.IsValid()) {
294     EventSP event_sp;
295     if (m_opaque_sp->GetEventForBroadcasterWithType(broadcaster.get(),
296                                                     event_type_mask, event_sp,
297                                                     std::chrono::seconds(0))) {
298       event.reset(event_sp);
299       return true;
300     }
301   }
302   event.reset(nullptr);
303   return false;
304 }
305 
HandleBroadcastEvent(const SBEvent & event)306 bool SBListener::HandleBroadcastEvent(const SBEvent &event) {
307   LLDB_RECORD_METHOD(bool, SBListener, HandleBroadcastEvent,
308                      (const lldb::SBEvent &), event);
309 
310   if (m_opaque_sp)
311     return m_opaque_sp->HandleBroadcastEvent(event.GetSP());
312   return false;
313 }
314 
GetSP()315 lldb::ListenerSP SBListener::GetSP() { return m_opaque_sp; }
316 
operator ->() const317 Listener *SBListener::operator->() const { return m_opaque_sp.get(); }
318 
get() const319 Listener *SBListener::get() const { return m_opaque_sp.get(); }
320 
reset(ListenerSP listener_sp)321 void SBListener::reset(ListenerSP listener_sp) {
322   m_opaque_sp = listener_sp;
323   m_unused_ptr = nullptr;
324 }
325 
326 namespace lldb_private {
327 namespace repro {
328 
329 template <>
RegisterMethods(Registry & R)330 void RegisterMethods<SBListener>(Registry &R) {
331   LLDB_REGISTER_CONSTRUCTOR(SBListener, ());
332   LLDB_REGISTER_CONSTRUCTOR(SBListener, (const char *));
333   LLDB_REGISTER_CONSTRUCTOR(SBListener, (const lldb::SBListener &));
334   LLDB_REGISTER_METHOD(const lldb::SBListener &,
335                        SBListener, operator=,(const lldb::SBListener &));
336   LLDB_REGISTER_METHOD_CONST(bool, SBListener, IsValid, ());
337   LLDB_REGISTER_METHOD_CONST(bool, SBListener, operator bool, ());
338   LLDB_REGISTER_METHOD(void, SBListener, AddEvent, (const lldb::SBEvent &));
339   LLDB_REGISTER_METHOD(void, SBListener, Clear, ());
340   LLDB_REGISTER_METHOD(uint32_t, SBListener, StartListeningForEventClass,
341                        (lldb::SBDebugger &, const char *, uint32_t));
342   LLDB_REGISTER_METHOD(bool, SBListener, StopListeningForEventClass,
343                        (lldb::SBDebugger &, const char *, uint32_t));
344   LLDB_REGISTER_METHOD(uint32_t, SBListener, StartListeningForEvents,
345                        (const lldb::SBBroadcaster &, uint32_t));
346   LLDB_REGISTER_METHOD(bool, SBListener, StopListeningForEvents,
347                        (const lldb::SBBroadcaster &, uint32_t));
348   LLDB_REGISTER_METHOD(bool, SBListener, WaitForEvent,
349                        (uint32_t, lldb::SBEvent &));
350   LLDB_REGISTER_METHOD(
351       bool, SBListener, WaitForEventForBroadcaster,
352       (uint32_t, const lldb::SBBroadcaster &, lldb::SBEvent &));
353   LLDB_REGISTER_METHOD(
354       bool, SBListener, WaitForEventForBroadcasterWithType,
355       (uint32_t, const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
356   LLDB_REGISTER_METHOD(bool, SBListener, PeekAtNextEvent, (lldb::SBEvent &));
357   LLDB_REGISTER_METHOD(bool, SBListener, PeekAtNextEventForBroadcaster,
358                        (const lldb::SBBroadcaster &, lldb::SBEvent &));
359   LLDB_REGISTER_METHOD(
360       bool, SBListener, PeekAtNextEventForBroadcasterWithType,
361       (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
362   LLDB_REGISTER_METHOD(bool, SBListener, GetNextEvent, (lldb::SBEvent &));
363   LLDB_REGISTER_METHOD(bool, SBListener, GetNextEventForBroadcaster,
364                        (const lldb::SBBroadcaster &, lldb::SBEvent &));
365   LLDB_REGISTER_METHOD(
366       bool, SBListener, GetNextEventForBroadcasterWithType,
367       (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
368   LLDB_REGISTER_METHOD(bool, SBListener, HandleBroadcastEvent,
369                        (const lldb::SBEvent &));
370 }
371 
372 }
373 }
374