mirror of https://gitlab.com/cppit/jucipp
12 changed files with 376 additions and 68 deletions
@ -0,0 +1,86 @@
|
||||
#include "debug.h" |
||||
|
||||
#include <thread> |
||||
|
||||
#include "lldb/API/SBTarget.h" |
||||
#include "lldb/API/SBProcess.h" |
||||
#include "lldb/API/SBListener.h" |
||||
#include "lldb/API/SBEvent.h" |
||||
#include "lldb/API/SBBreakpoint.h" |
||||
#include "lldb/API/SBThread.h" |
||||
#include "lldb/API/SBStream.h" |
||||
|
||||
#include <iostream> //TODO: remove |
||||
using namespace std; |
||||
|
||||
void log(const char *msg, void *) { |
||||
cout << "debugger log: " << msg << endl; |
||||
} |
||||
|
||||
Debug::Debug() { |
||||
lldb::SBDebugger::Initialize(); |
||||
|
||||
debugger=lldb::SBDebugger::Create(true, log, nullptr); |
||||
} |
||||
|
||||
void Debug::start(const boost::filesystem::path &project_path, const boost::filesystem::path &executable, |
||||
const boost::filesystem::path &path, std::function<void(int exit_status)> callback) { |
||||
std::thread debug_thread([this, project_path, executable, path, callback]() { |
||||
auto target=debugger.CreateTarget(executable.string().c_str()); |
||||
auto listener=lldb::SBListener("juCi++ lldb listener"); |
||||
|
||||
if(!target.IsValid()) { |
||||
cerr << "Error: Could not create debug target to: " << executable << endl; //TODO: output to terminal instead
|
||||
return; |
||||
} |
||||
|
||||
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
|
||||
return; |
||||
} |
||||
else |
||||
cerr << "Created breakpoint at: " << breakpoint.first << ":" << breakpoint.second << endl; |
||||
} |
||||
|
||||
lldb::SBError error; |
||||
auto process = 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(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
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(); |
||||
} |
||||
@ -0,0 +1,25 @@
|
||||
#ifndef JUCI_DEBUG_H_ |
||||
#define JUCI_DEBUG_H_ |
||||
|
||||
#include <boost/filesystem.hpp> |
||||
#include <unordered_map> |
||||
#include "lldb/API/SBDebugger.h" |
||||
|
||||
class Debug { |
||||
private: |
||||
Debug(); |
||||
public: |
||||
static Debug &get() { |
||||
static Debug singleton; |
||||
return singleton; |
||||
} |
||||
|
||||
void start(const boost::filesystem::path &project_path, const boost::filesystem::path &executable, const boost::filesystem::path &path="", std::function<void(int exit_status)> callback=nullptr); |
||||
|
||||
std::unordered_map<std::string, std::vector<std::pair<std::string, int> > > breakpoints; |
||||
|
||||
private: |
||||
lldb::SBDebugger debugger; |
||||
}; |
||||
|
||||
#endif |
||||
Loading…
Reference in new issue