diff --git a/src/debug.cc b/src/debug.cc index ca4db81..b3ed6e3 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -25,8 +25,10 @@ Debug::Debug(): stopped(false) { } void Debug::start(std::shared_ptr > > breakpoints, const boost::filesystem::path &executable, - const boost::filesystem::path &path, std::function callback) { - std::thread debug_thread([this, breakpoints, executable, path, callback]() { + const boost::filesystem::path &path, std::function callback, + std::function status_callback, + std::function stop_callback) { + std::thread debug_thread([this, breakpoints, executable, path, callback, status_callback, stop_callback]() { auto target=debugger.CreateTarget(executable.string().c_str()); auto listener=lldb::SBListener("juCi++ lldb listener"); @@ -40,8 +42,6 @@ void Debug::start(std::shared_ptrGetStateFromEvent(event); + + //Update debug status + lldb::SBStream stream; + event.GetDescription(stream); + std::string event_desc=stream.GetData(); + event_desc.pop_back(); + auto pos=event_desc.rfind(" = "); + if(status_callback && pos!=std::string::npos) + status_callback(event_desc.substr(pos+3)); + bool expected=false; if(state==lldb::StateType::eStateStopped && stopped.compare_exchange_strong(expected, true)) { + auto line_entry=process->GetSelectedThread().GetSelectedFrame().GetLineEntry(); + if(stop_callback) { + lldb::SBStream stream; + line_entry.GetFileSpec().GetDescription(stream); + stop_callback(stream.GetData(), line_entry.GetLine()); + } + + /*lldb::SBStream stream; + process->GetSelectedThread().GetDescription(stream); + cout << stream.GetData() << endl;*/ for(uint32_t thread_index=0;thread_indexGetNumThreads();thread_index++) { auto thread=process->GetThreadAtIndex(thread_index); for(uint32_t frame_index=0;frame_indexGetDescription(stream); + cout << stream.GetData() << endl; + + stream.Clear(); + process->GetSelectedThread().GetSelectedFrame().GetLineEntry().GetDescription(stream); + cout << stream.GetData() << endl;*/ + /*lldb::SBStream stream; auto value=values.GetValueAtIndex(value_index); cout << value.GetFrame().GetSymbol().GetName() << endl; @@ -79,7 +106,7 @@ void Debug::start(std::shared_ptrGetExitStatus(); if(callback) callback(exit_status); + if(status_callback) + status_callback(""); + if(stop_callback) + stop_callback("", 0); process.reset(); stopped=false; return; @@ -97,6 +128,10 @@ void Debug::start(std::shared_ptrContinue(); +} + void Debug::stop() { - auto error=process->Kill(); + auto error=process->Stop(); if(error.Fail()) { cerr << "Error (debug): " << error.GetCString() << endl; //TODO: output to terminal instead return; } } -void Debug::continue_debug() { - bool expected=true; - if(stopped.compare_exchange_strong(expected, false)) - process->Continue(); +void Debug::kill() { + auto error=process->Kill(); + if(error.Fail()) { + cerr << "Error (debug): " << error.GetCString() << endl; //TODO: output to terminal instead + return; + } } std::string Debug::get_value(const std::string &variable) { if(stopped) { - for(uint32_t thread_index=0;thread_indexGetNumThreads();thread_index++) { - auto thread=process->GetThreadAtIndex(thread_index); - for(uint32_t frame_index=0;frame_indexGetSelectedThread().GetSelectedFrame(); + auto values=frame.GetVariables(false, true, false, false); + for(uint32_t value_index=0;value_index > > breakpoints, const boost::filesystem::path &executable, const boost::filesystem::path &path="", std::function callback=nullptr); - void stop(); + void start(std::shared_ptr > > breakpoints, + const boost::filesystem::path &executable, const boost::filesystem::path &path="", + std::function callback=nullptr, + std::function status_callback=nullptr, + std::function stop_callback=nullptr); void continue_debug(); //can't use continue as function name + void stop(); + void kill(); std::string get_value(const std::string &variable); diff --git a/src/files.h b/src/files.h index ef12530..8628b56 100644 --- a/src/files.h +++ b/src/files.h @@ -98,9 +98,9 @@ const std::string configjson = " \"run_command\": \"Return\",\n" " \"kill_last_running\": \"Escape\",\n" " \"force_kill_last_running\": \"Escape\",\n" -" \"debug_start\": \"y\",\n" -" \"debug_stop\": \"\",\n" -" \"debug_continue\": \"y\",\n" +" \"debug_start_continue\": \"y\",\n" +" \"debug_stop\": \"y\",\n" +" \"debug_kill\": \"k\",\n" " \"debug_toggle_breakpoint\": \"b\",\n" #ifdef __linux " \"next_tab\": \"Tab\",\n" diff --git a/src/menu.cc b/src/menu.cc index 21e19ac..1fccdeb 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -272,15 +272,20 @@ Menu::Menu() { " _Debug" "
" " " - " _Start" - " app.debug_start" - +accels["debug_start"]+ //For Ubuntu... + " _Start/_Continue" + " app.debug_start_continue" + +accels["debug_start_continue"]+ //For Ubuntu... " " " " " _Stop" " app.debug_stop" +accels["debug_stop"]+ //For Ubuntu... " " + " " + " _Kill" + " app.debug_kill" + +accels["debug_kill"]+ //For Ubuntu... + " " "
" "
" " " diff --git a/src/source.cc b/src/source.cc index 88e5d30..d8fa996 100644 --- a/src/source.cc +++ b/src/source.cc @@ -122,12 +122,17 @@ Source::View::View(const boost::filesystem::path &file_path, const boost::filesy auto tag=get_buffer()->create_tag("spellcheck_error"); tag->property_underline()=Pango::Underline::UNDERLINE_ERROR; - auto mark_attr=Gsv::MarkAttributes::create(); + auto mark_attr_debug_breakpoint=Gsv::MarkAttributes::create(); Gdk::RGBA rgba; rgba.set_red(1.0); rgba.set_alpha(0.1); - mark_attr->set_background(rgba); - set_mark_attributes("breakpoint", mark_attr, 100); + mark_attr_debug_breakpoint->set_background(rgba); + set_mark_attributes("debug_breakpoint", mark_attr_debug_breakpoint, 100); + auto mark_attr_debug_stop=Gsv::MarkAttributes::create(); + rgba.set_red(0.0); + rgba.set_blue(1.0); + mark_attr_debug_stop->set_background(rgba); + set_mark_attributes("debug_stop", mark_attr_debug_stop, 100); get_buffer()->signal_changed().connect([this](){ if(spellcheck_checker==NULL) diff --git a/src/window.cc b/src/window.cc index c4ac90d..64cfabc 100644 --- a/src/window.cc +++ b/src/window.cc @@ -47,6 +47,7 @@ Window::Window() : compiling(false), debugging(false) { terminal_vbox.pack_start(terminal_scrolled_window); info_and_status_hbox.pack_start(notebook.info, Gtk::PACK_SHRINK); + info_and_status_hbox.set_center_widget(debug_status); info_and_status_hbox.pack_end(notebook.status, Gtk::PACK_SHRINK); terminal_vbox.pack_end(info_and_status_hbox, Gtk::PACK_SHRINK); vpaned.pack2(terminal_vbox, true, true); @@ -616,9 +617,14 @@ void Window::set_menu_actions() { Terminal::get().kill_last_async_process(true); }); - menu.add_action("debug_start", [this](){ - if(debugging) + menu.add_action("debug_start_continue", [this](){ + if(debugging) { + //Continue + if(notebook.get_current_page()!=-1) { + Debug::get().continue_debug(); + } return; + } boost::filesystem::path cmake_path; if(notebook.get_current_page()!=-1) cmake_path=notebook.get_current_view()->file_path.parent_path(); @@ -651,21 +657,12 @@ void Window::set_menu_actions() { auto view=notebook.get_view(c); if(project_path==view->project_path) { auto iter=view->get_buffer()->begin(); - if(view->get_source_buffer()->get_source_marks_at_iter(iter, "breakpoint").size()>0) + if(view->get_source_buffer()->get_source_marks_at_iter(iter, "debug_breakpoint").size()>0) breakpoints->emplace_back(view->file_path.filename(), iter.get_line()+1); - while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "breakpoint")) + while(view->get_source_buffer()->forward_iter_to_source_mark(iter, "debug_breakpoint")) breakpoints->emplace_back(view->file_path.filename(), iter.get_line()+1); } } - /*for(int c=0;cproject_path) { - for(int line_nr=0;line_nrget_buffer()->get_line_count();line_nr++) { - //if(view->get_source_buffer()->get_source_marks_at_line(line_nr, "breakpoint").size()>0) - // breakpoints->emplace_back(view->file_path.filename(), line_nr+1); - } - } - }*/ Terminal::get().print("Compiling and running "+executable_path.string()+"\n"); Terminal::get().async_process(Config::get().terminal.make_command, debug_build_path, [this, breakpoints, executable_path, debug_build_path](int exit_status){ if(exit_status==EXIT_SUCCESS) { @@ -682,6 +679,33 @@ void Window::set_menu_actions() { Debug::get().start(breakpoints, executable_path_spaces_fixed, debug_build_path, [this, executable_path](int exit_status){ debugging=false; Terminal::get().async_print(executable_path.string()+" returned: "+std::to_string(exit_status)+'\n'); + }, [this](const std::string &status) { + //TODO: move to main thread + if(status.empty()) + debug_status.set_text(""); + else + debug_status.set_text("debug: "+status); + }, [this](const boost::filesystem::path &file, int line) { + //TODO: move to main thread + //Remove debug stop source mark + for(int c=0;cfile_path==debug_last_stop_line.first) { + auto start_iter=view->get_buffer()->get_iter_at_line(debug_last_stop_line.second-1); + auto end_iter=start_iter; + while(!end_iter.ends_line() && end_iter.forward_char()) {} + view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_stop"); + break; + } + } + //Add debug stop source mark + for(int c=0;cfile_path==file) { + view->get_source_buffer()->create_source_mark("debug_stop", view->get_buffer()->get_iter_at_line(line-1)); + debug_last_stop_line={file, line}; + } + } }); } }); @@ -697,9 +721,9 @@ void Window::set_menu_actions() { Debug::get().stop(); } }); - menu.add_action("debug_continue", [this]() { - if(notebook.get_current_page()!=-1 && debugging) { - Debug::get().continue_debug(); + menu.add_action("debug_kill", [this]() { + if(debugging) { + Debug::get().kill(); } }); menu.add_action("debug_toggle_breakpoint", [this](){ @@ -707,14 +731,14 @@ void Window::set_menu_actions() { auto view=notebook.get_current_view(); auto line_nr=view->get_buffer()->get_insert()->get_iter().get_line()+1; - if(view->get_source_buffer()->get_source_marks_at_line(line_nr-1, "breakpoint").size()>0) { + if(view->get_source_buffer()->get_source_marks_at_line(line_nr-1, "debug_breakpoint").size()>0) { auto start_iter=view->get_buffer()->get_iter_at_line(line_nr-1); auto end_iter=start_iter; while(!end_iter.ends_line() && end_iter.forward_char()) {} - view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "breakpoint"); + view->get_source_buffer()->remove_source_marks(start_iter, end_iter, "debug_breakpoint"); } else - view->get_source_buffer()->create_source_mark("breakpoint", view->get_buffer()->get_insert()->get_iter()); + view->get_source_buffer()->create_source_mark("debug_breakpoint", view->get_buffer()->get_insert()->get_iter()); } }); diff --git a/src/window.h b/src/window.h index 45a592d..b8439c6 100644 --- a/src/window.h +++ b/src/window.h @@ -31,8 +31,11 @@ private: Gtk::HBox info_and_status_hbox; Gtk::AboutDialog about; EntryBox entry_box; + std::atomic compiling; std::atomic debugging; + Gtk::Label debug_status; + std::pair debug_last_stop_line; void configure(); void set_menu_actions();