Preserve execution memory for debug instance (#1072)

During debugging, the debug client may request to malloc a memory space
to evaluate the user expressions. If we malloc memory from the linear memory,
it may fail when the thread is in stop status. We preserve a buffer during
creating debug instance, and use a simple bump pointer allocator to serve lldb's
memory request.
This commit is contained in:
Xu Jun 2022-04-04 08:23:55 +08:00 committed by GitHub
parent f0dc6a3015
commit 24afd4e7cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 18 deletions

View File

@ -155,6 +155,15 @@
#define WASM_ENABLE_DEBUG_INTERP 0
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
#ifndef DEBUG_EXECUTION_MEMORY_SIZE
/* 0x85000 is the size required by lldb, if this is changed to a smaller value,
* then the debugger will not be able to evaluate user expressions, other
* functionality such as breakpoint and stepping are not influenced by this */
#define DEBUG_EXECUTION_MEMORY_SIZE 0x85000
#endif
#endif /* end of WASM_ENABLE_DEBUG_INTERP != 0 */
#ifndef WASM_ENABLE_DEBUG_AOT
#define WASM_ENABLE_DEBUG_AOT 0
#endif

View File

@ -345,7 +345,8 @@ WASMDebugInstance *
wasm_debug_instance_create(WASMCluster *cluster)
{
WASMDebugInstance *instance;
WASMExecEnv *exec_env;
WASMExecEnv *exec_env = NULL;
wasm_module_inst_t module_inst = NULL;
if (!g_debug_engine || !g_debug_engine->active) {
return NULL;
@ -373,6 +374,24 @@ wasm_debug_instance_create(WASMCluster *cluster)
instance->current_tid = exec_env->handle;
module_inst = wasm_runtime_get_module_inst(exec_env);
bh_assert(module_inst);
/* Allocate linear memory for evaluating expressions during debugging. If
* the allocation failed, the debugger will not be able to evaluate
* expressions */
instance->exec_mem_info.size = DEBUG_EXECUTION_MEMORY_SIZE;
instance->exec_mem_info.start_offset = wasm_runtime_module_malloc(
module_inst, instance->exec_mem_info.size, NULL);
if (instance->exec_mem_info.start_offset == 0) {
LOG_WARNING(
"WASM Debug Engine warning: failed to allocate linear memory for "
"execution. \n"
"Will not be able to evaluate expressions during "
"debugging");
}
instance->exec_mem_info.current_pos = instance->exec_mem_info.start_offset;
if (!wasm_debug_control_thread_create(instance)) {
LOG_ERROR("WASM Debug Engine error: failed to create control thread");
goto fail3;
@ -1182,9 +1201,7 @@ wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size,
int32 map_port)
{
WASMExecEnv *exec_env;
WASMModuleInstance *module_inst;
uint32 offset;
void *native_addr;
uint32 offset = 0;
(void)map_port;
if (!instance)
@ -1194,15 +1211,23 @@ wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size,
if (!exec_env)
return 0;
module_inst = (WASMModuleInstance *)exec_env->module_inst;
if (instance->exec_mem_info.start_offset == 0) {
return 0;
}
/* TODO: malloc in wasi libc maybe not be thread safe, we hope LLDB will
always ask for memory when threads stopped */
offset = wasm_runtime_module_malloc((wasm_module_inst_t)module_inst, size,
&native_addr);
if (!offset)
if ((uint64)instance->exec_mem_info.current_pos
- instance->exec_mem_info.start_offset + size
<= (uint64)instance->exec_mem_info.size) {
offset = instance->exec_mem_info.current_pos;
instance->exec_mem_info.current_pos += size;
}
if (offset == 0) {
LOG_WARNING("the memory may be not enough for debug, try use larger "
"--heap-size");
return 0;
}
return WASM_ADDR(WasmMemory, 0, offset);
}
@ -1210,8 +1235,6 @@ bool
wasm_debug_instance_ummap(WASMDebugInstance *instance, uint64 addr)
{
WASMExecEnv *exec_env;
WASMModuleInstance *module_inst;
uint32 offset;
if (!instance)
return false;
@ -1220,11 +1243,13 @@ wasm_debug_instance_ummap(WASMDebugInstance *instance, uint64 addr)
if (!exec_env)
return false;
module_inst = (WASMModuleInstance *)exec_env->module_inst;
if (WASM_ADDR_TYPE(addr) == WasmMemory) {
offset = WASM_ADDR_OFFSET(addr);
wasm_runtime_module_free((wasm_module_inst_t)module_inst, offset);
return true;
if (instance->exec_mem_info.start_offset == 0) {
return false;
}
return false;
(void)addr;
/* Currently we don't support to free the execution memory, simply return
* true here */
return true;
}

View File

@ -44,6 +44,12 @@ typedef enum debug_state_t {
APP_STOPPED
} debug_state_t;
typedef struct WASMDebugExecutionMemory {
uint32 start_offset;
uint32 size;
uint32 current_pos;
} WASMDebugExecutionMemory;
typedef struct WASMDebugInstance {
struct WASMDebugInstance *next;
WASMDebugControlThread *control_thread;
@ -60,6 +66,11 @@ typedef struct WASMDebugInstance {
* RUNNING when receiving STEP/CONTINUE commands, and set to
* STOPPED when any thread stopped */
volatile debug_state_t current_state;
/* Execution memory info. During debugging, the debug client may request to
* malloc a memory space to evaluate user expressions. We preserve a buffer
* during creating debug instance, and use a simple bump pointer allocator
* to serve lldb's memory request */
WASMDebugExecutionMemory exec_mem_info;
} WASMDebugInstance;
typedef enum WASMDebugEventKind {