* fix: clear exec_env_tls when destroying exec_env When an exec_env is destroyed, check if it matches the current thread's exec_env_tls and clear it to avoid dangling pointer issues. Without this fix, in daemon-style execution where the same thread runs multiple WASM modules sequentially (like Cloudflare Workers), the exec_env_tls can point to freed memory after an exec_env is destroyed, causing crashes on subsequent executions when the signal handler tries to access it. This is critical for AOT mode with hardware bounds checking enabled, where signal handlers rely on exec_env_tls to handle SIGSEGV properly. * test(exec_env): add reproducer for exec_env_tls dangling pointer bug Add test case that reproduces the bug where exec_env_tls is not cleared on early return paths in invoke_native_with_hw_bound_check. The test triggers native stack overflow check failure, which causes wasm_runtime_call_wasm to return early after setting exec_env_tls but without clearing it. This leaves exec_env_tls pointing to a destroyed exec_env, causing subsequent calls to fail with "invalid exec env". Test confirms the fix in wasm_exec_env_destroy correctly clears exec_env_tls when destroying the exec_env it points to. * fix(runtime): clear exec_env_tls on early return from stack overflow check Move the fix to clear exec_env_tls at the source - in the early return path of invoke_native_with_hw_bound_check when native stack overflow check fails. |
||
|---|---|---|
| .. | ||
| aot | ||
| aot-stack-frame | ||
| common | ||
| compilation | ||
| custom-section | ||
| gc | ||
| interpreter | ||
| libc-builtin | ||
| linear-memory-aot | ||
| linear-memory-wasm | ||
| linux-perf | ||
| memory64 | ||
| running-modes | ||
| runtime-common | ||
| shared-heap | ||
| shared-utils | ||
| smart-tests | ||
| tid-allocator | ||
| unsupported-features | ||
| wasm-c-api | ||
| wasm-vm | ||
| CMakeLists.txt | ||
| README.md | ||
| unit_common.cmake | ||
Guide to Creating a Test Suite for a New Feature in WAMR
This guide provides instructions for contributors on how to create a test suite for a new feature in the WAMR project. Follow these steps to ensure consistency and maintainability across the test framework.
General Guidelines
-
Create a New Directory: Always create a dedicated directory for a new feature under the
tests/unit/directory.- Reuse existing test cases and patch them when possible to avoid redundancy.
- Name the directory in lowercase with words separated by hyphens (e.g.,
new-feature). - Name the test source file in lowercase with words separated by underscore (e.g.,
new_test.cc).
-
Avoid Committing
.wasmFiles: Do not commit precompiled.wasmfiles. Instead:- Generate
.wasmfiles from.wator.csource files. - Use
ExternalProjectand thewasi-sdktoolchain to compile.wasmfiles during the build process.
- Generate
-
Keep Using
ctestas the framework: Continue to usectestfor running the test cases, as it is already integrated into the existing test framework.
Writing CMakeLists.txt for the Test Suite
When creating a CMakeLists.txt file for your test suite, follow these best practices:
-
Do Not Fetch Googletest Again: The root
unit/CMakeLists.txtalready fetches Googletest. Avoid including or fetching it again in your test suite. -
Find LLVM on Demand: If your test suite requires LLVM, use
find_packageto locate LLVM components as needed. Do not include LLVM globally unless required. -
Include
unit_common.cmake: Always include../unit_common.cmakein yourCMakeLists.txtto avoid duplicating common configurations and utilities.Example:
include("../unit_common.cmake") -
Use
WAMR_RUNTIME_LIB_SOURCE: Replace long lists of runtime source files with theWAMR_RUNTIME_LIB_SOURCEvariable to simplify your configuration.Example:
target_sources(your_test_target PRIVATE ${WAMR_RUNTIME_LIB_SOURCE}) -
Avoid Global Compilation Flags: Do not define global compilation flags in the
unitdirectory. Each test case should specify its own compilation flags based on its unique requirements.
Generating .wasm Files
-
Compile
.wasmFiles Dynamically: UseExternalProjectin yourCMakeLists.txtto compile.wasmfiles from.wator.csource files.- Use the
wasi-sdktoolchain for.cor.ccsource files. - Example configuration:
ExternalProject_Add( generate_wasm SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps BUILD_ALWAYS YES CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps -B build -DWASI_SDK_PREFIX=${WASI_SDK_DIR} -DCMAKE_TOOLCHAIN_FILE=${WASISDK_TOOLCHAIN} BUILD_COMMAND ${CMAKE_COMMAND} --build build INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}/wasm-apps )
- Use the
-
Example for
wasm-appsDirectory: Place your source files in awasm-apps/subdirectory within your test suite directory.-
Create a
CMakeLists.txtinwasm-apps/to handle the compilation of these files. -
Example
CMakeLists.txtforwasm-apps/:cmake_minimum_required(VERSION 3.13) project(wasm_apps) add_executable(example example.c) set_target_properties(example PROPERTIES SUFFIX .wasm) install(TARGETS example DESTINATION .)
-
Compiling and Running Test Cases
To compile and run the test cases, follow these steps:
-
Generate Build Files:
cmake -S . -B build -
Build the Test Suite:
cmake --build build -
Run the Tests:
ctest --test-dir build --output-on-failureThis will compile and execute all test cases in the test suite, displaying detailed output for any failures.
-
List all Tests: To see all available test cases, use:
ctest --test-dir build -N -
Run a Specific Test: To run a specific test case, use:
ctest --test-dir build -R <test_name> --output-on-failure
Collecting Code Coverage Data
To collect code coverage data using lcov, follow these steps:
-
Build with Coverage Flags: Ensure the test suite is built with coverage flags enabled:
cmake -S . -B build -DCOLLECT_CODE_COVERAGE=1 cmake --build build -
Run the Tests: Execute the test cases as described above.
-
Generate Coverage Report: Use
lcovto collect and generate the coverage report:lcov --capture --directory build --output-file coverage.all.info lcov --extract coverage.all.info "*/core/iwasm/*" "*/core/shared/*" --output-file coverage.info genhtml coverage.info --output-directory coverage-report -
View the Report: Open the
index.htmlfile in thecoverage-reportdirectory to view the coverage results in your browser. -
Summary of Coverage: To get a summary of the coverage data, use:
lcov --summary coverage.info
Example Directory Structure
Here’s an example of how your test suite directory might look:
new-feature/
├── CMakeLists.txt
├── new_feature_test.cc
├── wasm-apps/
| ├── CMakeLists.txt
│ ├── example.c
│ └── example.wat
Additional Notes
- Testing Framework: Use Googletest for writing unit tests. Refer to existing test cases in the
tests/unit/directory for examples. - Documentation: Add comments in your test code to explain the purpose of each test case.
- Edge Cases: Ensure your test suite covers edge cases and potential failure scenarios.
- Reuse Utilities: Leverage existing utilities in
common/(e.g.,mock_allocator.h,test_helper.h) to simplify your test code.
By following these guidelines, you can create a well-structured and maintainable test suite that integrates seamlessly with the WAMR testing framework.