Browse Source

Debug event handlers cleanup

merge-requests/365/head
eidheim 8 years ago
parent
commit
15ad9fbe2d
  1. 146
      src/debug_lldb.cc
  2. 14
      src/debug_lldb.h
  3. 59
      src/project.cc
  4. 27
      tests/lldb_test.cc

146
src/debug_lldb.cc

@ -10,19 +10,6 @@
#include "process.hpp" #include "process.hpp"
#include "config.h" #include "config.h"
#include <lldb/API/SBTarget.h>
#include <lldb/API/SBProcess.h>
#include <lldb/API/SBEvent.h>
#include <lldb/API/SBBreakpoint.h>
#include <lldb/API/SBThread.h>
#include <lldb/API/SBStream.h>
#include <lldb/API/SBDeclaration.h>
#include <lldb/API/SBCommandInterpreter.h>
#include <lldb/API/SBCommandReturnObject.h>
#include <lldb/API/SBBreakpointLocation.h>
using namespace std; //TODO: remove
extern char **environ; extern char **environ;
void log(const char *msg, void *) { void log(const char *msg, void *) {
@ -112,9 +99,6 @@ std::tuple<std::vector<std::string>, std::string, std::vector<std::string> > Deb
void Debug::LLDB::start(const std::string &command, const boost::filesystem::path &path, void Debug::LLDB::start(const std::string &command, const boost::filesystem::path &path,
const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints, const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints,
std::function<void(int exit_status)> callback,
std::function<void(const std::string &status)> status_callback,
std::function<void(const boost::filesystem::path &file_path, int line_nr, int line_index)> stop_callback,
const std::string &remote_host) { const std::string &remote_host) {
if(!debugger) { if(!debugger) {
lldb::SBDebugger::Initialize(); lldb::SBDebugger::Initialize();
@ -136,8 +120,8 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
auto target=debugger->CreateTarget(executable.c_str()); auto target=debugger->CreateTarget(executable.c_str());
if(!target.IsValid()) { if(!target.IsValid()) {
Terminal::get().async_print("Error (debug): Could not create debug target to: "+executable+'\n', true); Terminal::get().async_print("Error (debug): Could not create debug target to: "+executable+'\n', true);
if(callback) for(auto &handler: on_exit)
callback(-1); handler.second(-1);
return; return;
} }
@ -145,8 +129,8 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
for(auto &breakpoint: breakpoints) { for(auto &breakpoint: breakpoints) {
if(!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) { if(!(target.BreakpointCreateByLocation(breakpoint.first.string().c_str(), breakpoint.second)).IsValid()) {
Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+breakpoint.first.string()+":"+std::to_string(breakpoint.second)+'\n', true); Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+breakpoint.first.string()+":"+std::to_string(breakpoint.second)+'\n', true);
if(callback) for(auto &handler: on_exit)
callback(-1); handler.second(-1);
return; return;
} }
} }
@ -157,8 +141,8 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
process = std::make_unique<lldb::SBProcess>(target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error)); process = std::make_unique<lldb::SBProcess>(target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error));
if(error.Fail()) { if(error.Fail()) {
Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true);
if(callback) for(auto &handler: on_exit)
callback(-1); handler.second(-1);
return; return;
} }
lldb::SBEvent event; lldb::SBEvent event;
@ -199,16 +183,18 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
} }
if(error.Fail()) { if(error.Fail()) {
Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true);
if(callback) for(auto &handler: on_exit)
callback(-1); handler.second(-1);
return; return;
} }
if(debug_thread.joinable()) if(debug_thread.joinable())
debug_thread.join(); debug_thread.join();
debug_thread=std::thread([this, callback, status_callback, stop_callback]() { for(auto &handler: on_start)
handler.second(*process);
debug_thread=std::thread([this]() {
lldb::SBEvent event; lldb::SBEvent event;
while(true) { while(true) {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(listener->GetNextEvent(event)) { if(listener->GetNextEvent(event)) {
if((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged)>0) { if((event.GetType() & lldb::SBProcess::eBroadcastBitStateChanged)>0) {
auto state=process->GetStateFromEvent(event); auto state=process->GetStateFromEvent(event);
@ -224,67 +210,17 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
} }
} }
//Update debug status lock.unlock();
lldb::SBStream stream; for(auto &handler: on_event)
event.GetDescription(stream); handler.second(event);
std::string event_desc=stream.GetData(); lock.lock();
event_desc.pop_back();
auto pos=event_desc.rfind(" = "); if(state==lldb::StateType::eStateExited || state==lldb::StateType::eStateCrashed) {
if(status_callback && pos!=std::string::npos) { auto exit_status=state==lldb::StateType::eStateCrashed?-1:process->GetExitStatus();
auto status=event_desc.substr(pos+3); lock.unlock();
if(state==lldb::StateType::eStateStopped) { for(auto &handler: on_exit)
char buffer[100]; handler.second(exit_status);
auto thread=process->GetSelectedThread(); lock.lock();
auto n=thread.GetStopDescription(buffer, 100);
if(n>0)
status+=" ("+std::string(buffer, n<=100?n:100)+")";
auto line_entry=thread.GetSelectedFrame().GetLineEntry();
if(line_entry.IsValid()) {
lldb::SBStream stream;
line_entry.GetFileSpec().GetDescription(stream);
status +=" "+boost::filesystem::path(stream.GetData()).filename().string()+":"+std::to_string(line_entry.GetLine());
}
}
status_callback(status);
}
if(state==lldb::StateType::eStateStopped) {
if(stop_callback) {
auto line_entry=process->GetSelectedThread().GetSelectedFrame().GetLineEntry();
if(line_entry.IsValid()) {
lldb::SBStream stream;
line_entry.GetFileSpec().GetDescription(stream);
auto column=line_entry.GetColumn();
if(column==0)
column=1;
stop_callback(filesystem::get_normal_path(stream.GetData()), line_entry.GetLine(), column);
}
else
stop_callback("", 0, 0);
}
}
else if(state==lldb::StateType::eStateRunning) {
stop_callback("", 0, 0);
}
else if(state==lldb::StateType::eStateExited) {
auto exit_status=process->GetExitStatus();
if(callback)
callback(exit_status);
if(status_callback)
status_callback("");
if(stop_callback)
stop_callback("", 0, 0);
process.reset();
this->state=lldb::StateType::eStateInvalid;
return;
}
else if(state==lldb::StateType::eStateCrashed) {
if(callback)
callback(-1);
if(status_callback)
status_callback("");
if(stop_callback)
stop_callback("", 0, 0);
process.reset(); process.reset();
this->state=lldb::StateType::eStateInvalid; this->state=lldb::StateType::eStateInvalid;
return; return;
@ -311,13 +247,13 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat
} }
void Debug::LLDB::continue_debug() { void Debug::LLDB::continue_debug() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) if(state==lldb::StateType::eStateStopped)
process->Continue(); process->Continue();
} }
void Debug::LLDB::stop() { void Debug::LLDB::stop() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateRunning) { if(state==lldb::StateType::eStateRunning) {
auto error=process->Stop(); auto error=process->Stop();
if(error.Fail()) if(error.Fail())
@ -326,7 +262,7 @@ void Debug::LLDB::stop() {
} }
void Debug::LLDB::kill() { void Debug::LLDB::kill() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(process) { if(process) {
auto error=process->Kill(); auto error=process->Kill();
if(error.Fail()) if(error.Fail())
@ -335,21 +271,21 @@ void Debug::LLDB::kill() {
} }
void Debug::LLDB::step_over() { void Debug::LLDB::step_over() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
process->GetSelectedThread().StepOver(); process->GetSelectedThread().StepOver();
} }
} }
void Debug::LLDB::step_into() { void Debug::LLDB::step_into() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
process->GetSelectedThread().StepInto(); process->GetSelectedThread().StepInto();
} }
} }
void Debug::LLDB::step_out() { void Debug::LLDB::step_out() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
process->GetSelectedThread().StepOut(); process->GetSelectedThread().StepOut();
} }
@ -357,7 +293,7 @@ void Debug::LLDB::step_out() {
std::pair<std::string, std::string> Debug::LLDB::run_command(const std::string &command) { std::pair<std::string, std::string> Debug::LLDB::run_command(const std::string &command) {
std::pair<std::string, std::string> command_return; std::pair<std::string, std::string> command_return;
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped || state==lldb::StateType::eStateRunning) { if(state==lldb::StateType::eStateStopped || state==lldb::StateType::eStateRunning) {
lldb::SBCommandReturnObject command_return_object; lldb::SBCommandReturnObject command_return_object;
debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, true); debugger->GetCommandInterpreter().HandleCommand(command.c_str(), command_return_object, true);
@ -373,7 +309,7 @@ std::pair<std::string, std::string> Debug::LLDB::run_command(const std::string &
std::vector<Debug::LLDB::Frame> Debug::LLDB::get_backtrace() { std::vector<Debug::LLDB::Frame> Debug::LLDB::get_backtrace() {
std::vector<Frame> backtrace; std::vector<Frame> backtrace;
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
auto thread=process->GetSelectedThread(); auto thread=process->GetSelectedThread();
for(uint32_t c_f=0;c_f<thread.GetNumFrames();c_f++) { for(uint32_t c_f=0;c_f<thread.GetNumFrames();c_f++) {
@ -409,7 +345,7 @@ std::vector<Debug::LLDB::Frame> Debug::LLDB::get_backtrace() {
std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() { std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
std::vector<Debug::LLDB::Variable> variables; std::vector<Debug::LLDB::Variable> variables;
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
for(uint32_t c_t=0;c_t<process->GetNumThreads();c_t++) { for(uint32_t c_t=0;c_t<process->GetNumThreads();c_t++) {
auto thread=process->GetThreadAtIndex(c_t); auto thread=process->GetThreadAtIndex(c_t);
@ -463,7 +399,7 @@ std::vector<Debug::LLDB::Variable> Debug::LLDB::get_variables() {
} }
void Debug::LLDB::select_frame(uint32_t frame_index, uint32_t thread_index_id) { void Debug::LLDB::select_frame(uint32_t frame_index, uint32_t thread_index_id) {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
if(thread_index_id!=0) if(thread_index_id!=0)
process->SetSelectedThreadByIndexID(thread_index_id); process->SetSelectedThreadByIndexID(thread_index_id);
@ -479,7 +415,7 @@ void Debug::LLDB::cancel() {
std::string Debug::LLDB::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string Debug::LLDB::get_value(const std::string &variable, const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) {
std::string variable_value; std::string variable_value;
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
auto frame=process->GetSelectedThread().GetSelectedFrame(); auto frame=process->GetSelectedThread().GetSelectedFrame();
@ -520,7 +456,7 @@ std::string Debug::LLDB::get_value(const std::string &variable, const boost::fil
std::string Debug::LLDB::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) { std::string Debug::LLDB::get_return_value(const boost::filesystem::path &file_path, unsigned int line_nr, unsigned int line_index) {
std::string return_value; std::string return_value;
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateStopped) { if(state==lldb::StateType::eStateStopped) {
auto thread=process->GetSelectedThread(); auto thread=process->GetSelectedThread();
auto thread_return_value=thread.GetStopReturnValue(); auto thread_return_value=thread.GetStopReturnValue();
@ -542,22 +478,22 @@ std::string Debug::LLDB::get_return_value(const boost::filesystem::path &file_pa
} }
bool Debug::LLDB::is_invalid() { bool Debug::LLDB::is_invalid() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
return state==lldb::StateType::eStateInvalid; return state==lldb::StateType::eStateInvalid;
} }
bool Debug::LLDB::is_stopped() { bool Debug::LLDB::is_stopped() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
return state==lldb::StateType::eStateStopped; return state==lldb::StateType::eStateStopped;
} }
bool Debug::LLDB::is_running() { bool Debug::LLDB::is_running() {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
return state==lldb::StateType::eStateRunning; return state==lldb::StateType::eStateRunning;
} }
void Debug::LLDB::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) { void Debug::LLDB::add_breakpoint(const boost::filesystem::path &file_path, int line_nr) {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::eStateStopped || state==lldb::eStateRunning) { if(state==lldb::eStateStopped || state==lldb::eStateRunning) {
if(!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid()) if(!(process->GetTarget().BreakpointCreateByLocation(file_path.string().c_str(), line_nr)).IsValid())
Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+file_path.string()+":"+std::to_string(line_nr)+'\n', true); Terminal::get().async_print("Error (debug): Could not create breakpoint at: "+file_path.string()+":"+std::to_string(line_nr)+'\n', true);
@ -565,7 +501,7 @@ void Debug::LLDB::add_breakpoint(const boost::filesystem::path &file_path, int l
} }
void Debug::LLDB::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) { void Debug::LLDB::remove_breakpoint(const boost::filesystem::path &file_path, int line_nr, int line_count) {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::eStateStopped || state==lldb::eStateRunning) { if(state==lldb::eStateStopped || state==lldb::eStateRunning) {
auto target=process->GetTarget(); auto target=process->GetTarget();
for(int line_nr_try=line_nr;line_nr_try<line_count;line_nr_try++) { for(int line_nr_try=line_nr;line_nr_try<line_count;line_nr_try++) {
@ -590,7 +526,7 @@ void Debug::LLDB::remove_breakpoint(const boost::filesystem::path &file_path, in
} }
void Debug::LLDB::write(const std::string &buffer) { void Debug::LLDB::write(const std::string &buffer) {
std::unique_lock<std::mutex> lock(event_mutex); std::unique_lock<std::mutex> lock(mutex);
if(state==lldb::StateType::eStateRunning) { if(state==lldb::StateType::eStateRunning) {
process->PutSTDIN(buffer.c_str(), buffer.size()); process->PutSTDIN(buffer.c_str(), buffer.size());
} }

14
src/debug_lldb.h

@ -3,9 +3,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <unordered_map> #include <unordered_map>
#include <lldb/API/SBDebugger.h> #include <lldb/API/LLDB.h>
#include <lldb/API/SBListener.h>
#include <lldb/API/SBProcess.h>
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <tuple> #include <tuple>
@ -41,11 +39,14 @@ namespace Debug {
return singleton; return singleton;
} }
std::unordered_map<std::string, std::function<void(const lldb::SBProcess &)>> on_start;
std::unordered_map<std::string, std::function<void(int exit_status)>> on_exit;
std::unordered_map<std::string, std::function<void(const lldb::SBEvent &)>> on_event;
std::mutex mutex;
void start(const std::string &command, const boost::filesystem::path &path="", void start(const std::string &command, const boost::filesystem::path &path="",
const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints={}, const std::vector<std::pair<boost::filesystem::path, int> > &breakpoints={},
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_path, int line_nr, int line_index)> stop_callback=nullptr,
const std::string &remote_host=""); const std::string &remote_host="");
void continue_debug(); //can't use continue as function name void continue_debug(); //can't use continue as function name
void stop(); void stop();
@ -81,7 +82,6 @@ namespace Debug {
std::thread debug_thread; std::thread debug_thread;
lldb::StateType state; lldb::StateType state;
std::mutex event_mutex;
size_t buffer_size; size_t buffer_size;
}; };

59
src/project.cc

@ -447,24 +447,63 @@ void Project::Clang::debug_start() {
auto options_it=debug_options.find(project_path->string()); auto options_it=debug_options.find(project_path->string());
if(options_it!=debug_options.end() && options_it->second.remote_enabled.get_active()) if(options_it!=debug_options.end() && options_it->second.remote_enabled.get_active())
remote_host=options_it->second.remote_host.get_text(); remote_host=options_it->second.remote_host.get_text();
Debug::LLDB::get().start(*run_arguments, *project_path, breakpoints, [this, run_arguments](int exit_status){
Debug::LLDB::get().on_exit["debug_start"]=[this, run_arguments](int exit_status) {
debugging=false; debugging=false;
Terminal::get().async_print(*run_arguments+" returned: "+std::to_string(exit_status)+'\n'); Terminal::get().async_print(*run_arguments+" returned: "+std::to_string(exit_status)+'\n');
}, [this](const std::string &status) { dispatcher.post([this] {
dispatcher.post([this, status] { debug_update_status("");
debug_update_status(status);
}); });
}, [this](const boost::filesystem::path &file_path, int line_nr, int line_index) { };
dispatcher.post([this, file_path, line_nr, line_index] {
Project::debug_stop.first=file_path; Debug::LLDB::get().on_event["debug_start"]=[this](const lldb::SBEvent &event) {
Project::debug_stop.second.first=line_nr-1; std::string status;
Project::debug_stop.second.second=line_index-1; boost::filesystem::path stop_path;
unsigned stop_line=0, stop_column=0;
std::unique_lock<std::mutex> lock(Debug::LLDB::get().mutex);
auto process=lldb::SBProcess::GetProcessFromEvent(event);
auto state=lldb::SBProcess::GetStateFromEvent(event);
lldb::SBStream stream;
event.GetDescription(stream);
std::string event_desc=stream.GetData();
event_desc.pop_back();
auto pos=event_desc.rfind(" = ");
if(pos!=std::string::npos && pos+3<event_desc.size())
status=event_desc.substr(pos+3);
if(state==lldb::StateType::eStateStopped) {
char buffer[100];
auto thread=process.GetSelectedThread();
auto n=thread.GetStopDescription(buffer, 100);
if(n>0)
status+=" ("+std::string(buffer, n<=100?n:100)+")";
auto line_entry=thread.GetSelectedFrame().GetLineEntry();
if(line_entry.IsValid()) {
lldb::SBStream stream;
line_entry.GetFileSpec().GetDescription(stream);
auto line=line_entry.GetLine();
status +=" "+boost::filesystem::path(stream.GetData()).filename().string()+":"+std::to_string(line);
auto column=line_entry.GetColumn();
if(column==0)
column=1;
stop_path=filesystem::get_normal_path(stream.GetData());
stop_line=line-1;
stop_column=column-1;
}
}
dispatcher.post([this, status=std::move(status), stop_path=std::move(stop_path), stop_line, stop_column] {
debug_update_status(status);
Project::debug_stop.first=stop_path;
Project::debug_stop.second.first=stop_line;
Project::debug_stop.second.second=stop_column;
debug_update_stop(); debug_update_stop();
if(auto view=Notebook::get().get_current_view()) if(auto view=Notebook::get().get_current_view())
view->get_buffer()->place_cursor(view->get_buffer()->get_insert()->get_iter()); view->get_buffer()->place_cursor(view->get_buffer()->get_insert()->get_iter());
}); });
}, remote_host); };
Debug::LLDB::get().start(*run_arguments, *project_path, breakpoints, remote_host);
}); });
} }
}); });

27
tests/lldb_test.cc

@ -80,15 +80,26 @@ int main() {
std::atomic<bool> exited(false); std::atomic<bool> exited(false);
int exit_status; int exit_status;
std::atomic<int> line_nr(0); std::atomic<int> line_nr(0);
Debug::LLDB::get().on_exit["test"]=[&](int exit_status_) {
exit_status=exit_status_;
exited=true;
};
Debug::LLDB::get().on_event["test"]=[&](const lldb::SBEvent &event) {
std::unique_lock<std::mutex> lock(Debug::LLDB::get().mutex);
auto process=lldb::SBProcess::GetProcessFromEvent(event);
auto state=lldb::SBProcess::GetStateFromEvent(event);
if(state==lldb::StateType::eStateStopped) {
auto line_entry=process.GetSelectedThread().GetSelectedFrame().GetLineEntry();
if(line_entry.IsValid()) {
lldb::SBStream stream;
line_entry.GetFileSpec().GetDescription(stream);
line_nr=line_entry.GetLine();
}
}
};
std::thread debug_thread([&] { std::thread debug_thread([&] {
Debug::LLDB::get().start(exec_path.string(), "", breakpoints, [&](int exit_status_){ Debug::LLDB::get().start(exec_path.string(), "", breakpoints);
exit_status=exit_status_;
exited=true;
}, [](const std::string &status) {
}, [&](const boost::filesystem::path &file_path, int line_nr_, int line_index) {
line_nr=line_nr_;
});
}); });
for(;;) { for(;;) {

Loading…
Cancel
Save