Browse Source

Added debug status and now shows the line where the debug process is stopped

merge-requests/365/head
eidheim 10 years ago
parent
commit
8905f8fc75
  1. 88
      src/debug.cc
  2. 9
      src/debug.h
  3. 6
      src/files.h
  4. 11
      src/menu.cc
  5. 11
      src/source.cc
  6. 62
      src/window.cc
  7. 3
      src/window.h

88
src/debug.cc

@ -25,8 +25,10 @@ Debug::Debug(): stopped(false) {
}
void Debug::start(std::shared_ptr<std::vector<std::pair<boost::filesystem::path, int> > > breakpoints, const boost::filesystem::path &executable,
const boost::filesystem::path &path, std::function<void(int exit_status)> callback) {
std::thread debug_thread([this, breakpoints, executable, path, callback]() {
const boost::filesystem::path &path, std::function<void(int exit_status)> callback,
std::function<void(const std::string &status)> status_callback,
std::function<void(const boost::filesystem::path &file, int line)> 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_ptr<std::vector<std::pair<boost::filesystem::path,
cerr << "Error: Could not create breakpoint at: " << breakpoint.first << ":" << breakpoint.second << endl; //TODO: output to terminal instead
return;
}
else
cerr << "Created breakpoint at: " << breakpoint.first << ":" << breakpoint.second << endl;
}
lldb::SBError error;
@ -56,16 +56,43 @@ void Debug::start(std::shared_ptr<std::vector<std::pair<boost::filesystem::path,
while(true) {
if(listener.WaitForEvent(3, event)) {
auto state=process->GetStateFromEvent(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_index<process->GetNumThreads();thread_index++) {
auto thread=process->GetThreadAtIndex(thread_index);
for(uint32_t frame_index=0;frame_index<thread.GetNumFrames();frame_index++) {
auto frame=thread.GetFrameAtIndex(frame_index);
auto values=frame.GetVariables(false, true, true, false);
for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
cout << thread_index << ", " << frame_index << endl;
/*cout << thread_index << ", " << frame_index << endl;
lldb::SBStream stream;
process->GetDescription(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_ptr<std::vector<std::pair<boost::filesystem::path,
stream.Clear();
value.GetData().GetDescription(stream);
cout << " " << stream.GetData() << endl;
cout << " " << stream.GetData() << endl;*/
}
}
}
@ -89,6 +116,10 @@ void Debug::start(std::shared_ptr<std::vector<std::pair<boost::filesystem::path,
auto exit_status=process->GetExitStatus();
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_ptr<std::vector<std::pair<boost::filesystem::path,
else if(state==lldb::StateType::eStateCrashed) {
if(callback)
callback(-1);
if(status_callback)
status_callback("");
if(stop_callback)
stop_callback("", 0);
process.reset();
stopped=false;
return;
@ -108,36 +143,39 @@ void Debug::start(std::shared_ptr<std::vector<std::pair<boost::filesystem::path,
debug_thread.detach();
}
void Debug::continue_debug() {
bool expected=true;
if(stopped.compare_exchange_strong(expected, false))
process->Continue();
}
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_index<process->GetNumThreads();thread_index++) {
auto thread=process->GetThreadAtIndex(thread_index);
for(uint32_t frame_index=0;frame_index<thread.GetNumFrames();frame_index++) {
auto frame=thread.GetFrameAtIndex(frame_index);
auto values=frame.GetVariables(false, true, false, false);
for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
lldb::SBStream stream;
auto value=values.GetValueAtIndex(value_index);
if(value.GetName()==variable) {
value.GetDescription(stream);
return stream.GetData();
}
}
auto frame=process->GetSelectedThread().GetSelectedFrame();
auto values=frame.GetVariables(false, true, false, false);
for(uint32_t value_index=0;value_index<values.GetSize();value_index++) {
lldb::SBStream stream;
auto value=values.GetValueAtIndex(value_index);
if(value.GetName()==variable) {
value.GetDescription(stream);
return stream.GetData();
}
}
}

9
src/debug.h

@ -15,9 +15,14 @@ public:
return singleton;
}
void start(std::shared_ptr<std::vector<std::pair<boost::filesystem::path, int> > > breakpoints, const boost::filesystem::path &executable, const boost::filesystem::path &path="", std::function<void(int exit_status)> callback=nullptr);
void stop();
void start(std::shared_ptr<std::vector<std::pair<boost::filesystem::path, int> > > breakpoints,
const boost::filesystem::path &executable, const boost::filesystem::path &path="",
std::function<void(int exit_status)> callback=nullptr,
std::function<void(const std::string &status)> status_callback=nullptr,
std::function<void(const boost::filesystem::path &file, int line)> 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);

6
src/files.h

@ -98,9 +98,9 @@ const std::string configjson =
" \"run_command\": \"<alt>Return\",\n"
" \"kill_last_running\": \"<primary>Escape\",\n"
" \"force_kill_last_running\": \"<primary><shift>Escape\",\n"
" \"debug_start\": \"<primary>y\",\n"
" \"debug_stop\": \"\",\n"
" \"debug_continue\": \"<primary><shift>y\",\n"
" \"debug_start_continue\": \"<primary>y\",\n"
" \"debug_stop\": \"<primary><shift>y\",\n"
" \"debug_kill\": \"<primary>k\",\n"
" \"debug_toggle_breakpoint\": \"<primary>b\",\n"
#ifdef __linux
" \"next_tab\": \"<primary>Tab\",\n"

11
src/menu.cc

@ -272,15 +272,20 @@ Menu::Menu() {
" <attribute name='label' translatable='yes'>_Debug</attribute>"
" <section>"
" <item>"
" <attribute name='label' translatable='yes'>_Start</attribute>"
" <attribute name='action'>app.debug_start</attribute>"
+accels["debug_start"]+ //For Ubuntu...
" <attribute name='label' translatable='yes'>_Start/_Continue</attribute>"
" <attribute name='action'>app.debug_start_continue</attribute>"
+accels["debug_start_continue"]+ //For Ubuntu...
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_Stop</attribute>"
" <attribute name='action'>app.debug_stop</attribute>"
+accels["debug_stop"]+ //For Ubuntu...
" </item>"
" <item>"
" <attribute name='label' translatable='yes'>_Kill</attribute>"
" <attribute name='action'>app.debug_kill</attribute>"
+accels["debug_kill"]+ //For Ubuntu...
" </item>"
" </section>"
" <section>"
" <item>"

11
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)

62
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;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(project_path==view->project_path) {
for(int line_nr=0;line_nr<view->get_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;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(view->file_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;c<notebook.size();c++) {
auto view=notebook.get_view(c);
if(view->file_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());
}
});

3
src/window.h

@ -31,8 +31,11 @@ private:
Gtk::HBox info_and_status_hbox;
Gtk::AboutDialog about;
EntryBox entry_box;
std::atomic<bool> compiling;
std::atomic<bool> debugging;
Gtk::Label debug_status;
std::pair<boost::filesystem::path, int> debug_last_stop_line;
void configure();
void set_menu_actions();

Loading…
Cancel
Save