Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-scripts/config_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ elseif (WAMR_BUILD_LIBC_WASI EQUAL 1)
else ()
message (" Libc WASI disabled")
endif ()
if (WAMR_BUILD_FAST_INTERP EQUAL 1)
if ((WAMR_BUILD_FAST_INTERP EQUAL 1) AND (WAMR_BUILD_INTERP EQUAL 1))
add_definitions (-DWASM_ENABLE_FAST_INTERP=1)
message (" Fast interpreter enabled")
else ()
Expand Down
2 changes: 1 addition & 1 deletion core/iwasm/interpreter/wasm_mini_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -2438,7 +2438,7 @@ wasm_loader_unload(WASMModule *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, uint8 **p_else_addr,
uint8 **p_end_addr)
Expand Down
167 changes: 118 additions & 49 deletions core/iwasm/libraries/debug-engine/debug_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ typedef struct WASMDebugEngine {
bool active;
} WASMDebugEngine;

static WASMDebugEngine *g_debug_engine;

static bool
should_stop(WASMDebugControlThread *control_thread)
{
Expand All @@ -33,69 +35,112 @@ should_stop(WASMDebugControlThread *control_thread)
static void *
control_thread_routine(void *arg)
{
WASMDebugObject *debug_object = (WASMDebugObject *)arg;
WASMDebugInstance *debug_inst = (WASMDebugInstance *)arg;
WASMDebugControlThread *control_thread = NULL;
WASMCluster *cluster = NULL;
WASMExecEnv *exec_env;
bh_assert(debug_inst);

control_thread = debug_inst->control_thread;
bh_assert(control_thread);

cluster = debug_inst->cluster;
bh_assert(cluster);

exec_env = bh_list_first_elem(&cluster->exec_env_list);
bh_assert(exec_env);

os_mutex_lock(&exec_env->wait_lock);

control_thread->status = RUNNING;

debug_inst->id = g_debug_engine->debug_instance_list.len + 1;

control_thread->debug_engine = g_debug_engine;
control_thread->debug_instance = debug_inst;
strcpy(control_thread->ip_addr, g_debug_engine->ip_addr);
control_thread->port =
g_debug_engine->process_base_port + debug_inst->id;

LOG_WARNING("control thread of debug object %p start at %s:%d\n",
debug_object, debug_object->control_thread->ip_addr,
debug_object->control_thread->port);
debug_inst, control_thread->ip_addr, control_thread->port);

debug_object->control_thread->server =
wasm_launch_gdbserver(debug_object->control_thread->ip_addr,
debug_object->control_thread->port);
if (!debug_object->control_thread->server) {
control_thread->server =
wasm_launch_gdbserver(control_thread->ip_addr, control_thread->port);
if (!control_thread->server) {
LOG_ERROR("Failed to create debug server\n");
os_cond_signal(&exec_env->wait_cond);
os_mutex_unlock(&exec_env->wait_lock);
return NULL;
}

debug_object->control_thread->server->thread =
debug_object->control_thread;
control_thread->server->thread = control_thread;

/* control thread ready, notify main thread */
os_cond_signal(&exec_env->wait_cond);
os_mutex_unlock(&exec_env->wait_lock);

while (true) {
os_mutex_lock(&debug_object->control_thread->wait_lock);
if (!should_stop(debug_object->control_thread)) {
if (!wasm_gdbserver_handle_packet(
debug_object->control_thread->server))
debug_object->control_thread->status = STOPPED;
os_mutex_lock(&control_thread->wait_lock);
if (!should_stop(control_thread)) {
if (!wasm_gdbserver_handle_packet(control_thread->server)) {
control_thread->status = STOPPED;
}
}
else {
os_mutex_unlock(&debug_object->control_thread->wait_lock);
os_mutex_unlock(&control_thread->wait_lock);
break;
}
os_mutex_unlock(&debug_object->control_thread->wait_lock);
os_mutex_unlock(&control_thread->wait_lock);
}

LOG_VERBOSE("control thread of debug object %p stop\n", debug_object);
LOG_VERBOSE("control thread of debug object %p stop\n", debug_inst);
return NULL;
}

static WASMDebugControlThread *
wasm_debug_control_thread_create(WASMDebugObject *debug_object)
wasm_debug_control_thread_create(WASMDebugInstance *debug_instance)
{
WASMDebugControlThread *control_thread;
WASMCluster *cluster = debug_instance->cluster;
WASMExecEnv *exec_env;
bh_assert(cluster);

exec_env = bh_list_first_elem(&cluster->exec_env_list);
bh_assert(exec_env);

if (!(control_thread =
wasm_runtime_malloc(sizeof(WASMDebugControlThread)))) {
LOG_ERROR("WASM Debug Engine error: failed to allocate memory");
return NULL;
}
memset(control_thread, 0, sizeof(WASMDebugControlThread));

if (os_mutex_init(&control_thread->wait_lock) != 0)
goto fail;

if (os_cond_init(&control_thread->wait_cond) != 0)
goto fail1;
debug_instance->control_thread = control_thread;

control_thread->status = RUNNING;
os_mutex_lock(&exec_env->wait_lock);

if (0 != os_thread_create(&control_thread->tid, control_thread_routine,
debug_object, APP_THREAD_STACK_SIZE_MAX)) {
goto fail2;
debug_instance, APP_THREAD_STACK_SIZE_MAX)) {
os_mutex_unlock(&control_thread->wait_lock);
goto fail1;
}

/* wait until the debug control thread ready */
os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock);
os_mutex_unlock(&exec_env->wait_lock);
if (!control_thread->server)
goto fail1;

/* create control thread success, append debug instance to debug engine */
bh_list_insert(&g_debug_engine->debug_instance_list, debug_instance);
wasm_cluster_send_signal_all(debug_instance->cluster, WAMR_SIG_STOP);

return control_thread;

fail2:
os_cond_destroy(&control_thread->wait_cond);
fail1:
os_mutex_destroy(&control_thread->wait_lock);
fail:
Expand All @@ -104,27 +149,23 @@ wasm_debug_control_thread_create(WASMDebugObject *debug_object)
}

