|
|
|
|
@ -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<lldb::SBProcess>(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_id<process.GetNumThreads();thread_index_id++) { |
|
|
|
|
auto thread=process.GetThreadAtIndex(thread_index_id); |
|
|
|
|
cout << "NumFrames: " << thread.GetNumFrames() << endl; |
|
|
|
|
for(uint32_t frame_index=0;frame_index<thread.GetNumFrames();frame_index++) { |
|
|
|
|
auto frame=thread.GetFrameAtIndex(frame_index); |
|
|
|
|
auto values=frame.GetVariables(true, true, true, true); |
|
|
|
|
cout << "variables.GetSize(): " << values.GetSize() << endl; |
|
|
|
|
for(uint32_t value_index=0;value_index<values.GetSize();value_index++) { |
|
|
|
|
auto value=values.GetValueAtIndex(value_index); |
|
|
|
|
//cout << value.GetName() << ": " << value.GetValue() << endl;
|
|
|
|
|
lldb::SBStream stream; |
|
|
|
|
value.GetDescription(stream); |
|
|
|
|
cout << stream.GetData(); |
|
|
|
|
while(true) { |
|
|
|
|
if(listener.WaitForEvent(3, event)) { |
|
|
|
|
auto state=process->GetStateFromEvent(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_id<process->GetNumThreads();thread_index_id++) { |
|
|
|
|
auto thread=process->GetThreadAtIndex(thread_index_id); |
|
|
|
|
cout << "NumFrames: " << thread.GetNumFrames() << endl; |
|
|
|
|
for(uint32_t frame_index=0;frame_index<thread.GetNumFrames();frame_index++) { |
|
|
|
|
auto frame=thread.GetFrameAtIndex(frame_index); |
|
|
|
|
auto values=frame.GetVariables(true, true, true, true); |
|
|
|
|
cout << "variables.GetSize(): " << values.GetSize() << endl; |
|
|
|
|
for(uint32_t value_index=0;value_index<values.GetSize();value_index++) { |
|
|
|
|
auto value=values.GetValueAtIndex(value_index); |
|
|
|
|
lldb::SBStream stream; |
|
|
|
|
value.GetDescription(stream); |
|
|
|
|
cout << stream.GetData(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
else if(state==lldb::StateType::eStateExited) { |
|
|
|
|
auto exit_status=process->GetExitStatus(); |
|
|
|
|
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(); |
|
|
|
|
} |
|
|
|
|
|