1// LLDB test snippet that registers a listener with a process that hits 2// a breakpoint. 3 4#include <atomic> 5#include <iostream> 6#include <string> 7#include <thread> 8#include <vector> 9 10#include "lldb-headers.h" 11#include "common.h" 12 13using namespace lldb; 14using namespace std; 15 16void listener_func(); 17void check_listener(SBDebugger &dbg); 18 19// Listener thread and related variables 20atomic<bool> g_done; 21SBListener g_listener("test-listener"); 22thread g_listener_thread; 23 24void shutdown_listener() { 25 g_done.store(true); 26 if (g_listener_thread.joinable()) 27 g_listener_thread.join(); 28} 29 30void test(SBDebugger &dbg, std::vector<string> args) { 31 try { 32 g_done.store(false); 33 SBTarget target = dbg.CreateTarget(args.at(0).c_str()); 34 if (!target.IsValid()) throw Exception("invalid target"); 35 36 SBBreakpoint breakpoint = target.BreakpointCreateByName("next"); 37 if (!breakpoint.IsValid()) throw Exception("invalid breakpoint"); 38 39 std::unique_ptr<char> working_dir(get_working_dir()); 40 41 SBError error; 42 SBProcess process = target.Launch(g_listener, 43 0, 0, 0, 0, 0, 44 working_dir.get(), 45 0, 46 false, 47 error); 48 if (!error.Success()) 49 throw Exception("Error launching process."); 50 51 /* FIXME: the approach below deadlocks 52 SBProcess process = target.LaunchSimple(0, 0, working_dir.get()); 53 54 // get debugger listener (which is attached to process by default) 55 g_listener = dbg.GetListener(); 56 */ 57 58 // FIXME: because a listener is attached to the process at launch-time, 59 // registering the listener below results in two listeners being attached, 60 // which is not supported by LLDB. 61 // register listener 62 // process.GetBroadcaster().AddListener(g_listener, 63 // SBProcess::eBroadcastBitStateChanged); 64 65 // start listener thread 66 g_listener_thread = thread(listener_func); 67 check_listener(dbg); 68 69 } catch (Exception &e) { 70 shutdown_listener(); 71 throw e; 72 } 73 shutdown_listener(); 74} 75