Implement source debugging for interpreter and AOT (#769)
Implement source debugging feature for classic interpreter and AOT: - use `cmake -DWAMR_BUILD_DEBUG_INTERP=1` to enable interpreter debugging - use `cmake -DWAMR_BUILD_DEBUG_AOT=1` to enable AOT debugging See doc/source_debugging.md for more details.
This commit is contained in:
@ -10,6 +10,9 @@
|
||||
#include "wasm_opcode.h"
|
||||
#include "wasm_runtime.h"
|
||||
#include "../common/wasm_native.h"
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
#include "../libraries/debug-engine/debug_engine.h"
|
||||
#endif
|
||||
|
||||
/* Read a value of given type from the address pointed to by the given
|
||||
pointer and increase the pointer to the position just after the
|
||||
@ -2934,6 +2937,10 @@ load_from_sections(WASMModule *module, WASMSection *sections,
|
||||
if (section->section_type == SECTION_TYPE_CODE) {
|
||||
buf_code = section->section_body;
|
||||
buf_code_end = buf_code + section->section_body_size;
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0 || WASM_ENABLE_DEBUG_AOT != 0
|
||||
module->buf_code = (uint8 *)buf_code;
|
||||
module->buf_code_size = section->section_body_size;
|
||||
#endif
|
||||
}
|
||||
else if (section->section_type == SECTION_TYPE_FUNC) {
|
||||
buf_func = section->section_body;
|
||||
@ -3296,10 +3303,26 @@ create_module(char *error_buf, uint32 error_buf_size)
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
module->import_module_list = &module->import_module_list_head;
|
||||
#endif
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
bh_list_init(&module->fast_opcode_list);
|
||||
#endif
|
||||
return module;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
static void
|
||||
record_fast_op(WASMModule *module, uint8 * pos, uint8 orig_op)
|
||||
{
|
||||
WASMFastOPCodeNode *fast_op = wasm_runtime_malloc(sizeof(WASMFastOPCodeNode));
|
||||
if (fast_op) {
|
||||
fast_op->offset = pos - module->load_addr;
|
||||
fast_op->orig_op = orig_op;
|
||||
bh_list_insert(&module->fast_opcode_list, fast_op);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
WASMModule *
|
||||
wasm_loader_load_from_sections(WASMSection *section_list,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
@ -3493,6 +3516,11 @@ wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_bu
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
module->load_addr = (uint8 *)buf;
|
||||
module->load_size = size;
|
||||
#endif
|
||||
|
||||
if (!load(buf, size, module, error_buf, error_buf_size)) {
|
||||
goto fail;
|
||||
}
|
||||
@ -3593,7 +3621,6 @@ wasm_loader_unload(WASMModule *module)
|
||||
*/
|
||||
wasm_runtime_free(node);
|
||||
/*
|
||||
*
|
||||
* the module file reading buffer will be released
|
||||
* in runtime_destroy()
|
||||
*/
|
||||
@ -3601,12 +3628,21 @@ wasm_loader_unload(WASMModule *module)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
WASMFastOPCodeNode *fast_opcode =
|
||||
bh_list_first_elem(&module->fast_opcode_list);
|
||||
while(fast_opcode) {
|
||||
WASMFastOPCodeNode * next = bh_list_elem_next(fast_opcode);
|
||||
wasm_runtime_free(fast_opcode);
|
||||
fast_opcode = next;
|
||||
}
|
||||
#endif
|
||||
wasm_runtime_free(module);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
|
||||
wasm_loader_find_block_addr(WASMExecEnv *exec_env,
|
||||
BlockAddr *block_addr_cache,
|
||||
const uint8 *start_addr,
|
||||
const uint8 *code_end_addr,
|
||||
uint8 label_type,
|
||||
@ -3638,7 +3674,9 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
|
||||
|
||||
while (p < code_end_addr) {
|
||||
opcode = *p++;
|
||||
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
op_break_retry:
|
||||
#endif
|
||||
switch (opcode) {
|
||||
case WASM_OP_UNREACHABLE:
|
||||
case WASM_OP_NOP:
|
||||
@ -4156,6 +4194,31 @@ wasm_loader_find_block_addr(BlockAddr *block_addr_cache,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
case DEBUG_OP_BREAK: {
|
||||
WASMDebugInstance *debug_instance =
|
||||
wasm_exec_env_get_instance(exec_env);
|
||||
char orignal_opcode[1];
|
||||
uint64 size = 1;
|
||||
WASMModuleInstance *module_inst =
|
||||
(WASMModuleInstance *)exec_env->module_inst;
|
||||
uint64 offset = (p - 1) >= module_inst->module->load_addr
|
||||
? (p - 1) - module_inst->module->load_addr
|
||||
: ~0;
|
||||
if (debug_instance) {
|
||||
if (wasm_debug_instance_get_obj_mem(
|
||||
debug_instance, offset, orignal_opcode, &size)
|
||||
&& size == 1) {
|
||||
LOG_VERBOSE("WASM loader find OP_BREAK , recover it "
|
||||
"with %02x: ",
|
||||
orignal_opcode[0]);
|
||||
opcode = orignal_opcode[0];
|
||||
goto op_break_retry;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
return false;
|
||||
@ -6317,6 +6380,9 @@ handle_op_block_and_loop:
|
||||
* to new extended opcode so that interpreter can resolve the
|
||||
* block quickly.
|
||||
*/
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p - 2, *(p - 2));
|
||||
#endif
|
||||
*(p - 2) = EXT_OP_BLOCK + (opcode - WASM_OP_BLOCK);
|
||||
#endif
|
||||
}
|
||||
@ -7196,13 +7262,28 @@ handle_op_block_and_loop:
|
||||
#else
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
|
||||
if (local_offset < 0x80) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = EXT_OP_GET_LOCAL_FAST;
|
||||
if (is_32bit_type(local_type))
|
||||
if (is_32bit_type(local_type)) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)local_offset;
|
||||
else
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)(local_offset | 0x80);
|
||||
while (p_org < p)
|
||||
}
|
||||
while (p_org < p) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = WASM_OP_NOP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -7254,13 +7335,28 @@ handle_op_block_and_loop:
|
||||
#else
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
|
||||
if (local_offset < 0x80) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = EXT_OP_SET_LOCAL_FAST;
|
||||
if (is_32bit_type(local_type))
|
||||
if (is_32bit_type(local_type)) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)local_offset;
|
||||
else
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)(local_offset | 0x80);
|
||||
while (p_org < p)
|
||||
}
|
||||
while (p_org < p) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = WASM_OP_NOP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -7309,13 +7405,28 @@ handle_op_block_and_loop:
|
||||
#else
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
|
||||
if (local_offset < 0x80) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = EXT_OP_TEE_LOCAL_FAST;
|
||||
if (is_32bit_type(local_type))
|
||||
if (is_32bit_type(local_type)) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)local_offset;
|
||||
else
|
||||
}
|
||||
else {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = (uint8)(local_offset | 0x80);
|
||||
while (p_org < p)
|
||||
}
|
||||
while (p_org < p) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org++ = WASM_OP_NOP;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -7344,6 +7455,9 @@ handle_op_block_and_loop:
|
||||
#if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_JIT == 0)
|
||||
if (global_type == VALUE_TYPE_I64
|
||||
|| global_type == VALUE_TYPE_F64) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org = WASM_OP_GET_GLOBAL_64;
|
||||
}
|
||||
#endif
|
||||
@ -7393,10 +7507,16 @@ handle_op_block_and_loop:
|
||||
#if WASM_ENABLE_FAST_INTERP == 0
|
||||
if (global_type == VALUE_TYPE_I64
|
||||
|| global_type == VALUE_TYPE_F64) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org = WASM_OP_SET_GLOBAL_64;
|
||||
}
|
||||
else if (module->aux_stack_size > 0
|
||||
&& global_idx == module->aux_stack_top_global_index) {
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
record_fast_op(module, p_org, *p_org);
|
||||
#endif
|
||||
*p_org = WASM_OP_SET_GLOBAL_AUX_STACK;
|
||||
}
|
||||
#else /* else of WASM_ENABLE_FAST_INTERP */
|
||||
|
||||
Reference in New Issue
Block a user