Fix potential recursive lock in pthread_create_wrapper (#2980)
Potential recursive lock occurs in:
```
pthread_create_wrapper (acquire exec_env->wait_lock)
=> wasm_cluster_create_thread
=> allocate_aux_stack
=> wasm_runtime_module_malloc_internal
=> wasm_call_function
=> wasm_exec_env_set_thread_info (acquire exec_env->wait_lock again)
```
Allocate aux stack before calling wasm_cluster_create_thread to resolve it.
Reported in https://github.com/bytecodealliance/wasm-micro-runtime/pull/2977.
This commit is contained in:
@ -558,6 +558,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
||||
ThreadRoutineArgs *routine_args = NULL;
|
||||
uint32 thread_handle;
|
||||
uint32 stack_size = 8192;
|
||||
uint32 aux_stack_start = 0, aux_stack_size;
|
||||
int32 ret = -1;
|
||||
|
||||
bh_assert(module);
|
||||
@ -609,10 +610,22 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
||||
routine_args->info_node = info_node;
|
||||
routine_args->module_inst = new_module_inst;
|
||||
|
||||
/* Allocate aux stack previously since exec_env->wait_lock is acquired
|
||||
below, and if the stack is allocated in wasm_cluster_create_thread,
|
||||
runtime may call the exported malloc function to allocate the stack,
|
||||
which acquires exec_env->wait again in wasm_exec_env_set_thread_info,
|
||||
and recursive lock (or hang) occurs */
|
||||
if (!wasm_cluster_allocate_aux_stack(exec_env, &aux_stack_start,
|
||||
&aux_stack_size)) {
|
||||
LOG_ERROR("thread manager error: "
|
||||
"failed to allocate aux stack space for new thread");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
os_mutex_lock(&exec_env->wait_lock);
|
||||
ret =
|
||||
wasm_cluster_create_thread(exec_env, new_module_inst, true,
|
||||
pthread_start_routine, (void *)routine_args);
|
||||
ret = wasm_cluster_create_thread(
|
||||
exec_env, new_module_inst, true, aux_stack_start, aux_stack_size,
|
||||
pthread_start_routine, (void *)routine_args);
|
||||
if (ret != 0) {
|
||||
os_mutex_unlock(&exec_env->wait_lock);
|
||||
goto fail;
|
||||
@ -636,6 +649,8 @@ fail:
|
||||
wasm_runtime_free(info_node);
|
||||
if (routine_args)
|
||||
wasm_runtime_free(routine_args);
|
||||
if (aux_stack_start)
|
||||
wasm_cluster_free_aux_stack(exec_env, aux_stack_start);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user