1 //===-- SBListener.cpp ------------------------------------------*- C++ -*-===// 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 23 SBListener::SBListener() : m_opaque_sp(), m_unused_ptr(nullptr) { 24 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBListener); 25 } 26 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 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 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 48 SBListener::SBListener(const lldb::ListenerSP &listener_sp) 49 : m_opaque_sp(listener_sp), m_unused_ptr(nullptr) {} 50 51 SBListener::~SBListener() {} 52 53 bool SBListener::IsValid() const { 54 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBListener, IsValid); 55 return this->operator bool(); 56 } 57 SBListener::operator bool() const { 58 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBListener, operator bool); 59 60 return m_opaque_sp != nullptr; 61 } 62 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 315 lldb::ListenerSP SBListener::GetSP() { return m_opaque_sp; } 316 317 Listener *SBListener::operator->() const { return m_opaque_sp.get(); } 318 319 Listener *SBListener::get() const { return m_opaque_sp.get(); } 320 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 <> 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