From 68e4534822d1f1ccf353831e64853e221fd0bd77 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Fri, 17 Jan 2025 16:16:45 +0000 Subject: [PATCH 01/30] Iterate callstack API --- core/iwasm/aot/aot_runtime.c | 43 ++++++++++++++++++++ core/iwasm/aot/aot_runtime.h | 3 ++ core/iwasm/common/wasm_runtime_common.c | 28 +++++++++++++ core/iwasm/common/wasm_runtime_common.h | 3 ++ core/iwasm/include/wasm_export.h | 34 ++++++++++++++++ core/iwasm/interpreter/wasm_interp.h | 2 + core/iwasm/interpreter/wasm_interp_classic.c | 4 +- core/iwasm/interpreter/wasm_interp_fast.c | 5 ++- core/iwasm/interpreter/wasm_runtime.c | 30 ++++++++++++++ core/iwasm/interpreter/wasm_runtime.h | 4 ++ 10 files changed, 154 insertions(+), 2 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 0f7b5d3d9a..87f0775ecc 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -10,6 +10,7 @@ #include "../common/wasm_runtime_common.h" #include "../common/wasm_memory.h" #include "../interpreter/wasm_runtime.h" +#include #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif @@ -4104,6 +4105,48 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) #endif /* end of WASM_ENABLE_AOT_STACK_FRAME != 0 */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 +void +aot_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +{ +/* +* Note for devs: please refrain from such modifications inside of aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * For more details check wasm_iterate_callstack in wasm_export.h +*/ + if (!is_tiny_frame(exec_env)) { + //TODO: support standard frames + return; + } + uint8* top_boundary = exec_env->wasm_stack.top_boundary; + uint8* top = exec_env->wasm_stack.top; + uint8* bottom = exec_env->wasm_stack.bottom; + + bool is_top_index_in_range = top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); + if (!is_top_index_in_range) { + return; + } + bool is_top_aligned_with_bottom = (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; + if (!is_top_aligned_with_bottom) { + return; + } + + AOTTinyFrame* frame = (AOTTinyFrame*)(top - sizeof(AOTTinyFrame)); + WASMCApiFrame record_frame; + while (frame && + (uint8_t*)frame >= bottom) { + record_frame.instance = exec_env->module_inst; + record_frame.module_offset = 0; + record_frame.func_index = frame->func_index; + record_frame.func_offset = frame->ip_offset; + if (!frame_handler(user_data, &record_frame)) { + break; + } + frame -= 1; + } +} + bool aot_create_call_stack(struct WASMExecEnv *exec_env) { diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 297b2a5b5d..5405772c90 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -777,6 +777,9 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame); bool aot_create_call_stack(struct WASMExecEnv *exec_env); +void +aot_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data); + /** * @brief Dump wasm call stack or get the size * diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 5517fe60fc..b631a9e114 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7,6 +7,7 @@ #include "bh_common.h" #include "bh_assert.h" #include "bh_log.h" +#include "wasm_export.h" #include "wasm_native.h" #include "wasm_runtime_common.h" #include "wasm_memory.h" @@ -1740,6 +1741,33 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env) wasm_exec_env_destroy(exec_env); } +void +wasm_iterate_callstack(const wasm_exec_env_t exec_env, const wasm_frame_callback frame_callback, void* user_data) +{ +/* +* Note for devs: please refrain from such modifications inside of wasm_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * For more details check wasm_iterate_callstack in wasm_export.h +*/ + #if WASM_ENABLE_DUMP_CALL_STACK + WASMModuleInstance* module_inst = (WASMModuleInstance *)get_module_inst(exec_env); + + #if WASM_ENABLE_INTERP != 0 + if (module_inst->module_type == Wasm_Module_Bytecode) { + wasm_interp_iterate_callstack(exec_env, frame_callback, user_data); + } + #endif + + #if WASM_ENABLE_AOT != 0 + if (module_inst->module_type == Wasm_Module_AoT) { + aot_iterate_callstack(exec_env, frame_callback, user_data); + } + #endif + #endif +} + bool wasm_runtime_init_thread_env(void) { diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 4c7dfed4f7..6157c64317 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -652,6 +652,9 @@ wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env); +WASM_RUNTIME_API_EXTERN void +wasm_iterate_callstack(const wasm_exec_env_t exec_env, const wasm_frame_callback frame_handler, void* user_data); + /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon * wasm_runtime_get_module_inst(WASMExecEnv *exec_env); diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 273657246d..cf75eeb6cc 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -126,6 +126,9 @@ typedef WASMFunctionInstanceCommon *wasm_function_inst_t; struct WASMMemoryInstance; typedef struct WASMMemoryInstance *wasm_memory_inst_t; +struct wasm_frame_t; +typedef struct wasm_frame_t * wasm_frame_ptr_t; + /* WASM section */ typedef struct wasm_section_t { struct wasm_section_t *next; @@ -864,6 +867,37 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); + +typedef bool (*wasm_frame_callback)(void*, wasm_frame_ptr_t); + +/** + * @brief Iterate over callstack frames and execute callback on it. + * + * Caution: This is not a thread-safe function. Ensure the exec_env + * is suspended before calling it from another thread. + * + * Usage: In the callback to read frames fields use APIs + * for wasm_frame_t from wasm_c_api.h + * + * Note: The function is async-signal-safe if called with verified arguments. + * Meaning it's safe to call it from a signal handler even on a signal interruption + * from another thread if next variables hold valid pointers + * - exec_env + * - exec_env->module_inst + * - exec_env->module_inst->module + * + * Note for devs: please refrain from such modifications inside of this call + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * + * @param exec_env the execution environment that containes frames + * @param callback the callback function provided by the user + * @param user_data context for callback provided by the user + */ +WASM_RUNTIME_API_EXTERN void +wasm_iterate_callstack(const wasm_exec_env_t exec_env, const wasm_frame_callback callback, void *user_data); + /** * Get the singleton execution environment for the instance. * diff --git a/core/iwasm/interpreter/wasm_interp.h b/core/iwasm/interpreter/wasm_interp.h index 1416405460..a4e31766d2 100644 --- a/core/iwasm/interpreter/wasm_interp.h +++ b/core/iwasm/interpreter/wasm_interp.h @@ -26,6 +26,8 @@ typedef struct WASMInterpFrame { /* Instruction pointer of the bytecode array. */ uint8 *ip; + uint32 func_index; + #if WASM_ENABLE_FAST_JIT != 0 uint8 *jitted_return_addr; #endif diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 834311f7ea..2d4eb82d99 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1264,9 +1264,11 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, init_frame_refs(frame_ref, local_cell_num, cur_func); #endif + cur_func_index = (uint32)(cur_func - module_inst->e->functions); + frame->func_index = cur_func_index; + wasm_exec_env_set_cur_frame(exec_env, frame); - cur_func_index = (uint32)(cur_func - module_inst->e->functions); bh_assert(cur_func_index < module_inst->module->import_function_count); if (!func_import->call_conv_wasm_c_api) { native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index f44644e456..f61b24f7cd 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1205,9 +1205,11 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, init_frame_refs(frame->frame_ref, local_cell_num, cur_func); #endif + cur_func_index = (uint32)(cur_func - module_inst->e->functions); + frame->func_index = cur_func_index; + wasm_exec_env_set_cur_frame(exec_env, frame); - cur_func_index = (uint32)(cur_func - module_inst->e->functions); bh_assert(cur_func_index < module_inst->module->import_function_count); if (!func_import->call_conv_wasm_c_api) { native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; @@ -6032,6 +6034,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* Initialize the interpreter context. */ frame->function = cur_func; + frame->func_index = (uint32)(cur_func - module->e->functions); frame_ip = wasm_get_func_code(cur_func); frame_ip_end = wasm_get_func_code_end(cur_func); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index c3f35916cd..529e0a2fcb 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -5,6 +5,7 @@ #include "wasm_runtime.h" #include "wasm.h" +#include "wasm_exec_env.h" #include "wasm_loader.h" #include "wasm_interp.h" #include "bh_common.h" @@ -4196,6 +4197,35 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, || (WASM_ENABLE_MEMORY_TRACING != 0) */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 +uint32 +wasm_interp_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +{ +/* +* Note for devs: please refrain from such modifications inside of wasm_interp_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * For more details check wasm_iterate_callstack in wasm_export.h +*/ + WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); + WASMInterpFrame* cur_frame = wasm_exec_env_get_cur_frame(exec_env); + uint8* top_boundary = exec_env->wasm_stack.top_boundary; + uint8* bottom = exec_env->wasm_stack.bottom; + + WASMCApiFrame record_frame; + while (cur_frame && + (uint8_t*)cur_frame >= bottom && + (uint8_t*)cur_frame + sizeof(WASMInterpFrame) <= top_boundary) { + record_frame.instance = module_inst; + record_frame.module_offset = 0; + record_frame.func_index = cur_frame->func_index; + if (!frame_handler(user_data, &record_frame)) { + break; + } + cur_frame = cur_frame->prev_frame; + } +} + bool wasm_interp_create_call_stack(struct WASMExecEnv *exec_env) { diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 00e9ad107f..7322bb16c3 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -730,6 +730,10 @@ wasm_get_table_inst(const WASMModuleInstance *module_inst, uint32 tbl_idx) } #if WASM_ENABLE_DUMP_CALL_STACK != 0 + +uint32 +wasm_interp_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data); + bool wasm_interp_create_call_stack(struct WASMExecEnv *exec_env); From d0c6da10ff45953565709005125a8649e1ab34da Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 27 Jan 2025 11:28:30 +0000 Subject: [PATCH 02/30] wamr bool type --- core/iwasm/aot/aot_runtime.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 87f0775ecc..2d5f6fde7f 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -10,7 +10,6 @@ #include "../common/wasm_runtime_common.h" #include "../common/wasm_memory.h" #include "../interpreter/wasm_runtime.h" -#include #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif From 1f4d3dd4d476f0b97c2a1a6de1f2941edc208286 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 27 Jan 2025 11:31:02 +0000 Subject: [PATCH 03/30] clang-format --- core/iwasm/aot/aot_runtime.c | 40 +++++++++++--------- core/iwasm/aot/aot_runtime.h | 5 ++- core/iwasm/common/wasm_runtime_common.c | 39 ++++++++++--------- core/iwasm/common/wasm_runtime_common.h | 6 ++- core/iwasm/include/wasm_export.h | 23 ++++++------ core/iwasm/interpreter/wasm_runtime.c | 50 +++++++++++++------------ core/iwasm/interpreter/wasm_runtime.h | 6 ++- 7 files changed, 94 insertions(+), 75 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 2d5f6fde7f..134cd98589 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4104,37 +4104,41 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) #endif /* end of WASM_ENABLE_AOT_STACK_FRAME != 0 */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 -void -aot_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +void +aot_iterate_callstack(WASMExecEnv *exec_env, + const wasm_frame_callback frame_handler, void *user_data) { -/* -* Note for devs: please refrain from such modifications inside of aot_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and top_boundary - * For more details check wasm_iterate_callstack in wasm_export.h -*/ + /* + * Note for devs: please refrain from such modifications inside of + * aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_iterate_callstack in + * wasm_export.h + */ if (!is_tiny_frame(exec_env)) { - //TODO: support standard frames + // TODO: support standard frames return; } - uint8* top_boundary = exec_env->wasm_stack.top_boundary; - uint8* top = exec_env->wasm_stack.top; - uint8* bottom = exec_env->wasm_stack.bottom; + uint8 *top_boundary = exec_env->wasm_stack.top_boundary; + uint8 *top = exec_env->wasm_stack.top; + uint8 *bottom = exec_env->wasm_stack.bottom; - bool is_top_index_in_range = top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); + bool is_top_index_in_range = + top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); if (!is_top_index_in_range) { return; } - bool is_top_aligned_with_bottom = (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; + bool is_top_aligned_with_bottom = + (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; if (!is_top_aligned_with_bottom) { return; } - AOTTinyFrame* frame = (AOTTinyFrame*)(top - sizeof(AOTTinyFrame)); + AOTTinyFrame *frame = (AOTTinyFrame *)(top - sizeof(AOTTinyFrame)); WASMCApiFrame record_frame; - while (frame && - (uint8_t*)frame >= bottom) { + while (frame && (uint8_t *)frame >= bottom) { record_frame.instance = exec_env->module_inst; record_frame.module_offset = 0; record_frame.func_index = frame->func_index; diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 5405772c90..7a26be3ea9 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -777,8 +777,9 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame); bool aot_create_call_stack(struct WASMExecEnv *exec_env); -void -aot_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data); +void +aot_iterate_callstack(WASMExecEnv *exec_env, + const wasm_frame_callback frame_handler, void *user_data); /** * @brief Dump wasm call stack or get the size diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index b631a9e114..acf6f55446 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1741,31 +1741,36 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env) wasm_exec_env_destroy(exec_env); } -void -wasm_iterate_callstack(const wasm_exec_env_t exec_env, const wasm_frame_callback frame_callback, void* user_data) +void +wasm_iterate_callstack(const wasm_exec_env_t exec_env, + const wasm_frame_callback frame_callback, + void *user_data) { -/* -* Note for devs: please refrain from such modifications inside of wasm_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and top_boundary - * For more details check wasm_iterate_callstack in wasm_export.h -*/ - #if WASM_ENABLE_DUMP_CALL_STACK - WASMModuleInstance* module_inst = (WASMModuleInstance *)get_module_inst(exec_env); - - #if WASM_ENABLE_INTERP != 0 + /* + * Note for devs: please refrain from such modifications inside of + * wasm_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_iterate_callstack in + * wasm_export.h + */ +#if WASM_ENABLE_DUMP_CALL_STACK + WASMModuleInstance *module_inst = + (WASMModuleInstance *)get_module_inst(exec_env); + +#if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { wasm_interp_iterate_callstack(exec_env, frame_callback, user_data); } - #endif +#endif - #if WASM_ENABLE_AOT != 0 +#if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { aot_iterate_callstack(exec_env, frame_callback, user_data); } - #endif - #endif +#endif +#endif } bool diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 6157c64317..1650615efc 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -652,8 +652,10 @@ wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env); -WASM_RUNTIME_API_EXTERN void -wasm_iterate_callstack(const wasm_exec_env_t exec_env, const wasm_frame_callback frame_handler, void* user_data); +WASM_RUNTIME_API_EXTERN void +wasm_iterate_callstack(const wasm_exec_env_t exec_env, + const wasm_frame_callback frame_handler, + void *user_data); /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon * diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index cf75eeb6cc..ca6020c3a8 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -127,7 +127,7 @@ struct WASMMemoryInstance; typedef struct WASMMemoryInstance *wasm_memory_inst_t; struct wasm_frame_t; -typedef struct wasm_frame_t * wasm_frame_ptr_t; +typedef struct wasm_frame_t *wasm_frame_ptr_t; /* WASM section */ typedef struct wasm_section_t { @@ -867,21 +867,20 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); - -typedef bool (*wasm_frame_callback)(void*, wasm_frame_ptr_t); +typedef bool (*wasm_frame_callback)(void *, wasm_frame_ptr_t); /** * @brief Iterate over callstack frames and execute callback on it. * - * Caution: This is not a thread-safe function. Ensure the exec_env + * Caution: This is not a thread-safe function. Ensure the exec_env * is suspended before calling it from another thread. * - * Usage: In the callback to read frames fields use APIs + * Usage: In the callback to read frames fields use APIs * for wasm_frame_t from wasm_c_api.h * - * Note: The function is async-signal-safe if called with verified arguments. - * Meaning it's safe to call it from a signal handler even on a signal interruption - * from another thread if next variables hold valid pointers + * Note: The function is async-signal-safe if called with verified arguments. + * Meaning it's safe to call it from a signal handler even on a signal + * interruption from another thread if next variables hold valid pointers * - exec_env * - exec_env->module_inst * - exec_env->module_inst->module @@ -889,14 +888,16 @@ typedef bool (*wasm_frame_callback)(void*, wasm_frame_ptr_t); * Note for devs: please refrain from such modifications inside of this call * - any allocations/freeing memory * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary * * @param exec_env the execution environment that containes frames * @param callback the callback function provided by the user * @param user_data context for callback provided by the user */ -WASM_RUNTIME_API_EXTERN void -wasm_iterate_callstack(const wasm_exec_env_t exec_env, const wasm_frame_callback callback, void *user_data); +WASM_RUNTIME_API_EXTERN void +wasm_iterate_callstack(const wasm_exec_env_t exec_env, + const wasm_frame_callback callback, void *user_data); /** * Get the singleton execution environment for the instance. diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 529e0a2fcb..90fed59ba3 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4197,32 +4197,36 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, || (WASM_ENABLE_MEMORY_TRACING != 0) */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 -uint32 -wasm_interp_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +uint32 +wasm_interp_iterate_callstack(WASMExecEnv *exec_env, + const wasm_frame_callback frame_handler, + void *user_data) { -/* -* Note for devs: please refrain from such modifications inside of wasm_interp_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and top_boundary - * For more details check wasm_iterate_callstack in wasm_export.h -*/ - WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); - WASMInterpFrame* cur_frame = wasm_exec_env_get_cur_frame(exec_env); - uint8* top_boundary = exec_env->wasm_stack.top_boundary; - uint8* bottom = exec_env->wasm_stack.bottom; + /* + * Note for devs: please refrain from such modifications inside of + * wasm_interp_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_iterate_callstack in + * wasm_export.h + */ + WASMModuleInstance *module_inst = + (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); + WASMInterpFrame *cur_frame = wasm_exec_env_get_cur_frame(exec_env); + uint8 *top_boundary = exec_env->wasm_stack.top_boundary; + uint8 *bottom = exec_env->wasm_stack.bottom; WASMCApiFrame record_frame; - while (cur_frame && - (uint8_t*)cur_frame >= bottom && - (uint8_t*)cur_frame + sizeof(WASMInterpFrame) <= top_boundary) { - record_frame.instance = module_inst; - record_frame.module_offset = 0; - record_frame.func_index = cur_frame->func_index; - if (!frame_handler(user_data, &record_frame)) { - break; - } - cur_frame = cur_frame->prev_frame; + while (cur_frame && (uint8_t *)cur_frame >= bottom + && (uint8_t *)cur_frame + sizeof(WASMInterpFrame) <= top_boundary) { + record_frame.instance = module_inst; + record_frame.module_offset = 0; + record_frame.func_index = cur_frame->func_index; + if (!frame_handler(user_data, &record_frame)) { + break; + } + cur_frame = cur_frame->prev_frame; } } diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 7322bb16c3..d67461e91f 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -731,8 +731,10 @@ wasm_get_table_inst(const WASMModuleInstance *module_inst, uint32 tbl_idx) #if WASM_ENABLE_DUMP_CALL_STACK != 0 -uint32 -wasm_interp_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data); +uint32 +wasm_interp_iterate_callstack(WASMExecEnv *exec_env, + const wasm_frame_callback frame_handler, + void *user_data); bool wasm_interp_create_call_stack(struct WASMExecEnv *exec_env); From 1b82cccff3045cec5c576ff182ffb33b531eeab0 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 27 Jan 2025 11:35:56 +0000 Subject: [PATCH 04/30] meaning of the return bool type in the callback --- core/iwasm/include/wasm_export.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index ca6020c3a8..68e3d509a9 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -867,6 +867,13 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); + +/** + * Callback to be called on wasm_frame_t*. + * It accepts void* as a context that can be used for closures. + * It returns bool so the iterating can stop when the callback returns false. + * E.g. callback that returns false after processing 100 frames + */ typedef bool (*wasm_frame_callback)(void *, wasm_frame_ptr_t); /** From 813831de0e8e76c7fe03d35b45f674248e0084c5 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 27 Jan 2025 11:39:53 +0000 Subject: [PATCH 05/30] keep devs notes out of public API --- core/iwasm/common/wasm_runtime_common.c | 2 +- core/iwasm/include/wasm_export.h | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index acf6f55446..9aa4101ef7 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1748,7 +1748,7 @@ wasm_iterate_callstack(const wasm_exec_env_t exec_env, { /* * Note for devs: please refrain from such modifications inside of - * wasm_iterate_callstack + * wasm_iterate_callstack to preserve async-signal-safety * - any allocations/freeing memory * - dereferencing any pointers other than: exec_env, exec_env->module_inst, * exec_env->module_inst->module, pointers between stack's bottom and diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 68e3d509a9..430555ca8f 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -892,12 +892,6 @@ typedef bool (*wasm_frame_callback)(void *, wasm_frame_ptr_t); * - exec_env->module_inst * - exec_env->module_inst->module * - * Note for devs: please refrain from such modifications inside of this call - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and - * top_boundary - * * @param exec_env the execution environment that containes frames * @param callback the callback function provided by the user * @param user_data context for callback provided by the user From bf6b15521abf46af6bc776db543e994d09d9946a Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 27 Jan 2025 11:42:12 +0000 Subject: [PATCH 06/30] format --- core/iwasm/include/wasm_export.h | 1 - 1 file changed, 1 deletion(-) diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 430555ca8f..aba7fd4ec6 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -867,7 +867,6 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); - /** * Callback to be called on wasm_frame_t*. * It accepts void* as a context that can be used for closures. From c8b87318314ff71165e9efffec9d86a3a1e073c9 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 27 Jan 2025 15:08:03 +0000 Subject: [PATCH 07/30] support standard frames as well --- core/iwasm/aot/aot_runtime.c | 89 ++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 134cd98589..e137e59ca5 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4105,40 +4105,32 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) #if WASM_ENABLE_DUMP_CALL_STACK != 0 void -aot_iterate_callstack(WASMExecEnv *exec_env, - const wasm_frame_callback frame_handler, void *user_data) +aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) { - /* - * Note for devs: please refrain from such modifications inside of - * aot_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and - * top_boundary For more details check wasm_iterate_callstack in - * wasm_export.h - */ - if (!is_tiny_frame(exec_env)) { - // TODO: support standard frames - return; - } - uint8 *top_boundary = exec_env->wasm_stack.top_boundary; - uint8 *top = exec_env->wasm_stack.top; - uint8 *bottom = exec_env->wasm_stack.bottom; - - bool is_top_index_in_range = - top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); +/* + * Note for devs: please refrain from such modifications inside of aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * For more details check wasm_iterate_callstack in wasm_export.h +*/ + uint8* top_boundary = exec_env->wasm_stack.top_boundary; + uint8* top = exec_env->wasm_stack.top; + uint8* bottom = exec_env->wasm_stack.bottom; + + bool is_top_index_in_range = top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); if (!is_top_index_in_range) { return; } - bool is_top_aligned_with_bottom = - (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; + bool is_top_aligned_with_bottom = (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; if (!is_top_aligned_with_bottom) { return; } - AOTTinyFrame *frame = (AOTTinyFrame *)(top - sizeof(AOTTinyFrame)); + AOTTinyFrame* frame = (AOTTinyFrame*)(top - sizeof(AOTTinyFrame)); WASMCApiFrame record_frame; - while (frame && (uint8_t *)frame >= bottom) { + while (frame && + (uint8_t*)frame >= bottom) { record_frame.instance = exec_env->module_inst; record_frame.module_offset = 0; record_frame.func_index = frame->func_index; @@ -4150,6 +4142,53 @@ aot_iterate_callstack(WASMExecEnv *exec_env, } } +void +aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +{ +/* + * Note for devs: please refrain from such modifications inside of aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * For more details check wasm_iterate_callstack in wasm_export.h +*/ + WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); + AOTFrame* cur_frame = (AOTFrame *)wasm_exec_env_get_cur_frame(exec_env); + uint8* top_boundary = exec_env->wasm_stack.top_boundary; + uint8* bottom = exec_env->wasm_stack.bottom; + + WASMCApiFrame record_frame; + while (cur_frame && + (uint8_t*)cur_frame >= bottom && + (uint8_t*)cur_frame + sizeof(AOTFrame) <= top_boundary) { + record_frame.instance = module_inst; + record_frame.module_offset = 0; + record_frame.func_index = (uint32)cur_frame->func_index; + record_frame.func_offset = (uint32)cur_frame->ip_offset; + if (!frame_handler(user_data, &record_frame)) { + break; + } + cur_frame = cur_frame->prev_frame; + } +} + +void +aot_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +{ +/* +* Note for devs: please refrain from such modifications inside of aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and top_boundary + * For more details check wasm_iterate_callstack in wasm_export.h +*/ + if (!is_tiny_frame(exec_env)) { + aot_iterate_callstack_standard_frame(exec_env, frame_handler, user_data); + } else { + aot_iterate_callstack_tiny_frame(exec_env, frame_handler, user_data); + } +} + bool aot_create_call_stack(struct WASMExecEnv *exec_env) { From 9ff80523291f7257d43fb2bdb5647c63403009b1 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 27 Jan 2025 15:08:58 +0000 Subject: [PATCH 08/30] format --- core/iwasm/aot/aot_runtime.c | 114 ++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 50 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index e137e59ca5..408d6b5c8e 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4105,32 +4105,37 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) #if WASM_ENABLE_DUMP_CALL_STACK != 0 void -aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env, + const wasm_frame_callback frame_handler, + void *user_data) { -/* - * Note for devs: please refrain from such modifications inside of aot_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and top_boundary - * For more details check wasm_iterate_callstack in wasm_export.h -*/ - uint8* top_boundary = exec_env->wasm_stack.top_boundary; - uint8* top = exec_env->wasm_stack.top; - uint8* bottom = exec_env->wasm_stack.bottom; - - bool is_top_index_in_range = top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); + /* + * Note for devs: please refrain from such modifications inside of + * aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_iterate_callstack in + * wasm_export.h + */ + uint8 *top_boundary = exec_env->wasm_stack.top_boundary; + uint8 *top = exec_env->wasm_stack.top; + uint8 *bottom = exec_env->wasm_stack.bottom; + + bool is_top_index_in_range = + top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); if (!is_top_index_in_range) { return; } - bool is_top_aligned_with_bottom = (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; + bool is_top_aligned_with_bottom = + (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; if (!is_top_aligned_with_bottom) { return; } - AOTTinyFrame* frame = (AOTTinyFrame*)(top - sizeof(AOTTinyFrame)); + AOTTinyFrame *frame = (AOTTinyFrame *)(top - sizeof(AOTTinyFrame)); WASMCApiFrame record_frame; - while (frame && - (uint8_t*)frame >= bottom) { + while (frame && (uint8_t *)frame >= bottom) { record_frame.instance = exec_env->module_inst; record_frame.module_offset = 0; record_frame.func_index = frame->func_index; @@ -4143,48 +4148,57 @@ aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env, const wasm_frame_callbac } void -aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, + const wasm_frame_callback frame_handler, + void *user_data) { -/* - * Note for devs: please refrain from such modifications inside of aot_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and top_boundary - * For more details check wasm_iterate_callstack in wasm_export.h -*/ - WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); - AOTFrame* cur_frame = (AOTFrame *)wasm_exec_env_get_cur_frame(exec_env); - uint8* top_boundary = exec_env->wasm_stack.top_boundary; - uint8* bottom = exec_env->wasm_stack.bottom; + /* + * Note for devs: please refrain from such modifications inside of + * aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_iterate_callstack in + * wasm_export.h + */ + WASMModuleInstance *module_inst = + (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); + AOTFrame *cur_frame = (AOTFrame *)wasm_exec_env_get_cur_frame(exec_env); + uint8 *top_boundary = exec_env->wasm_stack.top_boundary; + uint8 *bottom = exec_env->wasm_stack.bottom; WASMCApiFrame record_frame; - while (cur_frame && - (uint8_t*)cur_frame >= bottom && - (uint8_t*)cur_frame + sizeof(AOTFrame) <= top_boundary) { - record_frame.instance = module_inst; - record_frame.module_offset = 0; - record_frame.func_index = (uint32)cur_frame->func_index; - record_frame.func_offset = (uint32)cur_frame->ip_offset; - if (!frame_handler(user_data, &record_frame)) { - break; - } - cur_frame = cur_frame->prev_frame; + while (cur_frame && (uint8_t *)cur_frame >= bottom + && (uint8_t *)cur_frame + sizeof(AOTFrame) <= top_boundary) { + record_frame.instance = module_inst; + record_frame.module_offset = 0; + record_frame.func_index = (uint32)cur_frame->func_index; + record_frame.func_offset = (uint32)cur_frame->ip_offset; + if (!frame_handler(user_data, &record_frame)) { + break; + } + cur_frame = cur_frame->prev_frame; } } void -aot_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void* user_data) +aot_iterate_callstack(WASMExecEnv *exec_env, + const wasm_frame_callback frame_handler, void *user_data) { -/* -* Note for devs: please refrain from such modifications inside of aot_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and top_boundary - * For more details check wasm_iterate_callstack in wasm_export.h -*/ + /* + * Note for devs: please refrain from such modifications inside of + * aot_iterate_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_iterate_callstack in + * wasm_export.h + */ if (!is_tiny_frame(exec_env)) { - aot_iterate_callstack_standard_frame(exec_env, frame_handler, user_data); - } else { + aot_iterate_callstack_standard_frame(exec_env, frame_handler, + user_data); + } + else { aot_iterate_callstack_tiny_frame(exec_env, frame_handler, user_data); } } From 6bfc08849a8bc8c2031442aef625e12b863a5bf5 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Tue, 28 Jan 2025 11:09:32 +0000 Subject: [PATCH 09/30] Calculate func_index instead of adding an extra field to wasm frame --- core/iwasm/interpreter/wasm_interp.h | 2 -- core/iwasm/interpreter/wasm_interp_classic.c | 4 +--- core/iwasm/interpreter/wasm_interp_fast.c | 5 +---- core/iwasm/interpreter/wasm_runtime.c | 3 ++- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/core/iwasm/interpreter/wasm_interp.h b/core/iwasm/interpreter/wasm_interp.h index a4e31766d2..1416405460 100644 --- a/core/iwasm/interpreter/wasm_interp.h +++ b/core/iwasm/interpreter/wasm_interp.h @@ -26,8 +26,6 @@ typedef struct WASMInterpFrame { /* Instruction pointer of the bytecode array. */ uint8 *ip; - uint32 func_index; - #if WASM_ENABLE_FAST_JIT != 0 uint8 *jitted_return_addr; #endif diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index 2d4eb82d99..834311f7ea 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -1264,11 +1264,9 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, init_frame_refs(frame_ref, local_cell_num, cur_func); #endif - cur_func_index = (uint32)(cur_func - module_inst->e->functions); - frame->func_index = cur_func_index; - wasm_exec_env_set_cur_frame(exec_env, frame); + cur_func_index = (uint32)(cur_func - module_inst->e->functions); bh_assert(cur_func_index < module_inst->module->import_function_count); if (!func_import->call_conv_wasm_c_api) { native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index f61b24f7cd..f44644e456 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -1205,11 +1205,9 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst, init_frame_refs(frame->frame_ref, local_cell_num, cur_func); #endif - cur_func_index = (uint32)(cur_func - module_inst->e->functions); - frame->func_index = cur_func_index; - wasm_exec_env_set_cur_frame(exec_env, frame); + cur_func_index = (uint32)(cur_func - module_inst->e->functions); bh_assert(cur_func_index < module_inst->module->import_function_count); if (!func_import->call_conv_wasm_c_api) { native_func_pointer = module_inst->import_func_ptrs[cur_func_index]; @@ -6034,7 +6032,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, /* Initialize the interpreter context. */ frame->function = cur_func; - frame->func_index = (uint32)(cur_func - module->e->functions); frame_ip = wasm_get_func_code(cur_func); frame_ip_end = wasm_get_func_code_end(cur_func); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 90fed59ba3..4ac882bffb 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4222,7 +4222,8 @@ wasm_interp_iterate_callstack(WASMExecEnv *exec_env, && (uint8_t *)cur_frame + sizeof(WASMInterpFrame) <= top_boundary) { record_frame.instance = module_inst; record_frame.module_offset = 0; - record_frame.func_index = cur_frame->func_index; + // It's safe to dereference module_inst->e because "e" is asigned only once in wasm_instantiate + record_frame.func_index = (uint32)(cur_frame->function - module_inst->e->functions); if (!frame_handler(user_data, &record_frame)) { break; } From b6daacb8363a86b9b1dfb5b2902ad6c78f8a22c0 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Tue, 28 Jan 2025 11:25:45 +0000 Subject: [PATCH 10/30] ignore frames with no function --- core/iwasm/interpreter/wasm_runtime.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 4ac882bffb..6ab5d756b1 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4220,10 +4220,16 @@ wasm_interp_iterate_callstack(WASMExecEnv *exec_env, WASMCApiFrame record_frame; while (cur_frame && (uint8_t *)cur_frame >= bottom && (uint8_t *)cur_frame + sizeof(WASMInterpFrame) <= top_boundary) { + if (!cur_frame->function) { + cur_frame = cur_frame->prev_frame; + continue; + } record_frame.instance = module_inst; record_frame.module_offset = 0; - // It's safe to dereference module_inst->e because "e" is asigned only once in wasm_instantiate - record_frame.func_index = (uint32)(cur_frame->function - module_inst->e->functions); + // It's safe to dereference module_inst->e because "e" is asigned only + // once in wasm_instantiate + record_frame.func_index = + (uint32)(cur_frame->function - module_inst->e->functions); if (!frame_handler(user_data, &record_frame)) { break; } From 5bfbfd5f581050732f65d3a44283a66e47422ca4 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Tue, 28 Jan 2025 11:36:59 +0000 Subject: [PATCH 11/30] update typo in the comment --- core/iwasm/aot/aot_runtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 408d6b5c8e..df956549a7 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4111,7 +4111,7 @@ aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env, { /* * Note for devs: please refrain from such modifications inside of - * aot_iterate_callstack + * aot_iterate_callstack_tiny_frame * - any allocations/freeing memory * - dereferencing any pointers other than: exec_env, exec_env->module_inst, * exec_env->module_inst->module, pointers between stack's bottom and @@ -4154,7 +4154,7 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, { /* * Note for devs: please refrain from such modifications inside of - * aot_iterate_callstack + * aot_iterate_callstack_standard_frame * - any allocations/freeing memory * - dereferencing any pointers other than: exec_env, exec_env->module_inst, * exec_env->module_inst->module, pointers between stack's bottom and From 478b373cdaf776fe2499e2995b032713748a11ca Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Tue, 28 Jan 2025 13:27:01 +0000 Subject: [PATCH 12/30] update signature --- core/iwasm/interpreter/wasm_runtime.c | 2 +- core/iwasm/interpreter/wasm_runtime.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 6ab5d756b1..e0f55353dc 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4197,7 +4197,7 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, || (WASM_ENABLE_MEMORY_TRACING != 0) */ #if WASM_ENABLE_DUMP_CALL_STACK != 0 -uint32 +void wasm_interp_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void *user_data) diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index d67461e91f..1b439bac16 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -731,7 +731,7 @@ wasm_get_table_inst(const WASMModuleInstance *module_inst, uint32 tbl_idx) #if WASM_ENABLE_DUMP_CALL_STACK != 0 -uint32 +void wasm_interp_iterate_callstack(WASMExecEnv *exec_env, const wasm_frame_callback frame_handler, void *user_data); From fb6c05e3494d58c42ed258aaeb3947f104977b6c Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Tue, 28 Jan 2025 16:14:01 +0000 Subject: [PATCH 13/30] add correct frame size for aot standard frames --- core/iwasm/aot/aot_runtime.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index df956549a7..ee483fa5b2 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4166,10 +4166,11 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, AOTFrame *cur_frame = (AOTFrame *)wasm_exec_env_get_cur_frame(exec_env); uint8 *top_boundary = exec_env->wasm_stack.top_boundary; uint8 *bottom = exec_env->wasm_stack.bottom; + uint32 frame_size = (uint32)offsetof(AOTFrame, lp); WASMCApiFrame record_frame; while (cur_frame && (uint8_t *)cur_frame >= bottom - && (uint8_t *)cur_frame + sizeof(AOTFrame) <= top_boundary) { + && (uint8_t *)cur_frame + frame_size <= top_boundary) { record_frame.instance = module_inst; record_frame.module_offset = 0; record_frame.func_index = (uint32)cur_frame->func_index; From f7204bddfb364dd1b595e5bb5f55fdc9e907127f Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Tue, 28 Jan 2025 16:33:52 +0000 Subject: [PATCH 14/30] standard frame is not supported when GC is enabled --- core/iwasm/aot/aot_runtime.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index ee483fa5b2..028bfe89f6 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4161,6 +4161,7 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, * top_boundary For more details check wasm_iterate_callstack in * wasm_export.h */ +#if WASM_ENABLE_GC == 0 WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); AOTFrame *cur_frame = (AOTFrame *)wasm_exec_env_get_cur_frame(exec_env); @@ -4180,6 +4181,12 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, } cur_frame = cur_frame->prev_frame; } +#else +/* + * TODO: add support for standard frames when GC is enabled + * now it poses a risk due to variable size of the frame + */ +#endif } void From 32338bb7d6564064b84bbbb775178d49962de515 Mon Sep 17 00:00:00 2001 From: "Georgii Rylov :slightly_smiling_face" Date: Mon, 24 Feb 2025 17:22:05 +0000 Subject: [PATCH 15/30] Copy read only API behind a flag instead of using user defined callback --- CMakeLists.txt | 5 ++ build-scripts/config_common.cmake | 8 +++ core/iwasm/aot/aot_runtime.c | 70 ++++++++++++++++--------- core/iwasm/aot/aot_runtime.h | 10 ++-- core/iwasm/common/wasm_runtime_common.c | 19 ++++--- core/iwasm/common/wasm_runtime_common.h | 23 +++----- core/iwasm/include/wasm_export.h | 41 ++++++++++----- core/iwasm/interpreter/wasm_runtime.c | 46 ++++++++++------ core/iwasm/interpreter/wasm_runtime.h | 10 ++-- 9 files changed, 143 insertions(+), 89 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6362d0e56e..287559ff16 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,11 @@ if (NOT DEFINED WAMR_BUILD_LIB_WASI_THREADS) set (WAMR_BUILD_LIB_WASI_THREADS 0) endif () +if (NOT DEFINED WAMR_ENABLE_COPY_CALLSTACK) + # Disable copy callstack by default + set (WAMR_ENABLE_COPY_CALLSTACK 0) +endif() + if (NOT DEFINED WAMR_BUILD_MINI_LOADER) # Disable wasm mini loader by default set (WAMR_BUILD_MINI_LOADER 0) diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index 88abf7324f..c7cfff8423 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -319,6 +319,14 @@ if (WAMR_BUILD_SHARED_HEAP EQUAL 1) message (" Shared heap enabled") endif() +if (WAMR_ENABLE_COPY_CALLSTACK EQUAL 1) + add_definitions (-DWAMR_ENABLE_COPY_CALLSTACK=1) + message(" Copy callstack enabled") +else () + add_definitions (-DWAMR_ENABLE_COPY_CALLSTACK=0) + message(" Copy callstack disabled") +endif() + if (WAMR_BUILD_MEMORY64 EQUAL 1) # if native is 32-bit or cross-compiled to 32-bit if (NOT WAMR_BUILD_TARGET MATCHES ".*64.*") diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index f5a135be95..0cd53e4a5c 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4103,11 +4103,11 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) } #endif /* end of WASM_ENABLE_AOT_STACK_FRAME != 0 */ -#if WASM_ENABLE_DUMP_CALL_STACK != 0 -void -aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env, - const wasm_frame_callback frame_handler, - void *user_data) +#if WAMR_ENABLE_COPY_CALLSTACK != 0 +uint32 +aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, + const uint32 length, + const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of @@ -4122,35 +4122,43 @@ aot_iterate_callstack_tiny_frame(WASMExecEnv *exec_env, uint8 *top = exec_env->wasm_stack.top; uint8 *bottom = exec_env->wasm_stack.bottom; + uint32 count = 0; + bool is_top_index_in_range = top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); if (!is_top_index_in_range) { - return; + return count; } bool is_top_aligned_with_bottom = (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; if (!is_top_aligned_with_bottom) { - return; + return count; } AOTTinyFrame *frame = (AOTTinyFrame *)(top - sizeof(AOTTinyFrame)); WASMCApiFrame record_frame; - while (frame && (uint8_t *)frame >= bottom) { + while (frame && (uint8_t *)frame >= bottom + && count < (skip_n + length)) { + if (count < skip_n) { + ++count; + frame -= 1; + continue; + } record_frame.instance = exec_env->module_inst; record_frame.module_offset = 0; record_frame.func_index = frame->func_index; record_frame.func_offset = frame->ip_offset; - if (!frame_handler(user_data, &record_frame)) { - break; - } + buffer[count - skip_n] = record_frame; frame -= 1; + ++count; } + return count; } -void -aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, - const wasm_frame_callback frame_handler, - void *user_data) +uint32 +aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, + const uint32 length, + const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of @@ -4169,17 +4177,24 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, uint8 *bottom = exec_env->wasm_stack.bottom; uint32 frame_size = (uint32)offsetof(AOTFrame, lp); + uint32 count = 0; + WASMCApiFrame record_frame; while (cur_frame && (uint8_t *)cur_frame >= bottom - && (uint8_t *)cur_frame + frame_size <= top_boundary) { + && (uint8_t *)cur_frame + frame_size <= top_boundary + && count < (skip_n + length)) { + if (count < skip_n) { + ++count; + cur_frame = cur_frame->prev_frame; + continue; + } record_frame.instance = module_inst; record_frame.module_offset = 0; record_frame.func_index = (uint32)cur_frame->func_index; record_frame.func_offset = (uint32)cur_frame->ip_offset; - if (!frame_handler(user_data, &record_frame)) { - break; - } + buffer[count - skip_n] = record_frame; cur_frame = cur_frame->prev_frame; + ++count; } #else /* @@ -4189,9 +4204,11 @@ aot_iterate_callstack_standard_frame(WASMExecEnv *exec_env, #endif } -void -aot_iterate_callstack(WASMExecEnv *exec_env, - const wasm_frame_callback frame_handler, void *user_data) + +uint32 +aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, + const uint32 length, + const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of @@ -4203,14 +4220,15 @@ aot_iterate_callstack(WASMExecEnv *exec_env, * wasm_export.h */ if (!is_tiny_frame(exec_env)) { - aot_iterate_callstack_standard_frame(exec_env, frame_handler, - user_data); + return aot_copy_callstack_standard_frame(exec_env, buffer, length, skip_n); } else { - aot_iterate_callstack_tiny_frame(exec_env, frame_handler, user_data); + return aot_copy_callstack_tiny_frame(exec_env, buffer, length, skip_n); } } +#endif // WAMR_ENABLE_COPY_CALLSTACK +#if WASM_ENABLE_DUMP_CALL_STACK != 0 bool aot_create_call_stack(struct WASMExecEnv *exec_env) { @@ -4391,7 +4409,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len) return total_len + 1; } -#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 */ +#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 && WASM_ENABLE_AOT_STACK_FRAME != 0 */ #if WASM_ENABLE_PERF_PROFILING != 0 void diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 7a26be3ea9..0cc66c4b6a 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -10,6 +10,7 @@ #include "../common/wasm_runtime_common.h" #include "../interpreter/wasm_runtime.h" #include "../compilation/aot.h" +#include "platform_common.h" #if WASM_ENABLE_GC != 0 #include "gc_export.h" #endif @@ -777,9 +778,12 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame); bool aot_create_call_stack(struct WASMExecEnv *exec_env); -void -aot_iterate_callstack(WASMExecEnv *exec_env, - const wasm_frame_callback frame_handler, void *user_data); +#if WAMR_ENABLE_COPY_CALLSTACK != 0 +uint32 +aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, + const uint32 length, + const uint32 skip_n); +#endif // WAMR_ENABLE_COPY_CALLSTACK /** * @brief Dump wasm call stack or get the size diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 7046c3b1a5..8d04f37996 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7,6 +7,7 @@ #include "bh_common.h" #include "bh_assert.h" #include "bh_log.h" +#include "platform_common.h" #include "wasm_export.h" #include "wasm_native.h" #include "wasm_runtime_common.h" @@ -1741,18 +1742,19 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env) wasm_exec_env_destroy(exec_env); } -void -wasm_iterate_callstack(const wasm_exec_env_t exec_env, - const wasm_frame_callback frame_callback, - void *user_data) +#if WAMR_ENABLE_COPY_CALLSTACK != 0 +uint32 +wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, + const uint32 length, + const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of - * wasm_iterate_callstack to preserve async-signal-safety + * wasm_copy_callstack to preserve async-signal-safety * - any allocations/freeing memory * - dereferencing any pointers other than: exec_env, exec_env->module_inst, * exec_env->module_inst->module, pointers between stack's bottom and - * top_boundary For more details check wasm_iterate_callstack in + * top_boundary For more details check wasm_copy_callstack in * wasm_export.h */ #if WASM_ENABLE_DUMP_CALL_STACK @@ -1761,17 +1763,18 @@ wasm_iterate_callstack(const wasm_exec_env_t exec_env, #if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { - wasm_interp_iterate_callstack(exec_env, frame_callback, user_data); + return wasm_interp_copy_callstack(exec_env, buffer, length, skip_n); } #endif #if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { - aot_iterate_callstack(exec_env, frame_callback, user_data); + return aot_copy_callstack(exec_env, buffer, length, skip_n); } #endif #endif } +#endif // WAMR_ENABLE_COPY_CALLSTACK bool wasm_runtime_init_thread_env(void) diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 1650615efc..19f11bd48f 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -8,6 +8,7 @@ #include "bh_platform.h" #include "bh_common.h" +#include "platform_common.h" #include "wasm_exec_env.h" #include "wasm_native.h" #include "../include/wasm_export.h" @@ -464,19 +465,6 @@ typedef struct WASMRegisteredModule { typedef package_type_t PackageType; typedef wasm_section_t WASMSection, AOTSection; -typedef struct wasm_frame_t { - /* wasm_instance_t */ - void *instance; - uint32 module_offset; - uint32 func_index; - uint32 func_offset; - const char *func_name_wp; - - uint32 *sp; - uint8 *frame_ref; - uint32 *lp; -} WASMCApiFrame; - #if WASM_ENABLE_JIT != 0 typedef struct LLVMJITOptions { uint32 opt_level; @@ -652,10 +640,11 @@ wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env); -WASM_RUNTIME_API_EXTERN void -wasm_iterate_callstack(const wasm_exec_env_t exec_env, - const wasm_frame_callback frame_handler, - void *user_data); +#if WAMR_ENABLE_COPY_CALLSTACK != 0 +WASM_RUNTIME_API_EXTERN uint32_t +wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, + const uint32 length, const uint32 skip_n); +#endif // WAMR_ENABLE_COPY_CALLSTACK /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon * diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index aba7fd4ec6..18a417cc90 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -126,8 +126,23 @@ typedef WASMFunctionInstanceCommon *wasm_function_inst_t; struct WASMMemoryInstance; typedef struct WASMMemoryInstance *wasm_memory_inst_t; -struct wasm_frame_t; + +typedef struct wasm_frame_t { + /* wasm_instance_t */ + void *instance; + uint32_t module_offset; + uint32_t func_index; + uint32_t func_offset; + const char *func_name_wp; + + uint32_t *sp; + uint8_t *frame_ref; + uint32_t *lp; +} WASMCApiFrame; + +// #if WAMR_ENABLE_COPY_CALLSTACK != 0 typedef struct wasm_frame_t *wasm_frame_ptr_t; +// #endif // WAMR_ENABLE_COPY_CALLSTACK /* WASM section */ typedef struct wasm_section_t { @@ -867,16 +882,10 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); -/** - * Callback to be called on wasm_frame_t*. - * It accepts void* as a context that can be used for closures. - * It returns bool so the iterating can stop when the callback returns false. - * E.g. callback that returns false after processing 100 frames - */ -typedef bool (*wasm_frame_callback)(void *, wasm_frame_ptr_t); +// #if WAMR_ENABLE_COPY_CALLSTACK != 0 /** - * @brief Iterate over callstack frames and execute callback on it. + * @brief Copy callstack frames. * * Caution: This is not a thread-safe function. Ensure the exec_env * is suspended before calling it from another thread. @@ -892,12 +901,16 @@ typedef bool (*wasm_frame_callback)(void *, wasm_frame_ptr_t); * - exec_env->module_inst->module * * @param exec_env the execution environment that containes frames - * @param callback the callback function provided by the user - * @param user_data context for callback provided by the user + * @param buffer the buffer of size equal length * sizeof(frame) to copy frames to + * @param length the number of frames to copy + * @param skip_n the number of frames to skip from the top of the stack + * + * @return number of copied frames */ -WASM_RUNTIME_API_EXTERN void -wasm_iterate_callstack(const wasm_exec_env_t exec_env, - const wasm_frame_callback callback, void *user_data); +WASM_RUNTIME_API_EXTERN uint32_t +wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, + const uint32_t length, const uint32_t skip_n); +// #endif /** * Get the singleton execution environment for the instance. diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 9dd68cca02..c616ac44b4 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -6,6 +6,7 @@ #include "wasm_runtime.h" #include "wasm.h" #include "wasm_exec_env.h" +#include "wasm_export.h" #include "wasm_loader.h" #include "wasm_interp.h" #include "bh_common.h" @@ -4196,46 +4197,57 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, #endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0) \ || (WASM_ENABLE_MEMORY_TRACING != 0) */ -#if WASM_ENABLE_DUMP_CALL_STACK != 0 -void -wasm_interp_iterate_callstack(WASMExecEnv *exec_env, - const wasm_frame_callback frame_handler, - void *user_data) + +#if WAMR_ENABLE_COPY_CALLSTACK != 0 +uint32 +wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, + uint32 length, uint32 skip_n) { /* - * Note for devs: please refrain from such modifications inside of - * wasm_interp_iterate_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and - * top_boundary For more details check wasm_iterate_callstack in - * wasm_export.h - */ + * Note for devs: please refrain from such modifications inside of + * wasm_interp_copy_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_copy_callstack in + * wasm_export.h + */ WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); WASMInterpFrame *cur_frame = wasm_exec_env_get_cur_frame(exec_env); uint8 *top_boundary = exec_env->wasm_stack.top_boundary; uint8 *bottom = exec_env->wasm_stack.bottom; + uint32 count = 0; + WASMCApiFrame record_frame; while (cur_frame && (uint8_t *)cur_frame >= bottom - && (uint8_t *)cur_frame + sizeof(WASMInterpFrame) <= top_boundary) { + && (uint8_t *)cur_frame + sizeof(WASMInterpFrame) <= top_boundary + && count < (skip_n + length)) { if (!cur_frame->function) { cur_frame = cur_frame->prev_frame; continue; } + if (count < skip_n) { + ++count; + cur_frame = cur_frame->prev_frame; + continue; + } record_frame.instance = module_inst; record_frame.module_offset = 0; // It's safe to dereference module_inst->e because "e" is asigned only // once in wasm_instantiate record_frame.func_index = (uint32)(cur_frame->function - module_inst->e->functions); - if (!frame_handler(user_data, &record_frame)) { - break; - } + buffer[count - skip_n] = record_frame; cur_frame = cur_frame->prev_frame; + ++count; } + return count; } +#endif // WAMR_ENABLE_COPY_CALLSTACK + +#if WASM_ENABLE_DUMP_CALL_STACK != 0 bool wasm_interp_create_call_stack(struct WASMExecEnv *exec_env) diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 1b439bac16..84abf63b15 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -12,6 +12,7 @@ #include "bh_hashmap.h" #include "../common/wasm_runtime_common.h" #include "../common/wasm_exec_env.h" +#include "wasm_export.h" #ifdef __cplusplus extern "C" { @@ -731,10 +732,11 @@ wasm_get_table_inst(const WASMModuleInstance *module_inst, uint32 tbl_idx) #if WASM_ENABLE_DUMP_CALL_STACK != 0 -void -wasm_interp_iterate_callstack(WASMExecEnv *exec_env, - const wasm_frame_callback frame_handler, - void *user_data); +#if WAMR_ENABLE_COPY_CALLSTACK != 0 +uint32 +wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, + uint32 length, uint32 skip_n); +#endif // WAMR_ENABLE_COPY_CALLSTACK bool wasm_interp_create_call_stack(struct WASMExecEnv *exec_env); From cc3f0a096bc31f95f78dda5880c7ca0c3e658865 Mon Sep 17 00:00:00 2001 From: "Georgii Rylov :slightly_smiling_face" Date: Mon, 24 Feb 2025 17:33:14 +0000 Subject: [PATCH 16/30] Cleaning up --- build-scripts/config_common.cmake | 4 ++-- core/iwasm/aot/aot_runtime.c | 6 +++--- core/iwasm/aot/aot_runtime.h | 1 - core/iwasm/common/wasm_runtime_common.c | 1 - core/iwasm/common/wasm_runtime_common.h | 1 - core/iwasm/include/wasm_export.h | 4 ---- 6 files changed, 5 insertions(+), 12 deletions(-) diff --git a/build-scripts/config_common.cmake b/build-scripts/config_common.cmake index c7cfff8423..df71198f1b 100644 --- a/build-scripts/config_common.cmake +++ b/build-scripts/config_common.cmake @@ -321,10 +321,10 @@ endif() if (WAMR_ENABLE_COPY_CALLSTACK EQUAL 1) add_definitions (-DWAMR_ENABLE_COPY_CALLSTACK=1) - message(" Copy callstack enabled") + message(" Copy callstack enabled") else () add_definitions (-DWAMR_ENABLE_COPY_CALLSTACK=0) - message(" Copy callstack disabled") + message(" Copy callstack disabled") endif() if (WAMR_BUILD_MEMORY64 EQUAL 1) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 0cd53e4a5c..78b4b60f4b 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4111,11 +4111,11 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, { /* * Note for devs: please refrain from such modifications inside of - * aot_iterate_callstack_tiny_frame + * aot_copy_callstack_tiny_frame * - any allocations/freeing memory * - dereferencing any pointers other than: exec_env, exec_env->module_inst, * exec_env->module_inst->module, pointers between stack's bottom and - * top_boundary For more details check wasm_iterate_callstack in + * top_boundary For more details check wasm_copy_callstack in * wasm_export.h */ uint8 *top_boundary = exec_env->wasm_stack.top_boundary; @@ -4409,7 +4409,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len) return total_len + 1; } -#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 && WASM_ENABLE_AOT_STACK_FRAME != 0 */ +#endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 */ #if WASM_ENABLE_PERF_PROFILING != 0 void diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 0cc66c4b6a..764403f72b 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -10,7 +10,6 @@ #include "../common/wasm_runtime_common.h" #include "../interpreter/wasm_runtime.h" #include "../compilation/aot.h" -#include "platform_common.h" #if WASM_ENABLE_GC != 0 #include "gc_export.h" #endif diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 8d04f37996..5ce16a14d1 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7,7 +7,6 @@ #include "bh_common.h" #include "bh_assert.h" #include "bh_log.h" -#include "platform_common.h" #include "wasm_export.h" #include "wasm_native.h" #include "wasm_runtime_common.h" diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 19f11bd48f..44406cdb45 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -8,7 +8,6 @@ #include "bh_platform.h" #include "bh_common.h" -#include "platform_common.h" #include "wasm_exec_env.h" #include "wasm_native.h" #include "../include/wasm_export.h" diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index 18a417cc90..a17f13f247 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -140,9 +140,7 @@ typedef struct wasm_frame_t { uint32_t *lp; } WASMCApiFrame; -// #if WAMR_ENABLE_COPY_CALLSTACK != 0 typedef struct wasm_frame_t *wasm_frame_ptr_t; -// #endif // WAMR_ENABLE_COPY_CALLSTACK /* WASM section */ typedef struct wasm_section_t { @@ -883,7 +881,6 @@ WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); -// #if WAMR_ENABLE_COPY_CALLSTACK != 0 /** * @brief Copy callstack frames. * @@ -910,7 +907,6 @@ wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); WASM_RUNTIME_API_EXTERN uint32_t wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, const uint32_t length, const uint32_t skip_n); -// #endif /** * Get the singleton execution environment for the instance. From 188eb1c9416444368818fdb269e9b683aa0c4d2a Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Tue, 25 Feb 2025 17:42:06 +0000 Subject: [PATCH 17/30] remove unnecessary includes --- core/iwasm/common/wasm_runtime_common.c | 1 - core/iwasm/interpreter/wasm_runtime.c | 1 - core/iwasm/interpreter/wasm_runtime.h | 1 - 3 files changed, 3 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 5ce16a14d1..a007c41f18 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -7,7 +7,6 @@ #include "bh_common.h" #include "bh_assert.h" #include "bh_log.h" -#include "wasm_export.h" #include "wasm_native.h" #include "wasm_runtime_common.h" #include "wasm_memory.h" diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index c616ac44b4..9431b0bed0 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -6,7 +6,6 @@ #include "wasm_runtime.h" #include "wasm.h" #include "wasm_exec_env.h" -#include "wasm_export.h" #include "wasm_loader.h" #include "wasm_interp.h" #include "bh_common.h" diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 84abf63b15..1cdce10edf 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -12,7 +12,6 @@ #include "bh_hashmap.h" #include "../common/wasm_runtime_common.h" #include "../common/wasm_exec_env.h" -#include "wasm_export.h" #ifdef __cplusplus extern "C" { From 857e6b73c88ffb680764fbe019606200d7e35464 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Wed, 26 Feb 2025 10:57:50 +0000 Subject: [PATCH 18/30] formatting --- core/iwasm/aot/aot_runtime.h | 3 +-- core/iwasm/common/wasm_runtime_common.c | 3 +-- core/iwasm/common/wasm_runtime_common.h | 2 +- core/iwasm/include/wasm_export.h | 7 +++---- core/iwasm/interpreter/wasm_runtime.c | 23 +++++++++++------------ core/iwasm/interpreter/wasm_runtime.h | 2 +- 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 764403f72b..a338cb4ef6 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -780,8 +780,7 @@ aot_create_call_stack(struct WASMExecEnv *exec_env); #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - const uint32 length, - const uint32 skip_n); + const uint32 length, const uint32 skip_n); #endif // WAMR_ENABLE_COPY_CALLSTACK /** diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index a007c41f18..065bff1daa 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1743,8 +1743,7 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env) #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, - const uint32 length, - const uint32 skip_n) + const uint32 length, const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 44406cdb45..61b44aef65 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -642,7 +642,7 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env); #if WAMR_ENABLE_COPY_CALLSTACK != 0 WASM_RUNTIME_API_EXTERN uint32_t wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, - const uint32 length, const uint32 skip_n); + const uint32 length, const uint32 skip_n); #endif // WAMR_ENABLE_COPY_CALLSTACK /* See wasm_export.h for description */ diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index a17f13f247..cacc68e2a3 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -126,7 +126,6 @@ typedef WASMFunctionInstanceCommon *wasm_function_inst_t; struct WASMMemoryInstance; typedef struct WASMMemoryInstance *wasm_memory_inst_t; - typedef struct wasm_frame_t { /* wasm_instance_t */ void *instance; @@ -880,7 +879,6 @@ wasm_runtime_create_exec_env(wasm_module_inst_t module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); - /** * @brief Copy callstack frames. * @@ -898,7 +896,8 @@ wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); * - exec_env->module_inst->module * * @param exec_env the execution environment that containes frames - * @param buffer the buffer of size equal length * sizeof(frame) to copy frames to + * @param buffer the buffer of size equal length * sizeof(frame) to copy frames + * to * @param length the number of frames to copy * @param skip_n the number of frames to skip from the top of the stack * @@ -906,7 +905,7 @@ wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); */ WASM_RUNTIME_API_EXTERN uint32_t wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, - const uint32_t length, const uint32_t skip_n); + const uint32_t length, const uint32_t skip_n); /** * Get the singleton execution environment for the instance. diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 9431b0bed0..0f75eb9f92 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4196,21 +4196,20 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, #endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0) \ || (WASM_ENABLE_MEMORY_TRACING != 0) */ - #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - uint32 length, uint32 skip_n) + uint32 length, uint32 skip_n) { /* - * Note for devs: please refrain from such modifications inside of - * wasm_interp_copy_callstack - * - any allocations/freeing memory - * - dereferencing any pointers other than: exec_env, exec_env->module_inst, - * exec_env->module_inst->module, pointers between stack's bottom and - * top_boundary For more details check wasm_copy_callstack in - * wasm_export.h - */ + * Note for devs: please refrain from such modifications inside of + * wasm_interp_copy_callstack + * - any allocations/freeing memory + * - dereferencing any pointers other than: exec_env, exec_env->module_inst, + * exec_env->module_inst->module, pointers between stack's bottom and + * top_boundary For more details check wasm_copy_callstack in + * wasm_export.h + */ WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); WASMInterpFrame *cur_frame = wasm_exec_env_get_cur_frame(exec_env); @@ -4221,8 +4220,8 @@ wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, WASMCApiFrame record_frame; while (cur_frame && (uint8_t *)cur_frame >= bottom - && (uint8_t *)cur_frame + sizeof(WASMInterpFrame) <= top_boundary - && count < (skip_n + length)) { + && (uint8_t *)cur_frame + sizeof(WASMInterpFrame) <= top_boundary + && count < (skip_n + length)) { if (!cur_frame->function) { cur_frame = cur_frame->prev_frame; continue; diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 1cdce10edf..3747eb80ff 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -734,7 +734,7 @@ wasm_get_table_inst(const WASMModuleInstance *module_inst, uint32 tbl_idx) #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - uint32 length, uint32 skip_n); + uint32 length, uint32 skip_n); #endif // WAMR_ENABLE_COPY_CALLSTACK bool From a5d8c0b477a9a9e57dfb7d1892b46bfee72baeab Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Wed, 26 Feb 2025 11:11:17 +0000 Subject: [PATCH 19/30] define if not defined --- core/iwasm/common/wasm_runtime_common.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index 61b44aef65..f89c8b5eec 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -639,6 +639,10 @@ wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env); +#ifndef WAMR_ENABLE_COPY_CALLSTACK +#define WAMR_ENABLE_COPY_CALLSTACK 0 +#endif + #if WAMR_ENABLE_COPY_CALLSTACK != 0 WASM_RUNTIME_API_EXTERN uint32_t wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, From 99cb6ec27e4a1c5ce01fa57091f6c34118adc693 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Wed, 26 Feb 2025 11:22:31 +0000 Subject: [PATCH 20/30] formatting --- core/iwasm/aot/aot_runtime.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 78b4b60f4b..19e71889dd 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4106,8 +4106,7 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - const uint32 length, - const uint32 skip_n) + const uint32 length, const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of @@ -4137,8 +4136,7 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, AOTTinyFrame *frame = (AOTTinyFrame *)(top - sizeof(AOTTinyFrame)); WASMCApiFrame record_frame; - while (frame && (uint8_t *)frame >= bottom - && count < (skip_n + length)) { + while (frame && (uint8_t *)frame >= bottom && count < (skip_n + length)) { if (count < skip_n) { ++count; frame -= 1; @@ -4156,9 +4154,9 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, } uint32 -aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - const uint32 length, - const uint32 skip_n) +aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, + wasm_frame_ptr_t buffer, const uint32 length, + const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of @@ -4204,11 +4202,9 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer #endif } - uint32 aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - const uint32 length, - const uint32 skip_n) + const uint32 length, const uint32 skip_n) { /* * Note for devs: please refrain from such modifications inside of @@ -4220,7 +4216,8 @@ aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, * wasm_export.h */ if (!is_tiny_frame(exec_env)) { - return aot_copy_callstack_standard_frame(exec_env, buffer, length, skip_n); + return aot_copy_callstack_standard_frame(exec_env, buffer, length, + skip_n); } else { return aot_copy_callstack_tiny_frame(exec_env, buffer, length, skip_n); From fc3077b74d2550d59fcd86d098931782d2e6bf66 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Thu, 27 Feb 2025 14:32:17 +0000 Subject: [PATCH 21/30] address comments --- core/config.h | 4 ++++ core/iwasm/aot/aot_runtime.c | 25 +++++++++++++++---------- core/iwasm/aot/aot_runtime.h | 5 +++-- core/iwasm/common/wasm_runtime_common.c | 11 +++++++---- core/iwasm/common/wasm_runtime_common.h | 9 +++------ core/iwasm/include/wasm_export.h | 11 ++++++----- core/iwasm/interpreter/wasm_runtime.c | 6 ++++-- core/iwasm/interpreter/wasm_runtime.h | 5 +++-- 8 files changed, 45 insertions(+), 31 deletions(-) diff --git a/core/config.h b/core/config.h index fbbbf6771d..d71aaca391 100644 --- a/core/config.h +++ b/core/config.h @@ -193,6 +193,10 @@ #error "Heap aux stack allocation must be enabled for WASI threads" #endif +#ifndef WAMR_ENABLE_COPY_CALLSTACK +#define WAMR_ENABLE_COPY_CALLSTACK 0 +#endif + #ifndef WASM_ENABLE_BASE_LIB #define WASM_ENABLE_BASE_LIB 0 #endif diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 19e71889dd..b06b19af15 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -10,6 +10,7 @@ #include "../common/wasm_runtime_common.h" #include "../common/wasm_memory.h" #include "../interpreter/wasm_runtime.h" +#include #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif @@ -4105,8 +4106,8 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 -aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - const uint32 length, const uint32 skip_n) +aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_t* buffer, + const uint32 length, const uint32 skip_n, char *error_buf, uint32 error_buf_size) { /* * Note for devs: please refrain from such modifications inside of @@ -4126,12 +4127,16 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, bool is_top_index_in_range = top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); if (!is_top_index_in_range) { - return count; + char* err_msg = "Top of the stack pointer is outside of the stack boundaries"; + strncpy(error_buf, err_msg, error_buf_size); + return 0; } bool is_top_aligned_with_bottom = (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; if (!is_top_aligned_with_bottom) { - return count; + char* err_msg = "Top of the stack is not aligned with the bottom"; + strncpy(error_buf, err_msg, error_buf_size); + return 0; } AOTTinyFrame *frame = (AOTTinyFrame *)(top - sizeof(AOTTinyFrame)); @@ -4155,8 +4160,8 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, uint32 aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, - wasm_frame_ptr_t buffer, const uint32 length, - const uint32 skip_n) + wasm_frame_t* buffer, const uint32 length, + const uint32 skip_n, char *error_buf, uint32_t error_buf_size) { /* * Note for devs: please refrain from such modifications inside of @@ -4203,8 +4208,8 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, } uint32 -aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - const uint32 length, const uint32 skip_n) +aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t* buffer, + const uint32 length, const uint32 skip_n, char *error_buf, uint32_t error_buf_size) { /* * Note for devs: please refrain from such modifications inside of @@ -4217,10 +4222,10 @@ aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, */ if (!is_tiny_frame(exec_env)) { return aot_copy_callstack_standard_frame(exec_env, buffer, length, - skip_n); + skip_n, error_buf, error_buf_size); } else { - return aot_copy_callstack_tiny_frame(exec_env, buffer, length, skip_n); + return aot_copy_callstack_tiny_frame(exec_env, buffer, length, skip_n, error_buf, error_buf_size); } } #endif // WAMR_ENABLE_COPY_CALLSTACK diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index a338cb4ef6..5be51c05a7 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -779,8 +779,9 @@ aot_create_call_stack(struct WASMExecEnv *exec_env); #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 -aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - const uint32 length, const uint32 skip_n); +aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t *buffer, + const uint32 length, const uint32 skip_n, char *error_buf, + uint32_t error_buf_size); #endif // WAMR_ENABLE_COPY_CALLSTACK /** diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 065bff1daa..99f0522e99 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1742,8 +1742,9 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env) #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 -wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, - const uint32 length, const uint32 skip_n) +wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_t *buffer, + const uint32 length, const uint32 skip_n, char *error_buf, + uint32_t error_buf_size) { /* * Note for devs: please refrain from such modifications inside of @@ -1760,13 +1761,15 @@ wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, #if WASM_ENABLE_INTERP != 0 if (module_inst->module_type == Wasm_Module_Bytecode) { - return wasm_interp_copy_callstack(exec_env, buffer, length, skip_n); + return wasm_interp_copy_callstack(exec_env, buffer, length, skip_n, + error_buf, error_buf_size); } #endif #if WASM_ENABLE_AOT != 0 if (module_inst->module_type == Wasm_Module_AoT) { - return aot_copy_callstack(exec_env, buffer, length, skip_n); + return aot_copy_callstack(exec_env, buffer, length, skip_n, error_buf, + error_buf_size); } #endif #endif diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index f89c8b5eec..c6425af206 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -639,14 +639,11 @@ wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst, WASM_RUNTIME_API_EXTERN void wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env); -#ifndef WAMR_ENABLE_COPY_CALLSTACK -#define WAMR_ENABLE_COPY_CALLSTACK 0 -#endif - #if WAMR_ENABLE_COPY_CALLSTACK != 0 WASM_RUNTIME_API_EXTERN uint32_t -wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, - const uint32 length, const uint32 skip_n); +wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_t *buffer, + const uint32 length, const uint32 skip_n, char *error_buf, + uint32 error_buf_size); #endif // WAMR_ENABLE_COPY_CALLSTACK /* See wasm_export.h for description */ diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index cacc68e2a3..e63ff01245 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -139,7 +139,7 @@ typedef struct wasm_frame_t { uint32_t *lp; } WASMCApiFrame; -typedef struct wasm_frame_t *wasm_frame_ptr_t; +typedef WASMCApiFrame wasm_frame_t; /* WASM section */ typedef struct wasm_section_t { @@ -896,16 +896,17 @@ wasm_runtime_destroy_exec_env(wasm_exec_env_t exec_env); * - exec_env->module_inst->module * * @param exec_env the execution environment that containes frames - * @param buffer the buffer of size equal length * sizeof(frame) to copy frames - * to + * @param buffer the buffer of size equal length * sizeof(wasm_frame_t) to copy + * frames to * @param length the number of frames to copy * @param skip_n the number of frames to skip from the top of the stack * * @return number of copied frames */ WASM_RUNTIME_API_EXTERN uint32_t -wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_ptr_t buffer, - const uint32_t length, const uint32_t skip_n); +wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_t *buffer, + const uint32_t length, const uint32_t skip_n, + char *error_buf, uint32_t error_buf_size); /** * Get the singleton execution environment for the instance. diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 0f75eb9f92..38fc022925 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -5,6 +5,7 @@ #include "wasm_runtime.h" #include "wasm.h" +#include "wasm_c_api.h" #include "wasm_exec_env.h" #include "wasm_loader.h" #include "wasm_interp.h" @@ -4198,8 +4199,9 @@ wasm_get_module_inst_mem_consumption(const WASMModuleInstance *module_inst, #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 -wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - uint32 length, uint32 skip_n) +wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t *buffer, + uint32 length, uint32 skip_n, char *error_buf, + uint32_t error_buf_size) { /* * Note for devs: please refrain from such modifications inside of diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 3747eb80ff..8d38c8831c 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -733,8 +733,9 @@ wasm_get_table_inst(const WASMModuleInstance *module_inst, uint32 tbl_idx) #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 -wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_ptr_t buffer, - uint32 length, uint32 skip_n); +wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t *buffer, + uint32 length, uint32 skip_n, char *error_buf, + uint32_t error_buf_size); #endif // WAMR_ENABLE_COPY_CALLSTACK bool From bda012e990a78c7efd0a7d6a0630d7d0d1174413 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Thu, 27 Feb 2025 14:35:53 +0000 Subject: [PATCH 22/30] formatting --- core/iwasm/aot/aot_runtime.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index b06b19af15..6335ec4058 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4106,8 +4106,9 @@ aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame) #if WAMR_ENABLE_COPY_CALLSTACK != 0 uint32 -aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_t* buffer, - const uint32 length, const uint32 skip_n, char *error_buf, uint32 error_buf_size) +aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, + const uint32 length, const uint32 skip_n, + char *error_buf, uint32 error_buf_size) { /* * Note for devs: please refrain from such modifications inside of @@ -4127,14 +4128,15 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_t* buffer, bool is_top_index_in_range = top_boundary >= top && top >= (bottom + sizeof(AOTTinyFrame)); if (!is_top_index_in_range) { - char* err_msg = "Top of the stack pointer is outside of the stack boundaries"; + char *err_msg = + "Top of the stack pointer is outside of the stack boundaries"; strncpy(error_buf, err_msg, error_buf_size); return 0; } bool is_top_aligned_with_bottom = (unsigned long)(top - bottom) % sizeof(AOTTinyFrame) == 0; if (!is_top_aligned_with_bottom) { - char* err_msg = "Top of the stack is not aligned with the bottom"; + char *err_msg = "Top of the stack is not aligned with the bottom"; strncpy(error_buf, err_msg, error_buf_size); return 0; } @@ -4159,9 +4161,9 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_t* buffer, } uint32 -aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, - wasm_frame_t* buffer, const uint32 length, - const uint32 skip_n, char *error_buf, uint32_t error_buf_size) +aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, + const uint32 length, const uint32 skip_n, + char *error_buf, uint32_t error_buf_size) { /* * Note for devs: please refrain from such modifications inside of @@ -4208,8 +4210,9 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, } uint32 -aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t* buffer, - const uint32 length, const uint32 skip_n, char *error_buf, uint32_t error_buf_size) +aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t *buffer, + const uint32 length, const uint32 skip_n, char *error_buf, + uint32_t error_buf_size) { /* * Note for devs: please refrain from such modifications inside of @@ -4221,11 +4224,12 @@ aot_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t* buffer, * wasm_export.h */ if (!is_tiny_frame(exec_env)) { - return aot_copy_callstack_standard_frame(exec_env, buffer, length, - skip_n, error_buf, error_buf_size); + return aot_copy_callstack_standard_frame( + exec_env, buffer, length, skip_n, error_buf, error_buf_size); } else { - return aot_copy_callstack_tiny_frame(exec_env, buffer, length, skip_n, error_buf, error_buf_size); + return aot_copy_callstack_tiny_frame(exec_env, buffer, length, skip_n, + error_buf, error_buf_size); } } #endif // WAMR_ENABLE_COPY_CALLSTACK From 0b5084cb632d6f5bf49ce59d6781d8b67166e26d Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Thu, 27 Feb 2025 15:06:31 +0000 Subject: [PATCH 23/30] remove spare diff line --- core/iwasm/interpreter/wasm_runtime.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 38fc022925..609ad4a3ba 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4248,7 +4248,6 @@ wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t *buffer, #endif // WAMR_ENABLE_COPY_CALLSTACK #if WASM_ENABLE_DUMP_CALL_STACK != 0 - bool wasm_interp_create_call_stack(struct WASMExecEnv *exec_env) { From bc00b3e492ecbd76230e2f21ba90c64d5ceb9afa Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 3 Mar 2025 13:36:05 +0000 Subject: [PATCH 24/30] address comments --- core/iwasm/aot/aot_runtime.c | 2 +- core/iwasm/common/wasm_runtime_common.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 6335ec4058..85b686ef9e 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -10,7 +10,6 @@ #include "../common/wasm_runtime_common.h" #include "../common/wasm_memory.h" #include "../interpreter/wasm_runtime.h" -#include #if WASM_ENABLE_SHARED_MEMORY != 0 #include "../common/wasm_shared_memory.h" #endif @@ -4201,6 +4200,7 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, cur_frame = cur_frame->prev_frame; ++count; } + return count; #else /* * TODO: add support for standard frames when GC is enabled diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 99f0522e99..ce4d465283 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1773,6 +1773,10 @@ wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_t *buffer, } #endif #endif + char *err_msg = + "No copy_callstack API was actually executed"; + strncpy(error_buf, err_msg, error_buf_size); + return 0; } #endif // WAMR_ENABLE_COPY_CALLSTACK From ffcc1579ea2f8c665fd50fcd215ad8769ebeeaab Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 3 Mar 2025 13:41:35 +0000 Subject: [PATCH 25/30] clang format --- core/iwasm/common/wasm_runtime_common.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index ce4d465283..d900dc233a 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -1773,8 +1773,7 @@ wasm_copy_callstack(const wasm_exec_env_t exec_env, wasm_frame_t *buffer, } #endif #endif - char *err_msg = - "No copy_callstack API was actually executed"; + char *err_msg = "No copy_callstack API was actually executed"; strncpy(error_buf, err_msg, error_buf_size); return 0; } From 32d0f5503e144bfc5cea5e07c27ed3e12c0c1020 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 3 Mar 2025 14:06:45 +0000 Subject: [PATCH 26/30] spare line --- core/iwasm/interpreter/wasm_runtime.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 609ad4a3ba..b4b55e65ac 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4217,7 +4217,6 @@ wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t *buffer, WASMInterpFrame *cur_frame = wasm_exec_env_get_cur_frame(exec_env); uint8 *top_boundary = exec_env->wasm_stack.top_boundary; uint8 *bottom = exec_env->wasm_stack.bottom; - uint32 count = 0; WASMCApiFrame record_frame; From 6166788c33c8e1244119d29a7e6e5917d06951f2 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 3 Mar 2025 15:17:57 +0000 Subject: [PATCH 27/30] spare lines --- core/iwasm/aot/aot_runtime.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 85b686ef9e..585a30728c 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4121,7 +4121,6 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, uint8 *top_boundary = exec_env->wasm_stack.top_boundary; uint8 *top = exec_env->wasm_stack.top; uint8 *bottom = exec_env->wasm_stack.bottom; - uint32 count = 0; bool is_top_index_in_range = @@ -4180,7 +4179,6 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, uint8 *top_boundary = exec_env->wasm_stack.top_boundary; uint8 *bottom = exec_env->wasm_stack.bottom; uint32 frame_size = (uint32)offsetof(AOTFrame, lp); - uint32 count = 0; WASMCApiFrame record_frame; From 56bb7e715bc335ed344b94a70f2a8057d6ee7ddf Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Wed, 5 Mar 2025 09:11:21 +0000 Subject: [PATCH 28/30] last fixes --- core/iwasm/aot/aot_runtime.c | 4 ++-- core/iwasm/interpreter/wasm_runtime.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 585a30728c..2e267e9509 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4172,6 +4172,7 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, * top_boundary For more details check wasm_iterate_callstack in * wasm_export.h */ + uint32 count = 0; #if WASM_ENABLE_GC == 0 WASMModuleInstance *module_inst = (WASMModuleInstance *)wasm_exec_env_get_module_inst(exec_env); @@ -4179,7 +4180,6 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, uint8 *top_boundary = exec_env->wasm_stack.top_boundary; uint8 *bottom = exec_env->wasm_stack.bottom; uint32 frame_size = (uint32)offsetof(AOTFrame, lp); - uint32 count = 0; WASMCApiFrame record_frame; while (cur_frame && (uint8_t *)cur_frame >= bottom @@ -4198,13 +4198,13 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, cur_frame = cur_frame->prev_frame; ++count; } - return count; #else /* * TODO: add support for standard frames when GC is enabled * now it poses a risk due to variable size of the frame */ #endif + return count; } uint32 diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index b4b55e65ac..400a6ae6c3 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -5,8 +5,6 @@ #include "wasm_runtime.h" #include "wasm.h" -#include "wasm_c_api.h" -#include "wasm_exec_env.h" #include "wasm_loader.h" #include "wasm_interp.h" #include "bh_common.h" From 811f35bf7d4cf4684fdc45a4785ccba9f1ac9d6b Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Wed, 5 Mar 2025 10:23:57 +0000 Subject: [PATCH 29/30] identation --- core/iwasm/aot/aot_runtime.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index 2e267e9509..db9002bb1b 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4172,6 +4172,7 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, * top_boundary For more details check wasm_iterate_callstack in * wasm_export.h */ + uint32 count = 0; #if WASM_ENABLE_GC == 0 WASMModuleInstance *module_inst = From e488345607fb503ce37dd6ce00426406a763ef66 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Wed, 5 Mar 2025 11:47:56 +0000 Subject: [PATCH 30/30] fix bug for return value when skip_n is passed --- core/iwasm/aot/aot_runtime.c | 4 ++-- core/iwasm/interpreter/wasm_runtime.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index db9002bb1b..bf7f51964f 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4155,7 +4155,7 @@ aot_copy_callstack_tiny_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, frame -= 1; ++count; } - return count; + return count >= skip_n ? count - skip_n : 0; } uint32 @@ -4205,7 +4205,7 @@ aot_copy_callstack_standard_frame(WASMExecEnv *exec_env, wasm_frame_t *buffer, * now it poses a risk due to variable size of the frame */ #endif - return count; + return count >= skip_n ? count - skip_n : 0; } uint32 diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 400a6ae6c3..64719f7f5f 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4240,7 +4240,7 @@ wasm_interp_copy_callstack(WASMExecEnv *exec_env, wasm_frame_t *buffer, cur_frame = cur_frame->prev_frame; ++count; } - return count; + return count >= skip_n ? count - skip_n : 0; } #endif // WAMR_ENABLE_COPY_CALLSTACK