1 #pragma once 2 #include "mutex.hpp" 3 #include <boost/filesystem.hpp> 4 #include <list> 5 #include <lldb/API/LLDB.h> 6 #include <thread> 7 #include <tuple> 8 9 namespace Debug { 10 class LLDB { 11 public: 12 class Frame { 13 public: 14 uint32_t index; 15 std::string module_filename; 16 boost::filesystem::path file_path; 17 std::string function_name; 18 int line_nr; 19 int line_index; 20 }; 21 class Variable { 22 public: 23 uint32_t thread_index_id; 24 uint32_t frame_index; 25 std::string name; 26 std::function<std::string()> get_value; 27 bool declaration_found; 28 boost::filesystem::path file_path; 29 int line_nr; 30 int line_index; 31 }; 32 33 private: 34 LLDB(); 35 void destroy_() EXCLUDES(mutex); 36 37 static bool initialized; 38 39 public: get()40 static LLDB &get() { 41 static LLDB instance; 42 return instance; 43 } 44 45 /// Must be called before application terminates (cannot be placed in destructor sadly) destroy()46 static void destroy() { 47 if(initialized) 48 get().destroy_(); 49 } 50 51 std::list<std::function<void(const lldb::SBProcess &)>> on_start; 52 /// The handlers are not run in the main loop. 53 std::list<std::function<void(int exit_status)>> on_exit; 54 /// The handlers are not run in the main loop. 55 std::list<std::function<void(const lldb::SBEvent &)>> on_event; 56 57 Mutex mutex; 58 59 void start(const std::string &command, const boost::filesystem::path &path = "", 60 const std::vector<std::pair<boost::filesystem::path, int>> &breakpoints = {}, 61 const std::vector<std::string> &startup_commands = {}, const std::string &remote_host = "") EXCLUDES(mutex); 62 void continue_debug() EXCLUDES(mutex); //can't use continue as function name 63 void stop() EXCLUDES(mutex); 64 void kill() EXCLUDES(mutex); 65 void step_over() EXCLUDES(mutex); 66 void step_into() EXCLUDES(mutex); 67 void step_out() EXCLUDES(mutex); 68 std::pair<std::string, std::string> run_command(const std::string &command) EXCLUDES(mutex); 69 std::vector<Frame> get_backtrace() EXCLUDES(mutex); 70 std::vector<Variable> get_variables() EXCLUDES(mutex); 71 void select_frame(uint32_t frame_index, uint32_t thread_index_id = 0) EXCLUDES(mutex); 72 73 /// Get value using variable name and location 74 std::string get_value(const std::string &variable_name, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) EXCLUDES(mutex); 75 /// Get value from expression 76 std::string get_value(const std::string &expression) EXCLUDES(mutex); 77 std::string get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) EXCLUDES(mutex); 78 79 bool is_invalid() EXCLUDES(mutex); 80 bool is_stopped() EXCLUDES(mutex); 81 bool is_running() EXCLUDES(mutex); 82 83 void add_breakpoint(const boost::filesystem::path &file_path, int line_nr) EXCLUDES(mutex); 84 void remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) EXCLUDES(mutex); 85 86 void write(const std::string &buffer) EXCLUDES(mutex); 87 88 private: 89 std::tuple<std::vector<std::string>, std::string, std::vector<std::string>> parse_run_arguments(const std::string &command); 90 91 std::unique_ptr<lldb::SBDebugger> debugger GUARDED_BY(mutex); 92 std::unique_ptr<lldb::SBListener> listener GUARDED_BY(mutex); 93 std::unique_ptr<lldb::SBProcess> process GUARDED_BY(mutex); 94 std::thread debug_thread; 95 96 lldb::StateType state GUARDED_BY(mutex); 97 98 size_t buffer_size; 99 }; 100 } // namespace Debug 101