static void
wasm_debug_control_thread_destroy(WASMDebugObject *debug_object)
wasm_debug_control_thread_destroy(WASMDebugInstance *debug_instance)
{
WASMDebugControlThread *control_thread = debug_object->control_thread;
WASMDebugControlThread *control_thread = debug_instance->control_thread;
LOG_VERBOSE("control thread of debug object %p stop at %s:%d\n",
debug_object, debug_object->control_thread->ip_addr,
debug_object->control_thread->port);
os_mutex_lock(&control_thread->wait_lock);
debug_instance, control_thread->ip_addr,
control_thread->port);
control_thread->status = STOPPED;
os_mutex_lock(&control_thread->wait_lock);
wasm_close_gdbserver(control_thread->server);
os_mutex_unlock(&control_thread->wait_lock);
os_cond_signal(&control_thread->wait_cond);
os_thread_join(control_thread->tid, NULL);
wasm_runtime_free(control_thread->server);

os_mutex_destroy(&control_thread->wait_lock);
os_cond_destroy(&control_thread->wait_cond);
wasm_runtime_free(control_thread);
}

static WASMDebugEngine *g_debug_engine;

static WASMDebugEngine *
wasm_debug_engine_create()
{
Expand Down Expand Up @@ -215,24 +256,20 @@ wasm_debug_instance_create(WASMCluster *cluster)
return NULL;
}
memset(instance, 0, sizeof(WASMDebugInstance));
instance->cluster = cluster;
instance->control_thread =
wasm_debug_control_thread_create((WASMDebugObject *)instance);
instance->control_thread->debug_engine = (WASMDebugObject *)g_debug_engine;
instance->control_thread->debug_instance = (WASMDebugObject *)instance;
strcpy(instance->control_thread->ip_addr, g_debug_engine->ip_addr);
instance->id = g_debug_engine->debug_instance_list.len + 1;
bh_list_init(&instance->break_point_list);

instance->cluster = cluster;
exec_env = bh_list_first_elem(&cluster->exec_env_list);
bh_assert(exec_env);

/* exec_evn is created, but handle may not be set yet. */
instance->current_tid = exec_env ? exec_env->handle : 0;
instance->current_tid = exec_env->handle;

if (!wasm_debug_control_thread_create(instance)) {
LOG_ERROR("WASM Debug Engine error: failed to create control thread");
wasm_runtime_free(instance);
return NULL;
}

