Skip to content

Commit

Permalink
threaded script debugger
Browse files Browse the repository at this point in the history
gdscript works
visual script was working, will be ported to extension
extension script needs work on extension API
C# works but needs more usage by dotnet6 port
  • Loading branch information
derammo committed Sep 13, 2022
1 parent 3fe3c43 commit 217f931
Show file tree
Hide file tree
Showing 55 changed files with 4,434 additions and 1,380 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ Generated\ Files/
*.pidb
*.svclog
*.scc
*.obj.enc

# Visual C++ cache files
ipch/
Expand Down
53 changes: 40 additions & 13 deletions core/debugger/debugger_marshalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,38 +32,65 @@

#include "core/io/marshalls.h"

#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() < (uint32_t)(expected), false, String("Malformed ") + what + " message from script debugger, message too short. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)(arr).size() < (uint32_t)(expected), false, String("Malformed ") + (what) + " message from script debugger, message too short. Expected size: " + itos(expected) + ", actual size: " + itos((arr).size()))
#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)(arr).size() > (uint32_t)(expected), false, String("Malformed ") + (what) + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos((arr).size()))

Array DebuggerMarshalls::ScriptStackDump::serialize() {
Array DebuggerMarshalls::ScriptStackDump::serialize() const {
Array arr;
arr.push_back(frames.size() * 3);
for (int i = 0; i < frames.size(); i++) {
arr.push_back(frames[i].file);
arr.push_back(frames[i].line);
arr.push_back(frames[i].func);
}
if (!tid.is_zero()) {
arr.push_back(tid);
}
return arr;
}

bool DebuggerMarshalls::ScriptStackDump::deserialize(const Array &p_arr) {
CHECK_SIZE(p_arr, 1, "ScriptStackDump");
uint32_t size = p_arr[0];
const uint32_t size = p_arr[0];
CHECK_SIZE(p_arr, size, "ScriptStackDump");
int idx = 1;
for (uint32_t i = 0; i < size / 3; i++) {
ScriptLanguage::StackInfo sf;
StackInfo sf;
sf.file = p_arr[idx];
sf.line = p_arr[idx + 1];
sf.func = p_arr[idx + 2];
frames.push_back(sf);
idx += 3;
}
if (idx == p_arr.size() - 1) {
// one extra data item is optional TID
tid = p_arr[idx];
++idx;
} else {
tid.zero();
}
CHECK_END(p_arr, idx, "ScriptStackDump");
return true;
}

Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
void DebuggerMarshalls::ScriptStackDump::populate(const ScriptLanguageThreadContext &p_context) {
tid = p_context.debug_get_thread_id();
const int slc = p_context.debug_get_stack_level_count();
for (int i = 0; i < slc; i++) {
StackInfo frame;
frame.file = p_context.debug_get_stack_level_source(i);
frame.line = p_context.debug_get_stack_level_line(i);
frame.func = p_context.debug_get_stack_level_function(i);
frames.push_back(frame);
}
}

void DebuggerMarshalls::ScriptStackDump::clear() {
tid = DebugThreadID();
frames.clear();
}

Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) const {
Array arr;
arr.push_back(name);
arr.push_back(type);
Expand All @@ -74,7 +101,7 @@ Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
}

int len = 0;
Error err = encode_variant(var, nullptr, len, true);
const Error err = encode_variant(var, nullptr, len, true);
if (err != OK) {
ERR_PRINT("Failed to encode variant.");
}
Expand All @@ -96,7 +123,7 @@ bool DebuggerMarshalls::ScriptStackVariable::deserialize(const Array &p_arr) {
return true;
}

