mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
addr2line.py: Support sourceMappingURL section produced by emcc (#3302)
And update the debug-tools sample.
This commit is contained in:
parent
1a043b6eb5
commit
fef26ead3e
|
@ -389,14 +389,14 @@ jobs:
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wasi_sdk_release }}
|
sudo wget ${{ matrix.wasi_sdk_release }}
|
||||||
sudo tar -xzf wasi-sdk-*.tar.gz
|
sudo tar -xzf wasi-sdk-*.tar.gz
|
||||||
sudo mv wasi-sdk-20.0 wasi-sdk
|
sudo ln -sf wasi-sdk-20.0 wasi-sdk
|
||||||
|
|
||||||
- name: download and install wabt
|
- name: download and install wabt
|
||||||
run: |
|
run: |
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wabt_release }}
|
sudo wget ${{ matrix.wabt_release }}
|
||||||
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
||||||
sudo mv wabt-1.0.31 wabt
|
sudo ln -sf wabt-1.0.31 wabt
|
||||||
- name: Get LLVM libraries
|
- name: Get LLVM libraries
|
||||||
id: retrieve_llvm_libs
|
id: retrieve_llvm_libs
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
|
4
.github/workflows/compilation_on_macos.yml
vendored
4
.github/workflows/compilation_on_macos.yml
vendored
|
@ -273,14 +273,14 @@ jobs:
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wasi_sdk_release }}
|
sudo wget ${{ matrix.wasi_sdk_release }}
|
||||||
sudo tar -xzf wasi-sdk-*.tar.gz
|
sudo tar -xzf wasi-sdk-*.tar.gz
|
||||||
sudo mv wasi-sdk-20.0 wasi-sdk
|
sudo ln -sf wasi-sdk-20.0 wasi-sdk
|
||||||
|
|
||||||
- name: download and install wabt
|
- name: download and install wabt
|
||||||
run: |
|
run: |
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wabt_release }}
|
sudo wget ${{ matrix.wabt_release }}
|
||||||
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
||||||
sudo mv wabt-1.0.31 wabt
|
sudo ln -sf wabt-1.0.31 wabt
|
||||||
|
|
||||||
- name: Build Sample [basic]
|
- name: Build Sample [basic]
|
||||||
run: |
|
run: |
|
||||||
|
|
4
.github/workflows/nightly_run.yml
vendored
4
.github/workflows/nightly_run.yml
vendored
|
@ -459,13 +459,13 @@ jobs:
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wasi_sdk_release }}
|
sudo wget ${{ matrix.wasi_sdk_release }}
|
||||||
sudo tar -xzf wasi-sdk-*.tar.gz
|
sudo tar -xzf wasi-sdk-*.tar.gz
|
||||||
sudo mv wasi-sdk-20.0 wasi-sdk
|
sudo ln -sf wasi-sdk-20.0 wasi-sdk
|
||||||
- name: download and install wabt
|
- name: download and install wabt
|
||||||
run: |
|
run: |
|
||||||
cd /opt
|
cd /opt
|
||||||
sudo wget ${{ matrix.wabt_release }}
|
sudo wget ${{ matrix.wabt_release }}
|
||||||
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
sudo tar -xzf wabt-1.0.31-*.tar.gz
|
||||||
sudo mv wabt-1.0.31 wabt
|
sudo ln -sf wabt-1.0.31 wabt
|
||||||
|
|
||||||
- name: Get LLVM libraries
|
- name: Get LLVM libraries
|
||||||
id: retrieve_llvm_libs
|
id: retrieve_llvm_libs
|
||||||
|
|
|
@ -7,6 +7,14 @@ include(CheckPIESupported)
|
||||||
|
|
||||||
project(debug_tools_sample)
|
project(debug_tools_sample)
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||||
|
find_package(WASISDK REQUIRED)
|
||||||
|
|
||||||
|
option(SOURCE_MAP_DEMO "Enable source map demo" OFF)
|
||||||
|
if (SOURCE_MAP_DEMO)
|
||||||
|
find_package(EMSCRIPTEN 3.1.50 REQUIRED)
|
||||||
|
endif ()
|
||||||
|
|
||||||
################ runtime settings ################
|
################ runtime settings ################
|
||||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
@ -61,7 +69,30 @@ include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||||
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
|
||||||
|
|
||||||
################ wasm application ################
|
################ wasm application ################
|
||||||
add_subdirectory(wasm-apps)
|
include(ExternalProject)
|
||||||
|
|
||||||
|
# wasm32-wasi
|
||||||
|
ExternalProject_Add(wasm33-wasi
|
||||||
|
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps"
|
||||||
|
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps -B build
|
||||||
|
-DWASI_SDK_PREFIX=${WASISDK_HOME}
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=${WASISDK_TOOLCHAIN}
|
||||||
|
BUILD_COMMAND ${CMAKE_COMMAND} --build build
|
||||||
|
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (EMSCRIPTEN_FOUND)
|
||||||
|
# wasm32-emscripten
|
||||||
|
ExternalProject_Add(wasm32-emscripten
|
||||||
|
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps"
|
||||||
|
CONFIGURE_COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/wasm-apps -B build
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN_TOOLCHAIN}
|
||||||
|
-DCMAKE_VERBOSE_MAKEFILE=On
|
||||||
|
-DSOURCE_MAP_DEMO=On
|
||||||
|
BUILD_COMMAND ${CMAKE_COMMAND} --build build
|
||||||
|
INSTALL_COMMAND ${CMAKE_COMMAND} --install build --prefix ${CMAKE_CURRENT_BINARY_DIR}/emscripten
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
################ wamr runtime ################
|
################ wamr runtime ################
|
||||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||||
|
|
|
@ -80,6 +80,39 @@ $ python3 ../../../test-tools/addr2line/addr2line.py \
|
||||||
call_stack.txt --no-addr
|
call_stack.txt --no-addr
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### sourcemap
|
||||||
|
|
||||||
|
This script also supports _sourcemap_ which is produced by [_emscripten_](https://emscripten.org/docs/tools_reference/emcc.html). The _sourcemap_ is used to map the wasm function to the original source file. To use it, add `-gsource-map` option to _emcc_ command line. The output should be a section named "sourceMappingURL" and a separated file named "_.map_.
|
||||||
|
|
||||||
|
If the wasm file is with _sourcemap_, the script will use it to get the source file and line info. It needs an extra command line option `--emsdk` to specify the path of _emsdk_. The script will use _emsymbolizer_ to query the source file and line info.
|
||||||
|
|
||||||
|
````bash
|
||||||
|
$ python3 ../../../test-tools/addr2line/addr2line.py \
|
||||||
|
--wasi-sdk /opt/wasi-sdk \
|
||||||
|
--wabt /opt/wabt \
|
||||||
|
--wasm-file emscripten/wasm-apps/trap.wasm \
|
||||||
|
--emsdk /opt/emsdk \
|
||||||
|
call_stack.from_wasm_w_sourcemap.txt
|
||||||
|
|
||||||
|
The output should be something like:
|
||||||
|
|
||||||
|
```text
|
||||||
|
1: c
|
||||||
|
at ../../../../../wasm-apps/trap.c:5:1
|
||||||
|
2: b
|
||||||
|
at ../../../../../wasm-apps/trap.c:11:12
|
||||||
|
3: a
|
||||||
|
at ../../../../../wasm-apps/trap.c:17:12
|
||||||
|
4: main
|
||||||
|
at ../../../../../wasm-apps/trap.c:24:5
|
||||||
|
5: __main_void
|
||||||
|
at ../../../../../../../../../emsdk/emscripten/system/lib/standalone/__main_void.c:53:10
|
||||||
|
6: _start
|
||||||
|
at ../../../../../../../../../emsdk/emscripten/system/lib/libc/crt1.c:27:3
|
||||||
|
````
|
||||||
|
|
||||||
|
> The script assume the separated map file _.map_ is in the same directory as the wasm file.
|
||||||
|
|
||||||
### Another approach
|
### Another approach
|
||||||
|
|
||||||
If the wasm file is with "name" section, it is able to output function name in the stack trace. To achieve that, need to enable `WAMR_BUILD_LOAD_CUSTOM_SECTION` and `WAMR_BUILD_CUSTOM_NAME_SECTION`. If using .aot file, need to add `--emit-custom-sections=name` into wamrc command line options.
|
If the wasm file is with "name" section, it is able to output function name in the stack trace. To achieve that, need to enable `WAMR_BUILD_LOAD_CUSTOM_SECTION` and `WAMR_BUILD_CUSTOM_NAME_SECTION`. If using .aot file, need to add `--emit-custom-sections=name` into wamrc command line options.
|
||||||
|
@ -97,4 +130,4 @@ Then the output should be something like
|
||||||
Exception: unreachable
|
Exception: unreachable
|
||||||
```
|
```
|
||||||
|
|
||||||
Also, it is able to use *addr2line.py* to add file and line info to the stack trace.
|
Also, it is able to use _addr2line.py_ to add file and line info to the stack trace.
|
||||||
|
|
45
samples/debug-tools/cmake/FindEMSCRIPTEN.cmake
Normal file
45
samples/debug-tools/cmake/FindEMSCRIPTEN.cmake
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
find_path(EMSCRIPTEN_HOME
|
||||||
|
NAMES upstream/emscripten
|
||||||
|
PATHS /opt/emsdk
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
NO_CMAKE_PATH
|
||||||
|
NO_CMAKE_SYSTEM_PATH
|
||||||
|
NO_CMAKE_FIND_ROOT_PATH
|
||||||
|
REQUIRED
|
||||||
|
)
|
||||||
|
|
||||||
|
find_file(EMSCRIPTEN_VERSION_FILE
|
||||||
|
NAMES emscripten-version.txt
|
||||||
|
PATHS ${EMSCRIPTEN_HOME}/upstream/emscripten
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
NO_CMAKE_PATH
|
||||||
|
NO_CMAKE_SYSTEM_PATH
|
||||||
|
NO_CMAKE_FIND_ROOT_PATH
|
||||||
|
REQUIRED
|
||||||
|
)
|
||||||
|
|
||||||
|
file(READ ${EMSCRIPTEN_VERSION_FILE} EMSCRIPTEN_VERSION_FILE_CONTENT)
|
||||||
|
|
||||||
|
string(REGEX
|
||||||
|
MATCH
|
||||||
|
"[0-9]+\.[0-9]+(\.[0-9]+)*"
|
||||||
|
EMSCRIPTEN_VERSION
|
||||||
|
${EMSCRIPTEN_VERSION_FILE_CONTENT}
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package_handle_standard_args(EMSCRIPTEN
|
||||||
|
REQUIRED_VARS EMSCRIPTEN_HOME
|
||||||
|
VERSION_VAR EMSCRIPTEN_VERSION
|
||||||
|
HANDLE_VERSION_RANGE
|
||||||
|
)
|
||||||
|
|
||||||
|
if(EMSCRIPTEN_FOUND)
|
||||||
|
set(EMSCRIPTEN_TOOLCHAIN ${EMSCRIPTEN_HOME}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake)
|
||||||
|
set(EMCC ${EMSCRIPTEN_HOME}/upstream/emscripten/emcc)
|
||||||
|
endif()
|
||||||
|
mark_as_advanced(EMSCRIPTEN_TOOLCHAIN EMCC)
|
27
samples/debug-tools/cmake/FindWAMRC.cmake
Normal file
27
samples/debug-tools/cmake/FindWAMRC.cmake
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
find_path(WAMRC_HOME
|
||||||
|
wamr-compiler
|
||||||
|
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../..
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
NO_CMAKE_PATH
|
||||||
|
NO_CMAKE_SYSTEM_PATH
|
||||||
|
NO_CMAKE_FIND_ROOT_PATH
|
||||||
|
REQUIRED
|
||||||
|
)
|
||||||
|
|
||||||
|
find_file(WAMRC_BIN
|
||||||
|
wamrc
|
||||||
|
HINTS ${WAMRC_HOME}/wamr-compiler/build
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
NO_CMAKE_PATH
|
||||||
|
NO_CMAKE_SYSTEM_PATH
|
||||||
|
NO_CMAKE_FIND_ROOT_PATH
|
||||||
|
REQUIRED
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package_handle_standard_args(WAMRC REQUIRED_VARS WAMRC_BIN)
|
||||||
|
mark_as_advanced(WAMRC_BIN)
|
24
samples/debug-tools/cmake/FindWASISDK.cmake
Normal file
24
samples/debug-tools/cmake/FindWASISDK.cmake
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
file(GLOB WASISDK_SEARCH_PATH "/opt/wasi-sdk-*")
|
||||||
|
find_path(WASISDK_HOME
|
||||||
|
NAMES share/wasi-sysroot
|
||||||
|
PATHS ${WASISDK_SEARCH_PATH}
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
REQUIRED
|
||||||
|
)
|
||||||
|
|
||||||
|
string(REGEX MATCH [0-9]+\.[0-9]+\.*[0-9]* WASISDK_VERSION ${WASISDK_HOME})
|
||||||
|
|
||||||
|
find_package_handle_standard_args(WASISDK REQUIRED_VARS WASISDK_HOME VERSION_VAR WASISDK_VERSION)
|
||||||
|
|
||||||
|
if(WASISDK_FOUND)
|
||||||
|
set(WASISDK_CC_COMMAND ${WASISDK_HOME}/bin/clang)
|
||||||
|
set(WASISDK_CXX_COMMAND ${WASISDK_HOME}/bin/clang++)
|
||||||
|
set(WASISDK_TOOLCHAIN ${WASISDK_HOME}/share/cmake/wasi-sdk.cmake)
|
||||||
|
set(WASISDK_SYSROOT ${WASISDK_HOME}/share/wasi-sysroot)
|
||||||
|
endif()
|
||||||
|
mark_as_advanced(WASISDK_CC_COMMAND WASISDK_CXX_COMMAND WASISDK_TOOLCHAIN WASISDK_SYSROOT WASISDK_HOME)
|
|
@ -1,91 +1,58 @@
|
||||||
# Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
# Copyright (C) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
|
||||||
if (APPLE)
|
cmake_minimum_required (VERSION 3.14)
|
||||||
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
|
|
||||||
set (CMAKE_C_LINK_FLAGS "")
|
project (debut_tools_wasm)
|
||||||
set (CMAKE_CXX_LINK_FLAGS "")
|
|
||||||
|
set (CMAKE_BUILD_TYPE Debug) # Otherwise no debug symbols (addr2line)
|
||||||
|
|
||||||
|
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../cmake)
|
||||||
|
find_package (WAMRC REQUIRED)
|
||||||
|
|
||||||
|
option(SOURCE_MAP_DEMO "Enable source map demo" OFF)
|
||||||
|
if (SOURCE_MAP_DEMO)
|
||||||
|
find_package(EMSCRIPTEN 3.1.50 REQUIRED)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (NOT DEFINED WASI_SDK_DIR)
|
|
||||||
set (WASI_SDK_DIR "/opt/wasi-sdk")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (DEFINED WASI_SYSROOT)
|
|
||||||
set (CMAKE_SYSROOT "${WASI_SYSROOT}")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
|
|
||||||
set (CMAKE_ASM_COMPILER "${WASI_SDK_DIR}/bin/clang")
|
|
||||||
set (CMAKE_EXE_LINKER_FLAGS "-target wasm32-wasi")
|
|
||||||
|
|
||||||
################ wabt and wamrc dependencies ################
|
|
||||||
message(CHECK_START "Detecting WABT")
|
|
||||||
if(NOT (DEFINED WABT_DIR OR DEFINED CACHE{WABT_DIR}))
|
|
||||||
find_path(WABT_DIR
|
|
||||||
wabt
|
|
||||||
PATHS /opt
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_CMAKE_FIND_ROOT_PATH
|
|
||||||
)
|
|
||||||
if(DEFINED WABT_DIR)
|
|
||||||
set(WABT_DIR ${WABT_DIR}/wabt)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if(WABT_DIR)
|
|
||||||
message(CHECK_PASS "found")
|
|
||||||
else()
|
|
||||||
message(CHECK_FAIL "not found")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(CHECK_START "Detecting WASM_OBJDUMP at ${WABT_DIR}")
|
|
||||||
find_program(WASM_OBJDUMP
|
|
||||||
wasm-objdump
|
|
||||||
PATHS "${WABT_DIR}/bin"
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_CMAKE_FIND_ROOT_PATH
|
|
||||||
)
|
|
||||||
if(WASM_OBJDUMP)
|
|
||||||
message(CHECK_PASS "found")
|
|
||||||
else()
|
|
||||||
message(CHECK_FAIL "not found")
|
|
||||||
endif()
|
|
||||||
if((NOT EXISTS ${WASM_OBJDUMP}) )
|
|
||||||
message(FATAL_ERROR "Please make sure to have wasm-objdump under the path=${WABT_DIR}/bin ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(WAMR_COMPILER_DIR ${CMAKE_CURRENT_LIST_DIR}/../../wamr-compiler/build)
|
|
||||||
message(CHECK_START "Detecting WAMR_COMPILER at ${WAMR_COMPILER_DIR}")
|
|
||||||
find_file(WAMR_COMPILER
|
|
||||||
wamrc
|
|
||||||
PATHS "${CMAKE_CURRENT_LIST_DIR}/../../../wamr-compiler/build"
|
|
||||||
NO_DEFAULT_PATH
|
|
||||||
NO_CMAKE_FIND_ROOT_PATH
|
|
||||||
)
|
|
||||||
if(WAMR_COMPILER)
|
|
||||||
message(CHECK_PASS "found")
|
|
||||||
else()
|
|
||||||
message(CHECK_FAIL "not found")
|
|
||||||
endif()
|
|
||||||
if((NOT EXISTS ${WAMR_COMPILER}) )
|
|
||||||
message(FATAL_ERROR "Please build wamrc under the path=${WAMR_ROOT_DIR}/wamr-compiler/")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
################ wasm and aot compilation ################
|
################ wasm and aot compilation ################
|
||||||
function (compile_sample SOURCE_FILE)
|
function (compile_sample SOURCE_FILE)
|
||||||
get_filename_component (FILE_NAME ${SOURCE_FILE} NAME_WLE)
|
get_filename_component (FILE_NAME ${SOURCE_FILE} NAME_WLE)
|
||||||
set (WASM_MODULE ${FILE_NAME}.wasm)
|
|
||||||
add_executable (${WASM_MODULE} ${SOURCE_FILE})
|
|
||||||
|
|
||||||
add_custom_target(
|
## wasm
|
||||||
wasm_to_aot
|
set (WASM_FILE ${FILE_NAME}.wasm)
|
||||||
|
add_executable (${FILE_NAME} ${SOURCE_FILE})
|
||||||
|
set_target_properties (${FILE_NAME} PROPERTIES SUFFIX .wasm)
|
||||||
|
|
||||||
|
## aot
|
||||||
|
set (AOT_FILE ${FILE_NAME}.aot)
|
||||||
|
add_custom_target (
|
||||||
|
${FILE_NAME}_aot
|
||||||
ALL
|
ALL
|
||||||
DEPENDS ${WAMR_COMPILER} ${WASM_MODULE}
|
DEPENDS ${WAMRC_BIN} ${WASM_FILE}
|
||||||
# Use --enable-dump-call-stack to generate stack trace (addr2line)
|
# Use --enable-dump-call-stack to generate stack trace (addr2line)
|
||||||
COMMAND ${WAMR_COMPILER} --size-level=0 --enable-dump-call-stack -o wasm-apps/trap.aot wasm-apps/trap.wasm
|
COMMAND ${WAMRC_BIN} --size-level=0 --enable-dump-call-stack -o ${AOT_FILE} ${WASM_FILE}
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
## wasm + sourcemap
|
||||||
|
if (DEFINED EMSCRIPTEN)
|
||||||
|
add_custom_target(
|
||||||
|
${FILE_NAME}_w_sourcemap
|
||||||
|
ALL
|
||||||
|
DEPENDS ${SOURCE_FILE}
|
||||||
|
COMMAND ${EMCC} -O0 -gsource-map -o ${FILE_NAME}.sourcemap.wasm ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
## install both
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${WASM_FILE} DESTINATION wasm-apps)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${AOT_FILE} DESTINATION wasm-apps)
|
||||||
|
if (DEFINED EMSCRIPTEN)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.sourcemap.wasm DESTINATION wasm-apps)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.sourcemap.wasm.map DESTINATION wasm-apps)
|
||||||
|
endif ()
|
||||||
endfunction ()
|
endfunction ()
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE Debug) # Otherwise no debug symbols (addr2line)
|
|
||||||
compile_sample(trap.c)
|
compile_sample(trap.c)
|
|
@ -43,6 +43,28 @@ For example, there is a call-stack dump:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def locate_sourceMappingURL_section(wasm_objdump: Path, wasm_file: Path) -> bool:
|
||||||
|
"""
|
||||||
|
Figure out if the wasm file has a sourceMappingURL section.
|
||||||
|
"""
|
||||||
|
cmd = f"{wasm_objdump} -h {wasm_file}"
|
||||||
|
p = subprocess.run(
|
||||||
|
shlex.split(cmd),
|
||||||
|
check=True,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
universal_newlines=True,
|
||||||
|
)
|
||||||
|
outputs = p.stdout.split(os.linesep)
|
||||||
|
|
||||||
|
for line in outputs:
|
||||||
|
line = line.strip()
|
||||||
|
if "sourceMappingURL" in line:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
||||||
"""
|
"""
|
||||||
Find the start offset of Code section in a wasm file.
|
Find the start offset of Code section in a wasm file.
|
||||||
|
@ -62,15 +84,6 @@ def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
||||||
)
|
)
|
||||||
outputs = p.stdout.split(os.linesep)
|
outputs = p.stdout.split(os.linesep)
|
||||||
|
|
||||||
# if there is no .debug section, return -1
|
|
||||||
for line in outputs:
|
|
||||||
line = line.strip()
|
|
||||||
if ".debug_info" in line:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
print(f"No .debug_info section found {wasm_file}")
|
|
||||||
return -1
|
|
||||||
|
|
||||||
for line in outputs:
|
for line in outputs:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if "Code" in line:
|
if "Code" in line:
|
||||||
|
@ -79,7 +92,7 @@ def get_code_section_start(wasm_objdump: Path, wasm_file: Path) -> int:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
||||||
def get_line_info_from_function_addr(
|
def get_line_info_from_function_addr_dwarf(
|
||||||
dwarf_dump: Path, wasm_file: Path, offset: int
|
dwarf_dump: Path, wasm_file: Path, offset: int
|
||||||
) -> tuple[str, str, str, str]:
|
) -> tuple[str, str, str, str]:
|
||||||
"""
|
"""
|
||||||
|
@ -126,7 +139,7 @@ def get_dwarf_tag_value(tag: str, line: str) -> str:
|
||||||
return m.groups()[0]
|
return m.groups()[0]
|
||||||
|
|
||||||
|
|
||||||
def get_line_info_from_function_name(
|
def get_line_info_from_function_name_dwarf(
|
||||||
dwarf_dump: Path, wasm_file: Path, function_name: str
|
dwarf_dump: Path, wasm_file: Path, function_name: str
|
||||||
) -> tuple[str, str, str]:
|
) -> tuple[str, str, str]:
|
||||||
"""
|
"""
|
||||||
|
@ -160,6 +173,51 @@ def get_line_info_from_function_name(
|
||||||
return (function_name, function_file, function_line)
|
return (function_name, function_file, function_line)
|
||||||
|
|
||||||
|
|
||||||
|
def get_line_info_from_function_addr_sourcemapping(
|
||||||
|
emsymbolizer: Path, wasm_file: Path, offset: int
|
||||||
|
) -> tuple[str, str, str, str]:
|
||||||
|
"""
|
||||||
|
Find the location info of a given offset in a wasm file which is compiled with emcc.
|
||||||
|
|
||||||
|
{emsymbolizer} {wasm_file} {offset of file}
|
||||||
|
|
||||||
|
there usually are two lines:
|
||||||
|
??
|
||||||
|
relative path to source file:line:column
|
||||||
|
"""
|
||||||
|
debug_info_source = wasm_file.with_name(f"{wasm_file.name}.map")
|
||||||
|
cmd = f"{emsymbolizer} -t code -f {debug_info_source} {wasm_file} {offset}"
|
||||||
|
p = subprocess.run(
|
||||||
|
shlex.split(cmd),
|
||||||
|
check=False,
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
universal_newlines=True,
|
||||||
|
cwd=Path.cwd(),
|
||||||
|
)
|
||||||
|
outputs = p.stdout.split(os.linesep)
|
||||||
|
|
||||||
|
function_name, function_file = "<unknown>", "unknown"
|
||||||
|
function_line, function_column = "?", "?"
|
||||||
|
|
||||||
|
for line in outputs:
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if not line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = re.match("(.*):(\d+):(\d+)", line)
|
||||||
|
if m:
|
||||||
|
function_file, function_line, function_column = m.groups()
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
# it's always ??, not sure about that
|
||||||
|
if "??" != line:
|
||||||
|
function_name = line
|
||||||
|
|
||||||
|
return (function_name, function_file, function_line, function_column)
|
||||||
|
|
||||||
|
|
||||||
def parse_line_info(line_info: str) -> tuple[str, str, str]:
|
def parse_line_info(line_info: str) -> tuple[str, str, str]:
|
||||||
"""
|
"""
|
||||||
line_info -> [file, line, column]
|
line_info -> [file, line, column]
|
||||||
|
@ -250,6 +308,7 @@ def main():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="use call stack without addresses or from fast interpreter mode",
|
help="use call stack without addresses or from fast interpreter mode",
|
||||||
)
|
)
|
||||||
|
parser.add_argument("--emsdk", type=Path, help="path to emsdk")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
wasm_objdump = args.wabt.joinpath("bin/wasm-objdump")
|
wasm_objdump = args.wabt.joinpath("bin/wasm-objdump")
|
||||||
|
@ -261,6 +320,15 @@ def main():
|
||||||
llvm_cxxfilt = args.wasi_sdk.joinpath("bin/llvm-cxxfilt")
|
llvm_cxxfilt = args.wasi_sdk.joinpath("bin/llvm-cxxfilt")
|
||||||
assert llvm_cxxfilt.exists()
|
assert llvm_cxxfilt.exists()
|
||||||
|
|
||||||
|
emcc_production = locate_sourceMappingURL_section(wasm_objdump, args.wasm_file)
|
||||||
|
if emcc_production:
|
||||||
|
if args.emsdk is None:
|
||||||
|
print("Please provide the path to emsdk via --emsdk")
|
||||||
|
return -1
|
||||||
|
|
||||||
|
emsymbolizer = args.emsdk.joinpath("upstream/emscripten/emsymbolizer")
|
||||||
|
assert emsymbolizer.exists()
|
||||||
|
|
||||||
code_section_start = get_code_section_start(wasm_objdump, args.wasm_file)
|
code_section_start = get_code_section_start(wasm_objdump, args.wasm_file)
|
||||||
if code_section_start == -1:
|
if code_section_start == -1:
|
||||||
return -1
|
return -1
|
||||||
|
@ -281,6 +349,7 @@ def main():
|
||||||
|
|
||||||
_, offset, index = splitted
|
_, offset, index = splitted
|
||||||
if args.no_addr:
|
if args.no_addr:
|
||||||
|
# FIXME: w/ emcc production
|
||||||
if not index.startswith("$f"): # E.g. _start or Text format
|
if not index.startswith("$f"): # E.g. _start or Text format
|
||||||
print(f"{i}: {index}")
|
print(f"{i}: {index}")
|
||||||
continue
|
continue
|
||||||
|
@ -290,22 +359,40 @@ def main():
|
||||||
print(f"{i}: {line}")
|
print(f"{i}: {line}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
line_info = get_line_info_from_function_name(
|
if not emcc_production:
|
||||||
llvm_dwarf_dump, args.wasm_file, function_index_to_name[index]
|
_, function_file, function_line = (
|
||||||
)
|
get_line_info_from_function_name_dwarf(
|
||||||
|
llvm_dwarf_dump,
|
||||||
|
args.wasm_file,
|
||||||
|
function_index_to_name[index],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_, function_file, function_line = _, "unknown", "?"
|
||||||
|
|
||||||
_, function_file, function_line = line_info
|
|
||||||
function_name = demangle(llvm_cxxfilt, function_index_to_name[index])
|
function_name = demangle(llvm_cxxfilt, function_index_to_name[index])
|
||||||
print(f"{i}: {function_name}")
|
print(f"{i}: {function_name}")
|
||||||
print(f"\tat {function_file}:{function_line}")
|
print(f"\tat {function_file}:{function_line}")
|
||||||
else:
|
else:
|
||||||
offset = int(offset, 16)
|
offset = int(offset, 16)
|
||||||
|
# match the algorithm in wasm_interp_create_call_stack()
|
||||||
|
# either a *offset* to *code* section start
|
||||||
|
# or a *offset* in a file
|
||||||
|
assert offset > code_section_start
|
||||||
offset = offset - code_section_start
|
offset = offset - code_section_start
|
||||||
function_name, function_file, function_line, function_column = (
|
|
||||||
get_line_info_from_function_addr(
|
if emcc_production:
|
||||||
llvm_dwarf_dump, args.wasm_file, offset
|
function_name, function_file, function_line, function_column = (
|
||||||
|
get_line_info_from_function_addr_sourcemapping(
|
||||||
|
emsymbolizer, args.wasm_file, offset
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
function_name, function_file, function_line, function_column = (
|
||||||
|
get_line_info_from_function_addr_dwarf(
|
||||||
|
llvm_dwarf_dump, args.wasm_file, offset
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
# if can't parse function_name, use name section or <index>
|
# if can't parse function_name, use name section or <index>
|
||||||
if function_name == "<unknown>":
|
if function_name == "<unknown>":
|
||||||
|
|
Loading…
Reference in New Issue
Block a user