instance->control_thread->port =
g_debug_engine->process_base_port + instance->id;
bh_list_init(&instance->break_point_list);
bh_list_insert(&g_debug_engine->debug_instance_list, instance);
wasm_cluster_send_signal_all(instance->cluster, WAMR_SIG_STOP);
return instance;
}

Expand All @@ -249,6 +286,22 @@ wasm_cluster_get_debug_instance(WASMDebugEngine *engine, WASMCluster *cluster)
return instance;
}

static void
wasm_debug_instance_destroy_breakpoints(WASMDebugInstance *instance)
{
WASMDebugBreakPoint *breakpoint, *next_bp;

breakpoint = bh_list_first_elem(&instance->break_point_list);
while (breakpoint) {
next_bp = bh_list_elem_next(breakpoint);

bh_list_remove(&instance->break_point_list, breakpoint);
wasm_runtime_free(breakpoint);

breakpoint = next_bp;
}
}

void
wasm_debug_instance_destroy(WASMCluster *cluster)
{
Expand All @@ -260,8 +313,13 @@ wasm_debug_instance_destroy(WASMCluster *cluster)

instance = wasm_cluster_get_debug_instance(g_debug_engine, cluster);
if (instance) {
wasm_debug_control_thread_destroy((WASMDebugObject *)instance);
/* destroy control thread */
wasm_debug_control_thread_destroy(instance);
bh_list_remove(&g_debug_engine->debug_instance_list, instance);

/* destroy all breakpoints */
wasm_debug_instance_destroy_breakpoints(instance);

wasm_runtime_free(instance);
}
}
Expand Down Expand Up @@ -444,6 +502,7 @@ wasm_debug_instance_get_memregion(WASMDebugInstance *instance, uint64 addr)
LOG_ERROR("WASM Debug Engine error: failed to allocate memory");
return NULL;
}
memset(mem_info, 0, sizeof(WASMDebugMemoryInfo));
mem_info->start = WASM_ADDR(WasmInvalid, 0, 0);
mem_info->size = 0;
mem_info->name[0] = '\0';
Expand Down Expand Up @@ -715,6 +774,7 @@ wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance,
"WASM Debug Engine error: failed to allocate memory");
return false;
}
memset(breakpoint, 0, sizeof(WASMDebugBreakPoint));
breakpoint->addr = offset;
/* TODO: how to if more than one breakpoints are set
at the same addr? */
Expand Down Expand Up @@ -872,6 +932,10 @@ wasm_debug_instance_get_local(WASMDebugInstance *instance,
return false;

param_count = cur_func->param_count;

if (local_index >= param_count + cur_func->local_count)
return false;

local_offset = cur_func->local_offsets[local_index];
if (local_index < param_count)
local_type = cur_func->param_types[local_index];
Expand Down Expand Up @@ -928,6 +992,11 @@ wasm_debug_instance_get_global(WASMDebugInstance *instance,
module_inst = (WASMModuleInstance *)exec_env->module_inst;
global_data = module_inst->global_data;
globals = module_inst->globals;

if ((global_index < 0)
|| ((uint32)global_index >= module_inst->global_count)) {
return false;
}
global = globals + global_index;

#if WASM_ENABLE_MULTI_MODULE == 0
Expand Down
14 changes: 5 additions & 9 deletions core/iwasm/libraries/debug-engine/debug_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,20 @@ typedef enum WASMDebugControlThreadStatus {
STOPPED,
} WASMDebugControlThreadStatus;

struct WASMDebugObject;
struct WASMDebugEngine;
struct WASMDebugInstance;

typedef struct WASMDebugControlThread {
WASMGDBServer *server;
korp_tid tid;
korp_mutex wait_lock;
korp_cond wait_cond;
char ip_addr[128];
int port;
WASMDebugControlThreadStatus status;
struct WASMDebugObject *debug_engine;
struct WASMDebugObject *debug_instance;
struct WASMDebugEngine *debug_engine;
struct WASMDebugInstance *debug_instance;
} WASMDebugControlThread;

typedef struct WASMDebugObject {
struct WASMDebugObject *next;
WASMDebugControlThread *control_thread;
} WASMDebugObject;

typedef struct WASMDebugBreakPoint {
struct WASMDebugBreakPoint *next;
uint64 addr;
Expand Down
Loading