diff --git a/src/debug.cc b/src/debug.cc index 7dacc30..df21394 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -17,7 +17,7 @@ void log(const char *msg, void *) { cout << "debugger log: " << msg << endl; } -Debug::Debug() { +Debug::Debug(): stopped(false) { lldb::SBDebugger::Initialize(); debugger=lldb::SBDebugger::Create(true, log, nullptr); @@ -36,7 +36,7 @@ void Debug::start(const boost::filesystem::path &project_path, const boost::file for(auto &breakpoint: breakpoints[project_path.string()]) { if(!(target.BreakpointCreateByLocation(breakpoint.first.c_str(), breakpoint.second)).IsValid()) { - cerr << "Error: Could not create breakpoint at: " << breakpoint.first << ":" << breakpoint.second << endl; //TODO: fix output to terminal instead + cerr << "Error: Could not create breakpoint at: " << breakpoint.first << ":" << breakpoint.second << endl; //TODO: output to terminal instead return; } else @@ -44,43 +44,62 @@ void Debug::start(const boost::filesystem::path &project_path, const boost::file } lldb::SBError error; - auto process = target.Launch(listener, nullptr, nullptr, nullptr, nullptr, nullptr, path.string().c_str(), lldb::eLaunchFlagNone, false, error); + process = std::unique_ptr(new lldb::SBProcess(target.Launch(listener, nullptr, nullptr, nullptr, nullptr, nullptr, path.string().c_str(), lldb::eLaunchFlagNone, false, error))); if(error.Fail()) { cerr << "Error (debug): " << error.GetCString() << endl; //TODO: output to terminal instead return; } - - //Wait till stopped. TODO: add check if process.GetStateFromEvent(event)==lldb::StateType::eStateStopped after + lldb::SBEvent event; - while(listener.WaitForEvent(3, event) && process.GetStateFromEvent(event)!=lldb::StateType::eStateStopped) {} - - cout << "NumThreads: " << process.GetNumThreads() << endl; - for(uint32_t thread_index_id=0;thread_index_idGetStateFromEvent(event); + bool expected=false; + if(state==lldb::StateType::eStateStopped && stopped.compare_exchange_strong(expected, true)) { + cout << "NumThreads: " << process->GetNumThreads() << endl; + for(uint32_t thread_index_id=0;thread_index_idGetNumThreads();thread_index_id++) { + auto thread=process->GetThreadAtIndex(thread_index_id); + cout << "NumFrames: " << thread.GetNumFrames() << endl; + for(uint32_t frame_index=0;frame_indexGetExitStatus(); + if(callback) + callback(exit_status); + process.reset(); + stopped=false; + return; + } + + else if(state==lldb::StateType::eStateCrashed) { + if(callback) + callback(-1); + process.reset(); + stopped=false; + return; } } + this_thread::sleep_for(std::chrono::milliseconds(200)); } - - process.Continue(); - - //Get exit status. TODO: add check if process.GetStateFromEvent(event)==lldb::StateType::eStateExited after - while(listener.WaitForEvent(3, event) && process.GetStateFromEvent(event)!=lldb::StateType::eStateExited) {} - auto exit_status=process.GetExitStatus(); - - if(callback) - callback(exit_status); }); debug_thread.detach(); } + +void Debug::continue_debug() { + bool expected=true; + if(stopped.compare_exchange_strong(expected, false)) + process->Continue(); +} diff --git a/src/debug.h b/src/debug.h index 59de421..cd18a21 100644 --- a/src/debug.h +++ b/src/debug.h @@ -4,6 +4,7 @@ #include #include #include "lldb/API/SBDebugger.h" +#include "lldb/API/SBProcess.h" class Debug { private: @@ -15,11 +16,14 @@ public: } void start(const boost::filesystem::path &project_path, const boost::filesystem::path &executable, const boost::filesystem::path &path="", std::function callback=nullptr); + void continue_debug(); //can't use continue as function name std::unordered_map > > breakpoints; private: lldb::SBDebugger debugger; + std::unique_ptr process; + std::atomic stopped; }; #endif diff --git a/src/files.h b/src/files.h index 945a2ba..91f2239 100644 --- a/src/files.h +++ b/src/files.h @@ -99,6 +99,7 @@ const std::string configjson = " \"kill_last_running\": \"Escape\",\n" " \"force_kill_last_running\": \"Escape\",\n" " \"debug_start\": \"y\",\n" +" \"debug_continue\": \"y\",\n" " \"debug_toggle_breakpoint\": \"b\",\n" #ifdef __linux " \"next_tab\": \"Tab\",\n" diff --git a/src/menu.cc b/src/menu.cc index ddc6f45..a3e8c32 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -276,6 +276,15 @@ Menu::Menu() { " app.debug_start" +accels["debug_start"]+ //For Ubuntu... " " + " " + "
" + " " + " _Continue" + " app.debug_continue" + +accels["debug_continue"]+ //For Ubuntu... + " " + "
" + "
" " " " _Toggle _Breakpoint" " app.debug_toggle_breakpoint" diff --git a/src/window.cc b/src/window.cc index 761a515..fa7f955 100644 --- a/src/window.cc +++ b/src/window.cc @@ -6,7 +6,7 @@ //#include "api.h" #include "dialogs.h" #include "filesystem.h" -#include "debug.h" //TODO: remove +#include "debug.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -695,6 +695,11 @@ void Window::set_menu_actions() { auto mark=view->get_source_buffer()->create_source_mark("breakpoint", view->get_buffer()->get_insert()->get_iter()); } }); + menu.add_action("debug_continue", [this]() { + if(notebook.get_current_page()!=-1) { + Debug::get().continue_debug(); + } + }); menu.add_action("next_tab", [this]() { if(notebook.get_current_page()!=-1) {