Array DebuggerMarshalls::OutputError::serialize() {
Array DebuggerMarshalls::OutputError::serialize() const {
Array arr;
arr.push_back(hr);
arr.push_back(min);
Expand All @@ -108,8 +135,8 @@ Array DebuggerMarshalls::OutputError::serialize() {
arr.push_back(error);
arr.push_back(error_descr);
arr.push_back(warning);
unsigned int size = callstack.size();
const ScriptLanguage::StackInfo *r = callstack.ptr();
const unsigned int size = callstack.size();
const StackInfo *r = callstack.ptr();
arr.push_back(size * 3);
for (int i = 0; i < callstack.size(); i++) {
arr.push_back(r[i].file);
Expand All @@ -131,11 +158,11 @@ bool DebuggerMarshalls::OutputError::deserialize(const Array &p_arr) {
error = p_arr[7];
error_descr = p_arr[8];
warning = p_arr[9];
unsigned int stack_size = p_arr[10];
const unsigned int stack_size = p_arr[10];
CHECK_SIZE(p_arr, stack_size, "OutputError");
int idx = 11;
callstack.resize(stack_size / 3);
ScriptLanguage::StackInfo *w = callstack.ptrw();
callstack.resize(static_cast<int>(stack_size) / 3);
StackInfo *w = callstack.ptrw();
for (unsigned int i = 0; i < stack_size / 3; i++) {
w[i].file = p_arr[idx];
w[i].func = p_arr[idx + 1];
Expand Down
20 changes: 14 additions & 6 deletions core/debugger/debugger_marshalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,29 @@
#include "core/object/script_language.h"

struct DebuggerMarshalls {
using DebugThreadID = ScriptLanguageThreadContext::DebugThreadID;
using StackInfo = ScriptLanguageThreadContext::StackInfo;

struct ScriptStackVariable {
String name;
Variant value;
int type = -1;

Array serialize(int max_size = 1 << 20); // 1 MiB default.
Array serialize(int max_size = 1 << 20) const; // 1 MiB default.
bool deserialize(const Array &p_arr);
};

struct ScriptStackDump {
List<ScriptLanguage::StackInfo> frames;
ScriptStackDump() {}
DebugThreadID tid;
List<StackInfo> frames;

ScriptStackDump() = default;

Array serialize();
Array serialize() const;
bool deserialize(const Array &p_arr);

void populate(const ScriptLanguageThreadContext &p_context);
void clear();
};

struct OutputError {
Expand All @@ -62,9 +70,9 @@ struct DebuggerMarshalls {
String error;
String error_descr;
bool warning = false;
Vector<ScriptLanguage::StackInfo> callstack;
Vector<StackInfo> callstack;

Array serialize();
Array serialize() const;
bool deserialize(const Array &p_arr);
};
};
Expand Down
23 changes: 17 additions & 6 deletions core/debugger/engine_debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@
#include "core/templates/hash_map.h"
#include "core/templates/vector.h"
#include "core/variant/array.h"
#include "core/variant/variant.h"

class RemoteDebuggerPeer;
class ScriptDebugger;
class ScriptLanguageThreadContext;

class EngineDebugger {
public:
Expand All @@ -61,7 +61,8 @@ class EngineDebugger {
bool active = false;

public:
Profiler() {}
Profiler() = default;

Profiler(void *p_data, ProfilingToggle p_toggle, ProfilingAdd p_add, ProfilingTick p_tick) {
data = p_data;
toggle = p_toggle;
Expand All @@ -77,7 +78,8 @@ class EngineDebugger {
void *data = nullptr;

public:
Capture() {}
Capture() = default;

Capture(void *p_data, CaptureFunc p_capture) {
data = p_data;
capture = p_capture;
Expand Down Expand Up @@ -110,7 +112,7 @@ class EngineDebugger {

static void initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints, void (*p_allow_focus_steal_fn)());
static void deinitialize();
static void register_profiler(const StringName &p_name, const Profiler &p_profiler);
static void register_profiler(const StringName &p_name, const Profiler &p_func);
static void unregister_profiler(const StringName &p_name);
static bool is_profiling(const StringName &p_name);
static bool has_profiler(const StringName &p_name);
Expand All @@ -128,10 +130,19 @@ class EngineDebugger {

void line_poll();

virtual void poll_events(bool p_is_idle) {}
virtual void poll_events(bool) {}
virtual void send_message(const String &p_msg, const Array &p_data) = 0;
virtual void send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, bool p_editor_notify, ErrorHandlerType p_type) = 0;
virtual void debug(bool p_can_continue = true, bool p_is_error_breakpoint = false) = 0;

// Initiate new debugging session on the caller thread and block the caller for the duration.
virtual void debug(ScriptLanguageThreadContext &p_focused_thread) = 0;

// Notify that the caller thread would like to be selected for debugging,
// but debugger is busy with another thread.
virtual void request_debug(const ScriptLanguageThreadContext &p_any_thread) = 0;

// Notify that the specified thread is held and can be inquired for stack info, but don't block.
virtual void thread_paused(const ScriptLanguageThreadContext &p_any_thread) = 0;

virtual ~EngineDebugger();
};
Expand Down
Loading

0 comments on commit 217f931

Please sign in to comment.