| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- /*
- * Copyright (C) 2021 Ant Group. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #include "bh_platform.h"
- #include "handler.h"
- #include "debug_engine.h"
- #include "packets.h"
- #include "utils.h"
- #include "wasm_runtime.h"
- /*
- * Note: A moderate MAX_PACKET_SIZE is ok because
- * LLDB queries our buffer size (via qSupported PacketSize)
- * and limits packet sizes accordingly.
- */
- #if defined(DEBUG_MAX_PACKET_SIZE)
- #define MAX_PACKET_SIZE DEBUG_MAX_PACKET_SIZE
- #else
- #define MAX_PACKET_SIZE (4096)
- #endif
- /*
- * Note: It's assumed that MAX_PACKET_SIZE is reasonably large.
- * See GetWorkingDir, WasmCallStack, etc.
- */
- #if MAX_PACKET_SIZE < PATH_MAX || MAX_PACKET_SIZE < (2048 + 1)
- #error MAX_PACKET_SIZE is too small
- #endif
- static char *tmpbuf;
- static korp_mutex tmpbuf_lock;
- int
- wasm_debug_handler_init()
- {
- int ret;
- tmpbuf = wasm_runtime_malloc(MAX_PACKET_SIZE);
- if (tmpbuf == NULL) {
- LOG_ERROR("debug-engine: Packet buffer allocation failure");
- return BHT_ERROR;
- }
- ret = os_mutex_init(&tmpbuf_lock);
- if (ret != BHT_OK) {
- wasm_runtime_free(tmpbuf);
- tmpbuf = NULL;
- }
- return ret;
- }
- void
- wasm_debug_handler_deinit()
- {
- wasm_runtime_free(tmpbuf);
- tmpbuf = NULL;
- os_mutex_destroy(&tmpbuf_lock);
- }
- void
- handle_interrupt(WASMGDBServer *server)
- {
- wasm_debug_instance_interrupt_all_threads(server->thread->debug_instance);
- }
- void
- handle_general_set(WASMGDBServer *server, char *payload)
- {
- const char *name;
- char *args;
- args = strchr(payload, ':');
- if (args)
- *args++ = '\0';
- name = payload;
- LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
- if (!strcmp(name, "StartNoAckMode")) {
- server->noack = true;
- write_packet(server, "OK");
- }
- if (!strcmp(name, "ThreadSuffixSupported")) {
- write_packet(server, "");
- }
- if (!strcmp(name, "ListThreadsInStopReply")) {
- write_packet(server, "");
- }
- if (!strcmp(name, "EnableErrorStrings")) {
- write_packet(server, "OK");
- }
- }
- static void
- process_xfer(WASMGDBServer *server, const char *name, char *args)
- {
- const char *mode = args;
- args = strchr(args, ':');
- if (args)
- *args++ = '\0';
- if (!strcmp(name, "libraries") && !strcmp(mode, "read")) {
- // TODO: how to get current wasm file name?
- uint64 addr = wasm_debug_instance_get_load_addr(
- (WASMDebugInstance *)server->thread->debug_instance);
- os_mutex_lock(&tmpbuf_lock);
- #if WASM_ENABLE_LIBC_WASI != 0
- char objname[128];
- if (!wasm_debug_instance_get_current_object_name(
- (WASMDebugInstance *)server->thread->debug_instance, objname,
- 128)) {
- objname[0] = 0; /* use an empty string */
- }
- snprintf(tmpbuf, MAX_PACKET_SIZE,
- "l<library-list><library name=\"%s\"><section "
- "address=\"0x%" PRIx64 "\"/></library></library-list>",
- objname, addr);
- #else
- snprintf(tmpbuf, MAX_PACKET_SIZE,
- "l<library-list><library name=\"%s\"><section "
- "address=\"0x%" PRIx64 "\"/></library></library-list>",
- "nobody.wasm", addr);
- #endif
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- }
- void
- process_wasm_local(WASMGDBServer *server, char *args)
- {
- int32 frame_index;
- int32 local_index;
- char buf[16];
- int32 size = 16;
- bool ret;
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "E01");
- if (sscanf(args, "%" PRId32 ";%" PRId32, &frame_index, &local_index) == 2) {
- ret = wasm_debug_instance_get_local(
- (WASMDebugInstance *)server->thread->debug_instance, frame_index,
- local_index, buf, &size);
- if (ret && size > 0) {
- mem2hex(buf, tmpbuf, size);
- }
- }
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- void
- process_wasm_global(WASMGDBServer *server, char *args)
- {
- int32 frame_index;
- int32 global_index;
- char buf[16];
- int32 size = 16;
- bool ret;
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "E01");
- if (sscanf(args, "%" PRId32 ";%" PRId32, &frame_index, &global_index)
- == 2) {
- ret = wasm_debug_instance_get_global(
- (WASMDebugInstance *)server->thread->debug_instance, frame_index,
- global_index, buf, &size);
- if (ret && size > 0) {
- mem2hex(buf, tmpbuf, size);
- }
- }
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- void
- handle_general_query(WASMGDBServer *server, char *payload)
- {
- const char *name;
- char *args;
- char triple[256];
- args = strchr(payload, ':');
- if (args)
- *args++ = '\0';
- name = payload;
- LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
- if (!strcmp(name, "C")) {
- uint64 pid, tid;
- pid = wasm_debug_instance_get_pid(
- (WASMDebugInstance *)server->thread->debug_instance);
- tid = (uint64)(uintptr_t)wasm_debug_instance_get_tid(
- (WASMDebugInstance *)server->thread->debug_instance);
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "QCp%" PRIx64 ".%" PRIx64 "", pid,
- tid);
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- if (!strcmp(name, "Supported")) {
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE,
- "qXfer:libraries:read+;PacketSize=%" PRIx32 ";",
- MAX_PACKET_SIZE);
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- if (!strcmp(name, "Xfer")) {
- name = args;
- if (!args) {
- LOG_ERROR("payload parse error during handle_general_query");
- return;
- }
- args = strchr(args, ':');
- if (args) {
- *args++ = '\0';
- process_xfer(server, name, args);
- }
- }
- if (!strcmp(name, "HostInfo")) {
- mem2hex("wasm32-wamr-wasi-wasm", triple,
- strlen("wasm32-wamr-wasi-wasm"));
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE,
- "vendor:wamr;ostype:wasi;arch:wasm32;"
- "triple:%s;endian:little;ptrsize:4;",
- triple);
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- if (!strcmp(name, "ModuleInfo")) {
- write_packet(server, "");
- }
- if (!strcmp(name, "GetWorkingDir")) {
- os_mutex_lock(&tmpbuf_lock);
- if (getcwd(tmpbuf, PATH_MAX))
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- if (!strcmp(name, "QueryGDBServer")) {
- write_packet(server, "");
- }
- if (!strcmp(name, "VAttachOrWaitSupported")) {
- write_packet(server, "");
- }
- if (!strcmp(name, "ProcessInfo")) {
- // Todo: process id parent-pid
- uint64 pid;
- pid = wasm_debug_instance_get_pid(
- (WASMDebugInstance *)server->thread->debug_instance);
- mem2hex("wasm32-wamr-wasi-wasm", triple,
- strlen("wasm32-wamr-wasi-wasm"));
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE,
- "pid:%" PRIx64 ";parent-pid:%" PRIx64
- ";vendor:wamr;ostype:wasi;arch:wasm32;"
- "triple:%s;endian:little;ptrsize:4;",
- pid, pid, triple);
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- if (!strcmp(name, "RegisterInfo0")) {
- os_mutex_lock(&tmpbuf_lock);
- snprintf(
- tmpbuf, MAX_PACKET_SIZE,
- "name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;"
- "set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;");
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- else if (!strncmp(name, "RegisterInfo", strlen("RegisterInfo"))) {
- write_packet(server, "E45");
- }
- if (!strcmp(name, "StructuredDataPlugins")) {
- write_packet(server, "");
- }
- if (args && (!strcmp(name, "MemoryRegionInfo"))) {
- uint64 addr = strtoll(args, NULL, 16);
- WASMDebugMemoryInfo *mem_info = wasm_debug_instance_get_memregion(
- (WASMDebugInstance *)server->thread->debug_instance, addr);
- if (mem_info) {
- char name_buf[256];
- mem2hex(mem_info->name, name_buf, strlen(mem_info->name));
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE,
- "start:%" PRIx64 ";size:%" PRIx64
- ";permissions:%s;name:%s;",
- (uint64)mem_info->start, mem_info->size,
- mem_info->permisson, name_buf);
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- wasm_debug_instance_destroy_memregion(
- (WASMDebugInstance *)server->thread->debug_instance, mem_info);
- }
- }
- if (!strcmp(name, "WasmData")) {
- write_packet(server, "");
- }
- if (!strcmp(name, "WasmMem")) {
- write_packet(server, "");
- }
- if (!strcmp(name, "Symbol")) {
- write_packet(server, "");
- }
- if (args && (!strcmp(name, "WasmCallStack"))) {
- uint64 tid = strtoll(args, NULL, 16);
- uint64 buf[1024 / sizeof(uint64)];
- uint32 count = wasm_debug_instance_get_call_stack_pcs(
- (WASMDebugInstance *)server->thread->debug_instance,
- (korp_tid)(uintptr_t)tid, buf, 1024 / sizeof(uint64));
- if (count > 0) {
- os_mutex_lock(&tmpbuf_lock);
- mem2hex((char *)buf, tmpbuf, count * sizeof(uint64));
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- else
- write_packet(server, "");
- }
- if (args && (!strcmp(name, "WasmLocal"))) {
- process_wasm_local(server, args);
- }
- if (args && (!strcmp(name, "WasmGlobal"))) {
- process_wasm_global(server, args);
- }
- if (!strcmp(name, "Offsets")) {
- write_packet(server, "");
- }
- if (!strncmp(name, "ThreadStopInfo", strlen("ThreadStopInfo"))) {
- int32 prefix_len = strlen("ThreadStopInfo");
- uint64 tid_number = strtoll(name + prefix_len, NULL, 16);
- korp_tid tid = (korp_tid)(uintptr_t)tid_number;
- uint32 status;
- status = wasm_debug_instance_get_thread_status(
- server->thread->debug_instance, tid);
- send_thread_stop_status(server, status, tid);
- }
- if (!strcmp(name, "WatchpointSupportInfo")) {
- os_mutex_lock(&tmpbuf_lock);
- // Any uint32 is OK for the watchpoint support
- snprintf(tmpbuf, MAX_PACKET_SIZE, "num:32;");
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- }
- void
- send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
- {
- int32 len = 0;
- uint64 pc;
- korp_tid tids[20];
- char pc_string[17];
- uint32 tids_count, i = 0;
- uint32 gdb_status = status;
- WASMExecEnv *exec_env;
- const char *exception;
- if (status == 0) {
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "W%02x", status);
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- return;
- }
- tids_count = wasm_debug_instance_get_tids(
- (WASMDebugInstance *)server->thread->debug_instance, tids, 20);
- pc = wasm_debug_instance_get_pc(
- (WASMDebugInstance *)server->thread->debug_instance);
- if (status == WAMR_SIG_SINGSTEP) {
- gdb_status = WAMR_SIG_TRAP;
- }
- os_mutex_lock(&tmpbuf_lock);
- // TODO: how name a wasm thread?
- len += snprintf(tmpbuf, MAX_PACKET_SIZE, "T%02xthread:%" PRIx64 ";name:%s;",
- gdb_status, (uint64)(uintptr_t)tid, "nobody");
- if (tids_count > 0) {
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, "threads:");
- while (i < tids_count) {
- if (i == tids_count - 1)
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
- "%" PRIx64 ";", (uint64)(uintptr_t)tids[i]);
- else
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
- "%" PRIx64 ",", (uint64)(uintptr_t)tids[i]);
- i++;
- }
- }
- mem2hex((void *)&pc, pc_string, 8);
- pc_string[8 * 2] = '\0';
- exec_env = wasm_debug_instance_get_current_env(
- (WASMDebugInstance *)server->thread->debug_instance);
- bh_assert(exec_env);
- exception =
- wasm_runtime_get_exception(wasm_runtime_get_module_inst(exec_env));
- if (exception) {
- /* When exception occurs, use reason:exception so the description can be
- * correctly processed by LLDB */
- uint32 exception_len = strlen(exception);
- len +=
- snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
- "thread-pcs:%" PRIx64 ";00:%s;reason:%s;description:", pc,
- pc_string, "exception");
- /* The description should be encoded as HEX */
- for (i = 0; i < exception_len; i++) {
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, "%02x",
- exception[i]);
- }
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len, ";");
- }
- else {
- if (status == WAMR_SIG_TRAP) {
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
- "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
- pc_string, "breakpoint");
- }
- else if (status == WAMR_SIG_SINGSTEP) {
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
- "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
- pc_string, "trace");
- }
- else { /* status > 0 (== 0 is checked at the function beginning) */
- len += snprintf(tmpbuf + len, MAX_PACKET_SIZE - len,
- "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
- pc_string, "signal");
- }
- }
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- void
- handle_v_packet(WASMGDBServer *server, char *payload)
- {
- const char *name;
- char *args;
- args = strchr(payload, ';');
- if (args)
- *args++ = '\0';
- name = payload;
- LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
- if (!strcmp("Cont?", name))
- write_packet(server, "vCont;c;C;s;S;");
- if (!strcmp("Cont", name)) {
- if (args) {
- if (args[0] == 's' || args[0] == 'c') {
- char *numstring = strchr(args, ':');
- if (numstring) {
- uint64 tid_number;
- korp_tid tid;
- *numstring++ = '\0';
- tid_number = strtoll(numstring, NULL, 16);
- tid = (korp_tid)(uintptr_t)tid_number;
- wasm_debug_instance_set_cur_thread(
- (WASMDebugInstance *)server->thread->debug_instance,
- tid);
- if (args[0] == 's') {
- wasm_debug_instance_singlestep(
- (WASMDebugInstance *)server->thread->debug_instance,
- tid);
- }
- else {
- wasm_debug_instance_continue(
- (WASMDebugInstance *)
- server->thread->debug_instance);
- }
- }
- }
- }
- }
- }
- void
- handle_threadstop_request(WASMGDBServer *server, char *payload)
- {
- korp_tid tid;
- uint32 status;
- WASMDebugInstance *debug_inst =
- (WASMDebugInstance *)server->thread->debug_instance;
- bh_assert(debug_inst);
- /* According to
- https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#Packets, the "?"
- package should be sent when connection is first established to query the
- reason the target halted */
- bh_assert(debug_inst->current_state == DBG_LAUNCHING);
- /* Waiting for the stop event */
- os_mutex_lock(&debug_inst->wait_lock);
- while (!debug_inst->stopped_thread) {
- os_cond_wait(&debug_inst->wait_cond, &debug_inst->wait_lock);
- }
- os_mutex_unlock(&debug_inst->wait_lock);
- tid = debug_inst->stopped_thread->handle;
- status = (uint32)debug_inst->stopped_thread->current_status->signal_flag;
- wasm_debug_instance_set_cur_thread(debug_inst, tid);
- send_thread_stop_status(server, status, tid);
- debug_inst->current_state = APP_STOPPED;
- debug_inst->stopped_thread = NULL;
- }
- void
- handle_set_current_thread(WASMGDBServer *server, char *payload)
- {
- LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
- if ('g' == *payload++) {
- uint64 tid = strtoll(payload, NULL, 16);
- if (tid > 0)
- wasm_debug_instance_set_cur_thread(
- (WASMDebugInstance *)server->thread->debug_instance,
- (korp_tid)(uintptr_t)tid);
- }
- write_packet(server, "OK");
- }
- void
- handle_get_register(WASMGDBServer *server, char *payload)
- {
- uint64 regdata;
- int32 i = strtol(payload, NULL, 16);
- if (i != 0) {
- write_packet(server, "E01");
- return;
- }
- regdata = wasm_debug_instance_get_pc(
- (WASMDebugInstance *)server->thread->debug_instance);
- os_mutex_lock(&tmpbuf_lock);
- mem2hex((void *)®data, tmpbuf, 8);
- tmpbuf[8 * 2] = '\0';
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- void
- handle_get_json_request(WASMGDBServer *server, char *payload)
- {
- char *args;
- args = strchr(payload, ':');
- if (args)
- *args++ = '\0';
- write_packet(server, "");
- }
- void
- handle_get_read_binary_memory(WASMGDBServer *server, char *payload)
- {
- write_packet(server, "");
- }
- void
- handle_get_read_memory(WASMGDBServer *server, char *payload)
- {
- uint64 maddr, mlen;
- bool ret;
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "%s", "");
- if (sscanf(payload, "%" SCNx64 ",%" SCNx64, &maddr, &mlen) == 2) {
- char *buff;
- if (mlen * 2 > MAX_PACKET_SIZE) {
- LOG_ERROR("Buffer overflow!");
- mlen = MAX_PACKET_SIZE / 2;
- }
- buff = wasm_runtime_malloc(mlen);
- if (buff) {
- ret = wasm_debug_instance_get_mem(
- (WASMDebugInstance *)server->thread->debug_instance, maddr,
- buff, &mlen);
- if (ret) {
- mem2hex(buff, tmpbuf, mlen);
- }
- wasm_runtime_free(buff);
- }
- }
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- void
- handle_get_write_memory(WASMGDBServer *server, char *payload)
- {
- size_t hex_len;
- int32 offset, act_len;
- uint64 maddr, mlen;
- char *buff;
- bool ret;
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "%s", "");
- if (sscanf(payload, "%" SCNx64 ",%" SCNx64 ":%n", &maddr, &mlen, &offset)
- == 2) {
- payload += offset;
- hex_len = strlen(payload);
- act_len = hex_len / 2 < mlen ? hex_len / 2 : mlen;
- buff = wasm_runtime_malloc(act_len);
- if (buff) {
- hex2mem(payload, buff, act_len);
- ret = wasm_debug_instance_set_mem(
- (WASMDebugInstance *)server->thread->debug_instance, maddr,
- buff, &mlen);
- if (ret) {
- snprintf(tmpbuf, MAX_PACKET_SIZE, "%s", "OK");
- }
- wasm_runtime_free(buff);
- }
- }
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- void
- handle_breakpoint_software_add(WASMGDBServer *server, uint64 addr,
- size_t length)
- {
- bool ret = wasm_debug_instance_add_breakpoint(
- (WASMDebugInstance *)server->thread->debug_instance, addr, length);
- write_packet(server, ret ? "OK" : "EO1");
- }
- void
- handle_breakpoint_software_remove(WASMGDBServer *server, uint64 addr,
- size_t length)
- {
- bool ret = wasm_debug_instance_remove_breakpoint(
- (WASMDebugInstance *)server->thread->debug_instance, addr, length);
- write_packet(server, ret ? "OK" : "EO1");
- }
- void
- handle_watchpoint_write_add(WASMGDBServer *server, uint64 addr, size_t length)
- {
- bool ret = wasm_debug_instance_watchpoint_write_add(
- (WASMDebugInstance *)server->thread->debug_instance, addr, length);
- write_packet(server, ret ? "OK" : "EO1");
- }
- void
- handle_watchpoint_write_remove(WASMGDBServer *server, uint64 addr,
- size_t length)
- {
- bool ret = wasm_debug_instance_watchpoint_write_remove(
- (WASMDebugInstance *)server->thread->debug_instance, addr, length);
- write_packet(server, ret ? "OK" : "EO1");
- }
- void
- handle_watchpoint_read_add(WASMGDBServer *server, uint64 addr, size_t length)
- {
- bool ret = wasm_debug_instance_watchpoint_read_add(
- (WASMDebugInstance *)server->thread->debug_instance, addr, length);
- write_packet(server, ret ? "OK" : "EO1");
- }
- void
- handle_watchpoint_read_remove(WASMGDBServer *server, uint64 addr, size_t length)
- {
- bool ret = wasm_debug_instance_watchpoint_read_remove(
- (WASMDebugInstance *)server->thread->debug_instance, addr, length);
- write_packet(server, ret ? "OK" : "EO1");
- }
- void
- handle_add_break(WASMGDBServer *server, char *payload)
- {
- int arg_c;
- size_t type, length;
- uint64 addr;
- if ((arg_c = sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length))
- != 3) {
- LOG_ERROR("Unsupported number of add break arguments %d", arg_c);
- write_packet(server, "");
- return;
- }
- switch (type) {
- case eBreakpointSoftware:
- handle_breakpoint_software_add(server, addr, length);
- break;
- case eWatchpointWrite:
- handle_watchpoint_write_add(server, addr, length);
- break;
- case eWatchpointRead:
- handle_watchpoint_read_add(server, addr, length);
- break;
- case eWatchpointReadWrite:
- handle_watchpoint_write_add(server, addr, length);
- handle_watchpoint_read_add(server, addr, length);
- break;
- default:
- LOG_ERROR("Unsupported breakpoint type %zu", type);
- write_packet(server, "");
- break;
- }
- }
- void
- handle_remove_break(WASMGDBServer *server, char *payload)
- {
- int arg_c;
- size_t type, length;
- uint64 addr;
- if ((arg_c = sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length))
- != 3) {
- LOG_ERROR("Unsupported number of remove break arguments %d", arg_c);
- write_packet(server, "");
- return;
- }
- switch (type) {
- case eBreakpointSoftware:
- handle_breakpoint_software_remove(server, addr, length);
- break;
- case eWatchpointWrite:
- handle_watchpoint_write_remove(server, addr, length);
- break;
- case eWatchpointRead:
- handle_watchpoint_read_remove(server, addr, length);
- break;
- case eWatchpointReadWrite:
- handle_watchpoint_write_remove(server, addr, length);
- handle_watchpoint_read_remove(server, addr, length);
- break;
- default:
- LOG_ERROR("Unsupported breakpoint type %zu", type);
- write_packet(server, "");
- break;
- }
- }
- void
- handle_continue_request(WASMGDBServer *server, char *payload)
- {
- wasm_debug_instance_continue(
- (WASMDebugInstance *)server->thread->debug_instance);
- }
- void
- handle_kill_request(WASMGDBServer *server, char *payload)
- {
- wasm_debug_instance_kill(
- (WASMDebugInstance *)server->thread->debug_instance);
- }
- static void
- handle_malloc(WASMGDBServer *server, char *payload)
- {
- char *args;
- uint64 addr, size;
- int32 map_prot = MMAP_PROT_NONE;
- args = strstr(payload, ",");
- if (args) {
- *args++ = '\0';
- }
- else {
- LOG_ERROR("Payload parse error during handle malloc");
- return;
- }
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "%s", "E03");
- size = strtoll(payload, NULL, 16);
- if (size > 0) {
- while (*args) {
- if (*args == 'r') {
- map_prot |= MMAP_PROT_READ;
- }
- if (*args == 'w') {
- map_prot |= MMAP_PROT_WRITE;
- }
- if (*args == 'x') {
- map_prot |= MMAP_PROT_EXEC;
- }
- args++;
- }
- addr = wasm_debug_instance_mmap(
- (WASMDebugInstance *)server->thread->debug_instance, size,
- map_prot);
- if (addr) {
- snprintf(tmpbuf, MAX_PACKET_SIZE, "%" PRIx64, addr);
- }
- }
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- static void
- handle_free(WASMGDBServer *server, char *payload)
- {
- uint64 addr;
- bool ret;
- os_mutex_lock(&tmpbuf_lock);
- snprintf(tmpbuf, MAX_PACKET_SIZE, "%s", "E03");
- addr = strtoll(payload, NULL, 16);
- ret = wasm_debug_instance_ummap(
- (WASMDebugInstance *)server->thread->debug_instance, addr);
- if (ret) {
- snprintf(tmpbuf, MAX_PACKET_SIZE, "%s", "OK");
- }
- write_packet(server, tmpbuf);
- os_mutex_unlock(&tmpbuf_lock);
- }
- void
- handle____request(WASMGDBServer *server, char *payload)
- {
- char *args;
- if (payload[0] == 'M') {
- args = payload + 1;
- handle_malloc(server, args);
- }
- if (payload[0] == 'm') {
- args = payload + 1;
- handle_free(server, args);
- }
- }
- void
- handle_detach_request(WASMGDBServer *server, char *payload)
- {
- if (payload != NULL) {
- write_packet(server, "OK");
- }
- wasm_debug_instance_detach(
- (WASMDebugInstance *)server->thread->debug_instance);
- }
|