add 'step' and 'resume' commands
This commit is contained in:
parent
5972bc769b
commit
9372a5226e
@ -2,8 +2,16 @@
|
||||
-- may be reused one global ffi buffer per lua_State
|
||||
|
||||
local breakpoints = {}
|
||||
local dbg_steps_mode = false
|
||||
local hook_lock = false
|
||||
|
||||
debug.sethook(function (e, line)
|
||||
if dbg_steps_mode and not hook_lock then
|
||||
hook_lock = true
|
||||
debug.breakpoint()
|
||||
debug.pull_events()
|
||||
end
|
||||
hook_lock = false
|
||||
local bps = breakpoints[line]
|
||||
if not bps then
|
||||
return
|
||||
@ -18,6 +26,9 @@ end, "l")
|
||||
|
||||
local DBG_EVENT_SET_BREAKPOINT = 1
|
||||
local DBG_EVENT_RM_BREAKPOINT = 2
|
||||
local DBG_EVENT_STEP = 3
|
||||
local DBG_EVENT_STEP_INTO_FUNCTION = 4
|
||||
local DBG_EVENT_RESUME = 5
|
||||
local __pull_events = debug.__pull_events
|
||||
debug.__pull_events = nil
|
||||
|
||||
@ -31,6 +42,10 @@ function debug.pull_events()
|
||||
debug.set_breakpoint(event[2], event[3])
|
||||
elseif event[1] == DBG_EVENT_RM_BREAKPOINT then
|
||||
debug.remove_breakpoint(event[2], event[3])
|
||||
elseif event[1] == DBG_EVENT_STEP then
|
||||
dbg_steps_mode = true
|
||||
elseif event[1] == DBG_EVENT_RESUME then
|
||||
dbg_steps_mode = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -130,25 +130,25 @@ DebuggingServer::~DebuggingServer() {
|
||||
|
||||
bool DebuggingServer::update() {
|
||||
if (connection == nullptr) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
std::string message = connection->read();
|
||||
if (message.empty()) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
logger.debug() << "received: " << message;
|
||||
try {
|
||||
auto obj = json::parse(message);
|
||||
if (!obj.has("type")) {
|
||||
logger.error() << "missing message type";
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
const auto& type = obj["type"].asString();
|
||||
return performCommand(type, obj);
|
||||
} catch (const std::runtime_error& err) {
|
||||
logger.error() << "could not to parse message: " << err.what();
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DebuggingServer::performCommand(
|
||||
@ -158,24 +158,38 @@ bool DebuggingServer::performCommand(
|
||||
engine.quit();
|
||||
connection->sendResponse("success");
|
||||
} else if (type == "detach") {
|
||||
logger.info() << "detach received";
|
||||
connection->sendResponse("success");
|
||||
connection.reset();
|
||||
engine.detachDebugger();
|
||||
return false;
|
||||
} else if (type == "set-breakpoint" || type == "remove-breakpoint") {
|
||||
if (!map.has("source") || !map.has("line"))
|
||||
return true;
|
||||
breakpointEvents.push_back(BreakpointEvent {
|
||||
return false;
|
||||
breakpointEvents.push_back(DebuggingEvent {
|
||||
type[0] == 's'
|
||||
? BreakpointEventType::SET_BREAKPOINT
|
||||
: BreakpointEventType::REMOVE_BREAKPOINT,
|
||||
? DebuggingEventType::SET_BREAKPOINT
|
||||
: DebuggingEventType::REMOVE_BREAKPOINT,
|
||||
BreakpointEventDto {
|
||||
map["source"].asString(),
|
||||
static_cast<int>(map["line"].asInteger()),
|
||||
}
|
||||
});
|
||||
} else if (type == "step" || type == "step-into-function") {
|
||||
breakpointEvents.push_back(DebuggingEvent {
|
||||
type == "step"
|
||||
? DebuggingEventType::STEP
|
||||
: DebuggingEventType::STEP_INTO_FUNCTION,
|
||||
SignalEventDto {}
|
||||
});
|
||||
return true;
|
||||
} else if (type == "resume") {
|
||||
breakpointEvents.push_back(DebuggingEvent {
|
||||
DebuggingEventType::RESUME, SignalEventDto {}});
|
||||
return true;
|
||||
} else {
|
||||
logger.error() << "unsupported command '" << type << "'";
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void DebuggingServer::onHitBreakpoint(dv::value&& stackTrace) {
|
||||
@ -195,6 +209,6 @@ void DebuggingServer::setClient(u64id_t client) {
|
||||
std::make_unique<ClientConnection>(engine.getNetwork(), client);
|
||||
}
|
||||
|
||||
std::vector<BreakpointEvent> DebuggingServer::pullBreakpointEvents() {
|
||||
std::vector<DebuggingEvent> DebuggingServer::pullEvents() {
|
||||
return std::move(breakpointEvents);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <variant>
|
||||
|
||||
#include "typedefs.hpp"
|
||||
|
||||
@ -36,16 +37,27 @@ namespace devtools {
|
||||
u64id_t connection;
|
||||
};
|
||||
|
||||
enum class BreakpointEventType {
|
||||
enum class DebuggingEventType {
|
||||
SET_BREAKPOINT = 1,
|
||||
REMOVE_BREAKPOINT,
|
||||
STEP,
|
||||
STEP_INTO_FUNCTION,
|
||||
RESUME,
|
||||
};
|
||||
struct BreakpointEvent {
|
||||
BreakpointEventType type;
|
||||
|
||||
struct BreakpointEventDto {
|
||||
std::string source;
|
||||
int line;
|
||||
};
|
||||
|
||||
struct SignalEventDto {
|
||||
};
|
||||
|
||||
struct DebuggingEvent {
|
||||
DebuggingEventType type;
|
||||
std::variant<BreakpointEventDto, SignalEventDto> data;
|
||||
};
|
||||
|
||||
class DebuggingServer {
|
||||
public:
|
||||
DebuggingServer(Engine& engine, const std::string& serverString);
|
||||
@ -55,13 +67,15 @@ namespace devtools {
|
||||
void onHitBreakpoint(dv::value&& stackTrace);
|
||||
|
||||
void setClient(u64id_t client);
|
||||
std::vector<BreakpointEvent> pullBreakpointEvents();
|
||||
std::vector<DebuggingEvent> pullEvents();
|
||||
private:
|
||||
Engine& engine;
|
||||
network::Server& server;
|
||||
std::unique_ptr<ClientConnection> connection;
|
||||
std::vector<BreakpointEvent> breakpointEvents;
|
||||
std::vector<DebuggingEvent> breakpointEvents;
|
||||
|
||||
bool performCommand(const std::string& type, const dv::value& map);
|
||||
bool performCommand(
|
||||
const std::string& type, const dv::value& map
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -284,11 +284,13 @@ void Engine::postUpdate() {
|
||||
scripting::process_post_runnables();
|
||||
|
||||
if (debuggingServer) {
|
||||
if (!debuggingServer->update()) {
|
||||
debuggingServer->update();
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::detachDebugger() {
|
||||
debuggingServer.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::updateFrontend() {
|
||||
double delta = time.getDelta();
|
||||
@ -317,10 +319,9 @@ void Engine::startPauseLoop() {
|
||||
input->toggleCursor();
|
||||
}
|
||||
}
|
||||
while (!isQuitSignal()) {
|
||||
while (!isQuitSignal() && debuggingServer) {
|
||||
network->update();
|
||||
if (!debuggingServer->update()) {
|
||||
debuggingServer.reset();
|
||||
if (debuggingServer->update()) {
|
||||
break;
|
||||
}
|
||||
if (isHeadless()) {
|
||||
|
||||
@ -190,4 +190,6 @@ public:
|
||||
devtools::DebuggingServer* getDebuggingServer() {
|
||||
return debuggingServer.get();
|
||||
}
|
||||
|
||||
void detachDebugger();
|
||||
};
|
||||
|
||||
@ -280,8 +280,11 @@ static int l_debug_breakpoint(lua::State* L) {
|
||||
}
|
||||
|
||||
static int l_debug_pull_events(lua::State* L) {
|
||||
if (auto server = engine->getDebuggingServer()) {
|
||||
auto events = server->pullBreakpointEvents();
|
||||
auto server = engine->getDebuggingServer();
|
||||
if (!server) {
|
||||
return 0;
|
||||
}
|
||||
auto events = server->pullEvents();
|
||||
if (events.empty()) {
|
||||
return 0;
|
||||
}
|
||||
@ -293,18 +296,18 @@ static int l_debug_pull_events(lua::State* L) {
|
||||
lua::pushinteger(L, static_cast<int>(event.type));
|
||||
lua::rawseti(L, 1);
|
||||
|
||||
lua::pushstring(L, event.source);
|
||||
if (auto dto = std::get_if<devtools::BreakpointEventDto>(&event.data)) {
|
||||
lua::pushstring(L, dto->source);
|
||||
lua::rawseti(L, 2);
|
||||
|
||||
lua::pushinteger(L, event.line);
|
||||
lua::pushinteger(L, dto->line);
|
||||
lua::rawseti(L, 3);
|
||||
}
|
||||
|
||||
lua::rawseti(L, i + 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initialize_libs_extends(lua::State* L) {
|
||||
if (lua::getglobal(L, "debug")) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user