debugger_dap: Support variables and setVariable requests

This commit is contained in:
kichikuou
2021-10-23 08:12:13 +09:00
parent 0793b57e3c
commit 40a4d8b2f6
5 changed files with 164 additions and 2 deletions
+12
View File
@@ -323,6 +323,18 @@ const char *dsym_source_line(struct debug_symbols *dsym, int page, int line) {
return info->lines[line];
}
int dsym_num_variables(struct debug_symbols *dsym) {
if (!dsym)
return 0;
return dsym->nr_vars;
}
const char *dsym_variable_name(struct debug_symbols *dsym, int i) {
if (!dsym || (unsigned)i >= dsym->nr_vars)
return NULL;
return dsym->variables[i];
}
int dsym_lookup_variable(struct debug_symbols *dsym, const char *name) {
if (!dsym || !dsym->variables)
return -1;
+2
View File
@@ -30,6 +30,8 @@ const char *dsym_page2src(struct debug_symbols *dsym, int page);
int dsym_line2addr(struct debug_symbols *dsym, int page, int line);
int dsym_addr2line(struct debug_symbols *dsym, int page, int addr);
const char *dsym_source_line(struct debug_symbols *dsym, int page, int line);
int dsym_num_variables(struct debug_symbols *dsym);
const char *dsym_variable_name(struct debug_symbols *dsym, int i);
int dsym_lookup_variable(struct debug_symbols *dsym, const char *name);
const char *dsym_addr2func(struct debug_symbols *dsym, int page, int addr);
boolean dsym_func2addr(struct debug_symbols *dsym, const char *name, int *inout_page, int *out_addr);
+145 -2
View File
@@ -32,10 +32,16 @@
#include "debugger_private.h"
#include "debug_symbol.h"
#include "system.h"
#include "nact.h"
#include "variable.h"
#define THREAD_ID 1
enum VariablesReference {
VREF_GLOBALS = 1,
VREF_STRINGS,
};
static boolean initialized = false;
static char *src_dir;
@@ -102,6 +108,7 @@ static void cmd_initialize(cJSON *args, cJSON *resp) {
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
cJSON_AddBoolToObject(body, "supportsConfigurationDoneRequest", true);
cJSON_AddBoolToObject(body, "supportsEvaluateForHovers", true);
cJSON_AddBoolToObject(body, "supportsSetVariable", true);
}
static void cmd_launch(cJSON *args, cJSON *resp) {
@@ -251,10 +258,142 @@ static void cmd_threads(cJSON *args, cJSON *resp) {
}
static void cmd_scopes(cJSON *args, cJSON *resp) {
cJSON *body;
cJSON *body, *scopes, *globals, *strings;
cJSON_AddBoolToObject(resp, "success", true);
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
cJSON_AddItemToObjectCS(body, "scopes", cJSON_CreateArray());
cJSON_AddItemToObjectCS(body, "scopes", scopes = cJSON_CreateArray());
cJSON_AddItemToArray(scopes, globals = cJSON_CreateObject());
cJSON_AddStringToObject(globals, "name", "All Variables");
cJSON_AddNumberToObject(globals, "variablesReference", VREF_GLOBALS);
cJSON_AddNumberToObject(globals, "namedVariables", dsym_num_variables(symbols));
cJSON_AddBoolToObject(globals, "expensive", false);
cJSON_AddItemToArray(scopes, strings = cJSON_CreateObject());
cJSON_AddStringToObject(strings, "name", "Strings");
cJSON_AddNumberToObject(strings, "variablesReference", VREF_STRINGS);
cJSON_AddNumberToObject(strings, "indexedVariables", svar_count() + 1);
cJSON_AddBoolToObject(strings, "expensive", false);
}
char *format_string_value(const char *str) {
char *utf = toUTF8(str);
char *new_value = malloc(strlen(utf) + 3);
sprintf(new_value, "\"%s\"", utf);
free(utf);
return new_value;
}
static void cmd_variables(cJSON *args, cJSON *resp) {
cJSON *start_ = cJSON_GetObjectItemCaseSensitive(args, "start");
cJSON *count_ = cJSON_GetObjectItemCaseSensitive(args, "count");
int start = cJSON_IsNumber(start_) ? start_->valueint : 0;
int count = cJSON_IsNumber(count_) ? count_->valueint : 65536;
cJSON *vref = cJSON_GetObjectItemCaseSensitive(args, "variablesReference");
if (cJSON_IsNumber(vref) && vref->valueint == VREF_GLOBALS) {
cJSON *body, *variables;
cJSON_AddBoolToObject(resp, "success", true);
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
cJSON_AddItemToObjectCS(body, "variables", variables = cJSON_CreateArray());
int end = dsym_num_variables(symbols);
if (end > start + count)
end = start + count;
for (int i = start; i < end; i++) {
cJSON *var = cJSON_CreateObject();
cJSON_AddItemToArray(variables, var);
cJSON_AddStringToObject(var, "name", dsym_variable_name(symbols, i));
char value[20];
sprintf(value, "%d", sysVar[i]);
cJSON_AddStringToObject(var, "value", value);
cJSON_AddNumberToObject(var, "variablesReference", 0);
}
} else if (cJSON_IsNumber(vref) && vref->valueint == VREF_STRINGS) {
cJSON *body, *variables;
cJSON_AddBoolToObject(resp, "success", true);
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
cJSON_AddItemToObjectCS(body, "variables", variables = cJSON_CreateArray());
if (start == 0) {
start++;
count--;
}
int end = svar_count() + 1;
if (end > start + count)
end = start + count;
for (int i = start; i < end; i++) {
char name[20];
cJSON *var = cJSON_CreateObject();
cJSON_AddItemToArray(variables, var);
sprintf(name, "[%d]", i);
cJSON_AddStringToObject(var, "name", name);
char *value = format_string_value(svar_get(i));
cJSON_AddStringToObject(var, "value", value);
free(value);
cJSON_AddNumberToObject(var, "variablesReference", 0);
}
} else {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "invalid variablesReference");
}
}
static void cmd_setVariable(cJSON *args, cJSON *resp) {
cJSON *name = cJSON_GetObjectItemCaseSensitive(args, "name");
cJSON *value = cJSON_GetObjectItemCaseSensitive(args, "value");
if (!cJSON_IsString(name) || !cJSON_IsString(value)) {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "invalid arguments");
return;
}
cJSON *vref = cJSON_GetObjectItemCaseSensitive(args, "variablesReference");
if (cJSON_IsNumber(vref) && vref->valueint == VREF_GLOBALS) {
int var = dbg_lookup_var(name->valuestring);
if (var < 0) {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "invalid variable name");
return;
}
int parsed_value;
if (sscanf(value->valuestring, "%i", &parsed_value) != 1) {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "syntax error");
return;
}
sysVar[var] = parsed_value & 0xffff;
cJSON *body;
cJSON_AddBoolToObject(resp, "success", true);
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
char new_value[20];
sprintf(new_value, "%d", sysVar[var]);
cJSON_AddStringToObject(body, "value", new_value);
} else if (cJSON_IsNumber(vref) && vref->valueint == VREF_STRINGS) {
int idx;
if (sscanf(name->valuestring, "[%d]", &idx) != 1 || idx < 1 || idx > svar_count()) {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "invalid string index");
return;
}
int len = strlen(value->valuestring);
if (len < 2 || value->valuestring[0] != '"' || value->valuestring[len-1] != '"') {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "syntax error");
return;
}
value->valuestring[len-1] = '\0';
char *str = fromUTF8(value->valuestring + 1);
svar_set(idx, str);
free(str);
cJSON *body;
cJSON_AddBoolToObject(resp, "success", true);
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
char *new_value = format_string_value(svar_get(idx));
cJSON_AddStringToObject(body, "value", new_value);
free(new_value);
} else {
cJSON_AddBoolToObject(resp, "success", false);
cJSON_AddStringToObject(resp, "message", "invalid variablesReference");
}
}
static void cmd_disconnect(cJSON *args, cJSON *resp) {
@@ -311,6 +450,10 @@ static boolean handle_request(cJSON *request) {
cmd_threads(args, resp);
} else if (!strcmp(command->valuestring, "scopes")) {
cmd_scopes(args, resp);
} else if (!strcmp(command->valuestring, "variables")) {
cmd_variables(args, resp);
} else if (!strcmp(command->valuestring, "setVariable")) {
cmd_setVariable(args, resp);
} else if (!strcmp(command->valuestring, "disconnect")) {
cmd_disconnect(args, resp);
} else {
+4
View File
@@ -111,6 +111,10 @@ extern void svar_init(int cnt, int len) {
strvar_len = len;
}
extern int svar_count(void) {
return strvar_cnt;
}
/* 変数の初期化 */
extern boolean v_initVars() {
strVar = calloc(STRVAR_MAX, sizeof(char *));
+1
View File
@@ -59,6 +59,7 @@ extern boolean v_getArrayBufferStatus(int page);
extern boolean v_initVars();
extern void svar_init(int cnt, int len);
extern int svar_count(void);
extern const char *svar_get(int no);
extern void svar_set(int no, const char *str);
extern void svar_copy(int dstno, int dstpos, int srcno, int srcpos, int len);