From 17b68253914720f0a4c46664d4f0061d861f7746 Mon Sep 17 00:00:00 2001 From: eloparco Date: Tue, 2 May 2023 15:40:38 +0100 Subject: [PATCH] fix: return error when exception encountered after main thread finishes --- .../test/trap_after_main_thread_finishes.c | 44 +++++++++++++++++++ .../test/trap_after_main_thread_finishes.json | 3 ++ product-mini/platforms/posix/main.c | 6 ++- product-mini/platforms/windows/main.c | 6 ++- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c create mode 100644 core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json diff --git a/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c b/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c new file mode 100644 index 0000000000..69e125d407 --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#ifndef __wasi__ +#error This example only compiles to WASM/WASI target +#endif + +#include +#include +#include + +#include "wasi_thread_start.h" + +enum CONSTANTS { + SECOND = 1000 * 1000 * 1000, /* 1 second */ + TIMEOUT = 1LL * SECOND +}; + +typedef struct { + start_args_t base; +} shared_t; + +void +__wasi_thread_start_C(int thread_id, int *start_arg) +{ + /* Wait so that the exception is raised after the main thread has finished + * already */ + __builtin_wasm_memory_atomic_wait32(NULL, 0, TIMEOUT); + __builtin_trap(); +} + +int +main(int argc, char **argv) +{ + shared_t data = { 0 }; + + assert(start_args_init(&data.base)); + int thread_id = __wasi_thread_spawn(&data); + assert(thread_id > 0 && "Thread creation failed"); + + return EXIT_SUCCESS; +} diff --git a/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json b/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json new file mode 100644 index 0000000000..9dc1e30d2b --- /dev/null +++ b/core/iwasm/libraries/lib-wasi-threads/test/trap_after_main_thread_finishes.json @@ -0,0 +1,3 @@ +{ + "exit_code": 1 +} diff --git a/product-mini/platforms/posix/main.c b/product-mini/platforms/posix/main.c index 8727ed3895..2e96ccddd6 100644 --- a/product-mini/platforms/posix/main.c +++ b/product-mini/platforms/posix/main.c @@ -745,8 +745,12 @@ main(int argc, char *argv[]) #if WASM_ENABLE_LIBC_WASI != 0 if (ret == 0) { - /* propagate wasi exit code. */ + /* wait for threads to finish and propagate wasi exit code. */ ret = wasm_runtime_get_wasi_exit_code(wasm_module_inst); + if (wasm_runtime_get_exception(wasm_module_inst)) { + /* got an exception in spawned thread */ + ret = 1; + } } #endif diff --git a/product-mini/platforms/windows/main.c b/product-mini/platforms/windows/main.c index 05647b5dbc..26fa7dcc96 100644 --- a/product-mini/platforms/windows/main.c +++ b/product-mini/platforms/windows/main.c @@ -549,8 +549,12 @@ main(int argc, char *argv[]) #if WASM_ENABLE_LIBC_WASI != 0 if (ret == 0) { - /* propagate wasi exit code. */ + /* wait for threads to finish and propagate wasi exit code. */ ret = wasm_runtime_get_wasi_exit_code(wasm_module_inst); + if (wasm_runtime_get_exception(wasm_module_inst)) { + /* got an exception in spawned thread */ + ret = 1; + } } #endif