mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-08 20:56:13 +00:00
Add memory watchpoint support for source debugger (#1762)
Allow to add watchpoints to variables for source debugging. For instance: `breakpoint set variable var` will pause WAMR execution when the address at var is written to. Can also set read/write watchpoints by passing r/w flags. This will pause execution when the address at var is read: `watchpoint set variable -w read var` Add two linked lists for read/write watchpoints. When the debug message handler receives a watchpoint request, it adds/removes to one/both of these lists. In the interpreter, when an address is read or stored to, check whether the address is in these lists. If so, throw a sigtrap and suspend the process.
This commit is contained in:
parent
9d52960e4d
commit
c3d66f916e
|
@ -70,6 +70,35 @@ typedef float64 CellType_F64;
|
||||||
goto unaligned_atomic; \
|
goto unaligned_atomic; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
|
#define TRIGGER_WATCHPOINT_SIGTRAP() \
|
||||||
|
do { \
|
||||||
|
wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP); \
|
||||||
|
CHECK_SUSPEND_FLAGS(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CHECK_WATCHPOINT(list, current_addr) \
|
||||||
|
do { \
|
||||||
|
WASMDebugWatchPoint *watchpoint = bh_list_first_elem(list); \
|
||||||
|
while (watchpoint) { \
|
||||||
|
WASMDebugWatchPoint *next = bh_list_elem_next(watchpoint); \
|
||||||
|
if (watchpoint->addr <= current_addr \
|
||||||
|
&& watchpoint->addr + watchpoint->length > current_addr) { \
|
||||||
|
TRIGGER_WATCHPOINT_SIGTRAP(); \
|
||||||
|
} \
|
||||||
|
watchpoint = next; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CHECK_READ_WATCHPOINT(addr, offset) \
|
||||||
|
CHECK_WATCHPOINT(watch_point_list_read, WASM_ADDR_OFFSET(addr + offset))
|
||||||
|
#define CHECK_WRITE_WATCHPOINT(addr, offset) \
|
||||||
|
CHECK_WATCHPOINT(watch_point_list_write, WASM_ADDR_OFFSET(addr + offset))
|
||||||
|
#else
|
||||||
|
#define CHECK_READ_WATCHPOINT(addr, offset)
|
||||||
|
#define CHECK_WRITE_WATCHPOINT(addr, offset)
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline uint32
|
static inline uint32
|
||||||
rotl32(uint32 n, uint32 c)
|
rotl32(uint32 n, uint32 c)
|
||||||
{
|
{
|
||||||
|
@ -1127,6 +1156,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
|
|
||||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||||
uint8 *frame_ip_orig = NULL;
|
uint8 *frame_ip_orig = NULL;
|
||||||
|
WASMDebugInstance *debug_instance = wasm_exec_env_get_instance(exec_env);
|
||||||
|
bh_list *watch_point_list_read = &debug_instance->watch_point_list_read;
|
||||||
|
bh_list *watch_point_list_write = &debug_instance->watch_point_list_write;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||||
|
@ -1792,6 +1824,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(4);
|
CHECK_MEMORY_OVERFLOW(4);
|
||||||
PUSH_I32(LOAD_I32(maddr));
|
PUSH_I32(LOAD_I32(maddr));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1806,6 +1839,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(8);
|
CHECK_MEMORY_OVERFLOW(8);
|
||||||
PUSH_I64(LOAD_I64(maddr));
|
PUSH_I64(LOAD_I64(maddr));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1819,6 +1853,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(1);
|
CHECK_MEMORY_OVERFLOW(1);
|
||||||
PUSH_I32(sign_ext_8_32(*(int8 *)maddr));
|
PUSH_I32(sign_ext_8_32(*(int8 *)maddr));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1832,6 +1867,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(1);
|
CHECK_MEMORY_OVERFLOW(1);
|
||||||
PUSH_I32((uint32)(*(uint8 *)maddr));
|
PUSH_I32((uint32)(*(uint8 *)maddr));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1845,6 +1881,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(2);
|
CHECK_MEMORY_OVERFLOW(2);
|
||||||
PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
|
PUSH_I32(sign_ext_16_32(LOAD_I16(maddr)));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1858,6 +1895,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(2);
|
CHECK_MEMORY_OVERFLOW(2);
|
||||||
PUSH_I32((uint32)(LOAD_U16(maddr)));
|
PUSH_I32((uint32)(LOAD_U16(maddr)));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1871,6 +1909,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(1);
|
CHECK_MEMORY_OVERFLOW(1);
|
||||||
PUSH_I64(sign_ext_8_64(*(int8 *)maddr));
|
PUSH_I64(sign_ext_8_64(*(int8 *)maddr));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1884,6 +1923,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(1);
|
CHECK_MEMORY_OVERFLOW(1);
|
||||||
PUSH_I64((uint64)(*(uint8 *)maddr));
|
PUSH_I64((uint64)(*(uint8 *)maddr));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1897,6 +1937,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(2);
|
CHECK_MEMORY_OVERFLOW(2);
|
||||||
PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
|
PUSH_I64(sign_ext_16_64(LOAD_I16(maddr)));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1910,6 +1951,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(2);
|
CHECK_MEMORY_OVERFLOW(2);
|
||||||
PUSH_I64((uint64)(LOAD_U16(maddr)));
|
PUSH_I64((uint64)(LOAD_U16(maddr)));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1924,6 +1966,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(4);
|
CHECK_MEMORY_OVERFLOW(4);
|
||||||
PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
|
PUSH_I64(sign_ext_32_64(LOAD_I32(maddr)));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1937,6 +1980,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(4);
|
CHECK_MEMORY_OVERFLOW(4);
|
||||||
PUSH_I64((uint64)(LOAD_U32(maddr)));
|
PUSH_I64((uint64)(LOAD_U32(maddr)));
|
||||||
|
CHECK_READ_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1953,6 +1997,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
addr = POP_I32();
|
addr = POP_I32();
|
||||||
CHECK_MEMORY_OVERFLOW(4);
|
CHECK_MEMORY_OVERFLOW(4);
|
||||||
STORE_U32(maddr, frame_sp[1]);
|
STORE_U32(maddr, frame_sp[1]);
|
||||||
|
CHECK_WRITE_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1969,6 +2014,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
CHECK_MEMORY_OVERFLOW(8);
|
CHECK_MEMORY_OVERFLOW(8);
|
||||||
PUT_I64_TO_ADDR((uint32 *)maddr,
|
PUT_I64_TO_ADDR((uint32 *)maddr,
|
||||||
GET_I64_FROM_ADDR(frame_sp + 1));
|
GET_I64_FROM_ADDR(frame_sp + 1));
|
||||||
|
CHECK_WRITE_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -1993,7 +2039,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
CHECK_MEMORY_OVERFLOW(2);
|
CHECK_MEMORY_OVERFLOW(2);
|
||||||
STORE_U16(maddr, (uint16)sval);
|
STORE_U16(maddr, (uint16)sval);
|
||||||
}
|
}
|
||||||
|
CHECK_WRITE_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
@ -2023,6 +2069,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
CHECK_MEMORY_OVERFLOW(4);
|
CHECK_MEMORY_OVERFLOW(4);
|
||||||
STORE_U32(maddr, (uint32)sval);
|
STORE_U32(maddr, (uint32)sval);
|
||||||
}
|
}
|
||||||
|
CHECK_WRITE_WATCHPOINT(addr, offset);
|
||||||
(void)flags;
|
(void)flags;
|
||||||
HANDLE_OP_END();
|
HANDLE_OP_END();
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,6 +392,8 @@ wasm_debug_instance_create(WASMCluster *cluster, int32 port)
|
||||||
}
|
}
|
||||||
|
|
||||||
bh_list_init(&instance->break_point_list);
|
bh_list_init(&instance->break_point_list);
|
||||||
|
bh_list_init(&instance->watch_point_list_read);
|
||||||
|
bh_list_init(&instance->watch_point_list_write);
|
||||||
|
|
||||||
instance->cluster = cluster;
|
instance->cluster = cluster;
|
||||||
exec_env = bh_list_first_elem(&cluster->exec_env_list);
|
exec_env = bh_list_first_elem(&cluster->exec_env_list);
|
||||||
|
@ -452,6 +454,23 @@ wasm_debug_instance_destroy_breakpoints(WASMDebugInstance *instance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wasm_debug_instance_destroy_watchpoints(WASMDebugInstance *instance,
|
||||||
|
bh_list *watchpoints)
|
||||||
|
{
|
||||||
|
WASMDebugWatchPoint *watchpoint, *next;
|
||||||
|
|
||||||
|
watchpoint = bh_list_first_elem(watchpoints);
|
||||||
|
while (watchpoint) {
|
||||||
|
next = bh_list_elem_next(watchpoint);
|
||||||
|
|
||||||
|
bh_list_remove(watchpoints, watchpoint);
|
||||||
|
wasm_runtime_free(watchpoint);
|
||||||
|
|
||||||
|
watchpoint = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_debug_instance_destroy(WASMCluster *cluster)
|
wasm_debug_instance_destroy(WASMCluster *cluster)
|
||||||
{
|
{
|
||||||
|
@ -472,6 +491,10 @@ wasm_debug_instance_destroy(WASMCluster *cluster)
|
||||||
|
|
||||||
/* destroy all breakpoints */
|
/* destroy all breakpoints */
|
||||||
wasm_debug_instance_destroy_breakpoints(instance);
|
wasm_debug_instance_destroy_breakpoints(instance);
|
||||||
|
wasm_debug_instance_destroy_watchpoints(
|
||||||
|
instance, &instance->watch_point_list_read);
|
||||||
|
wasm_debug_instance_destroy_watchpoints(
|
||||||
|
instance, &instance->watch_point_list_write);
|
||||||
|
|
||||||
os_mutex_destroy(&instance->wait_lock);
|
os_mutex_destroy(&instance->wait_lock);
|
||||||
os_cond_destroy(&instance->wait_cond);
|
os_cond_destroy(&instance->wait_cond);
|
||||||
|
@ -995,6 +1018,65 @@ wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
add_watchpoint(bh_list *list, uint64 addr, uint64 length)
|
||||||
|
{
|
||||||
|
WASMDebugWatchPoint *watchpoint;
|
||||||
|
if (!(watchpoint = wasm_runtime_malloc(sizeof(WASMDebugWatchPoint)))) {
|
||||||
|
LOG_ERROR("WASM Debug Engine error: failed to allocate memory for "
|
||||||
|
"watchpoint");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memset(watchpoint, 0, sizeof(WASMDebugWatchPoint));
|
||||||
|
watchpoint->addr = addr;
|
||||||
|
watchpoint->length = length;
|
||||||
|
bh_list_insert(list, watchpoint);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
remove_watchpoint(bh_list *list, uint64 addr, uint64 length)
|
||||||
|
{
|
||||||
|
WASMDebugWatchPoint *watchpoint = bh_list_first_elem(list);
|
||||||
|
while (watchpoint) {
|
||||||
|
WASMDebugWatchPoint *next = bh_list_elem_next(watchpoint);
|
||||||
|
if (watchpoint->addr == addr && watchpoint->length == length) {
|
||||||
|
bh_list_remove(list, watchpoint);
|
||||||
|
wasm_runtime_free(watchpoint);
|
||||||
|
}
|
||||||
|
watchpoint = next;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_write_add(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length)
|
||||||
|
{
|
||||||
|
return add_watchpoint(&instance->watch_point_list_write, addr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_write_remove(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length)
|
||||||
|
{
|
||||||
|
return remove_watchpoint(&instance->watch_point_list_write, addr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_read_add(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length)
|
||||||
|
{
|
||||||
|
return add_watchpoint(&instance->watch_point_list_read, addr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_read_remove(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length)
|
||||||
|
{
|
||||||
|
return remove_watchpoint(&instance->watch_point_list_read, addr, length);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_debug_instance_on_failure(WASMDebugInstance *instance)
|
wasm_debug_instance_on_failure(WASMDebugInstance *instance)
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,6 +36,12 @@ typedef struct WASMDebugBreakPoint {
|
||||||
uint64 orignal_data;
|
uint64 orignal_data;
|
||||||
} WASMDebugBreakPoint;
|
} WASMDebugBreakPoint;
|
||||||
|
|
||||||
|
typedef struct WASMDebugWatchPoint {
|
||||||
|
bh_list_link next;
|
||||||
|
uint64 addr;
|
||||||
|
uint64 length;
|
||||||
|
} WASMDebugWatchPoint;
|
||||||
|
|
||||||
typedef enum debug_state_t {
|
typedef enum debug_state_t {
|
||||||
/* Debugger state conversion sequence:
|
/* Debugger state conversion sequence:
|
||||||
* DBG_LAUNCHING ---> APP_STOPPED <---> APP_RUNNING
|
* DBG_LAUNCHING ---> APP_STOPPED <---> APP_RUNNING
|
||||||
|
@ -56,6 +62,8 @@ struct WASMDebugInstance {
|
||||||
struct WASMDebugInstance *next;
|
struct WASMDebugInstance *next;
|
||||||
WASMDebugControlThread *control_thread;
|
WASMDebugControlThread *control_thread;
|
||||||
bh_list break_point_list;
|
bh_list break_point_list;
|
||||||
|
bh_list watch_point_list_read;
|
||||||
|
bh_list watch_point_list_write;
|
||||||
WASMCluster *cluster;
|
WASMCluster *cluster;
|
||||||
uint32 id;
|
uint32 id;
|
||||||
korp_tid current_tid;
|
korp_tid current_tid;
|
||||||
|
@ -184,6 +192,22 @@ bool
|
||||||
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr,
|
wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr,
|
||||||
uint64 length);
|
uint64 length);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_write_add(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_write_remove(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_read_add(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length);
|
||||||
|
|
||||||
|
bool
|
||||||
|
wasm_debug_instance_watchpoint_read_remove(WASMDebugInstance *instance,
|
||||||
|
uint64 addr, uint64 length);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_debug_instance_on_failure(WASMDebugInstance *instance);
|
wasm_debug_instance_on_failure(WASMDebugInstance *instance);
|
||||||
|
|
||||||
|
|
|
@ -358,6 +358,14 @@ handle_general_query(WASMGDBServer *server, char *payload)
|
||||||
|
|
||||||
send_thread_stop_status(server, status, 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
|
void
|
||||||
|
@ -643,46 +651,125 @@ handle_get_write_memory(WASMGDBServer *server, char *payload)
|
||||||
os_mutex_unlock(&tmpbuf_lock);
|
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
|
void
|
||||||
handle_add_break(WASMGDBServer *server, char *payload)
|
handle_add_break(WASMGDBServer *server, char *payload)
|
||||||
{
|
{
|
||||||
|
int arg_c;
|
||||||
size_t type, length;
|
size_t type, length;
|
||||||
uint64 addr;
|
uint64 addr;
|
||||||
|
|
||||||
if (sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length) == 3) {
|
if ((arg_c = sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length))
|
||||||
if (type == eBreakpointSoftware) {
|
!= 3) {
|
||||||
bool ret = wasm_debug_instance_add_breakpoint(
|
LOG_ERROR("Unsupported number of add break arguments %d", arg_c);
|
||||||
(WASMDebugInstance *)server->thread->debug_instance, addr,
|
write_packet(server, "");
|
||||||
length);
|
return;
|
||||||
if (ret)
|
}
|
||||||
write_packet(server, "OK");
|
|
||||||
else
|
switch (type) {
|
||||||
write_packet(server, "E01");
|
case eBreakpointSoftware:
|
||||||
return;
|
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 %d", type);
|
||||||
|
write_packet(server, "");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
write_packet(server, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
handle_remove_break(WASMGDBServer *server, char *payload)
|
handle_remove_break(WASMGDBServer *server, char *payload)
|
||||||
{
|
{
|
||||||
|
int arg_c;
|
||||||
size_t type, length;
|
size_t type, length;
|
||||||
uint64 addr;
|
uint64 addr;
|
||||||
|
|
||||||
if (sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length) == 3) {
|
if ((arg_c = sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length))
|
||||||
if (type == eBreakpointSoftware) {
|
!= 3) {
|
||||||
bool ret = wasm_debug_instance_remove_breakpoint(
|
LOG_ERROR("Unsupported number of remove break arguments %d", arg_c);
|
||||||
(WASMDebugInstance *)server->thread->debug_instance, addr,
|
write_packet(server, "");
|
||||||
length);
|
return;
|
||||||
if (ret)
|
}
|
||||||
write_packet(server, "OK");
|
|
||||||
else
|
switch (type) {
|
||||||
write_packet(server, "E01");
|
case eBreakpointSoftware:
|
||||||
return;
|
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 %d", type);
|
||||||
|
write_packet(server, "");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
write_packet(server, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in New Issue
Block a user