[Web] Fix static init order in WASM runtime to prevent GetKwargsObject crash#18968
[Web] Fix static init order in WASM runtime to prevent GetKwargsObject crash#18968gnguralnick wants to merge 1 commit intoapache:mainfrom
Conversation
…t crash After tvm-ffi v0.1.9 (6b39efb), ObjectDef::~ObjectDef() calls AutoRegisterInit() which eagerly resolves ffi.GetKwargsObject via GetGlobalRequired(). In the WASM build, all .cc files are #include'd into a single translation unit (wasm_runtime.cc), so __attribute__((constructor)) functions run in source order. Previously, runtime files like file_utils.cc, profiling.cc, and rpc_session.cc (which use ObjectDef in their static init blocks) were included before object.cc (which registers ffi.GetKwargsObject). This caused a fatal error during _initialize because the ObjectDef destructors ran before the function they depend on was registered. Fix: move all tvm-ffi core includes before the runtime files so that ffi.GetKwargsObject is registered before any ObjectDef destructor needs it.
There was a problem hiding this comment.
Code Review
This pull request reorders the #include statements in web/emcc/wasm_runtime.cc to ensure that TVM FFI core components are initialized before other runtime components, preventing static initialization failures in WASM. Feedback suggests further refining the internal order of the FFI includes by moving object.cc before other components like container.cc and function.cc to ensure the object system is fully registered before it is used by subsequent FFI modules.
| #include "3rdparty/tvm-ffi/src/ffi/backtrace.cc" | ||
| #include "3rdparty/tvm-ffi/src/ffi/container.cc" | ||
| #include "3rdparty/tvm-ffi/src/ffi/dtype.cc" | ||
| #include "3rdparty/tvm-ffi/src/ffi/error.cc" | ||
| #include "3rdparty/tvm-ffi/src/ffi/function.cc" | ||
| #include "3rdparty/tvm-ffi/src/ffi/object.cc" | ||
| #include "3rdparty/tvm-ffi/src/ffi/tensor.cc" |
There was a problem hiding this comment.
To ensure robustness against static initialization order issues within the FFI core itself, object.cc should be included before other FFI components that might use the object system (such as container.cc, function.cc, or tensor.cc). Since object.cc registers ffi.GetKwargsObject, any static initialization in the subsequent files that triggers ObjectDef logic will be safe if object.cc is included first. This aligns with the logic described in the PR summary regarding the dependency on ffi.GetKwargsObject during static initialization.
| #include "3rdparty/tvm-ffi/src/ffi/backtrace.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/container.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/dtype.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/error.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/function.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/object.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/tensor.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/backtrace.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/error.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/object.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/container.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/dtype.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/function.cc" | |
| #include "3rdparty/tvm-ffi/src/ffi/tensor.cc" |
There was a problem hiding this comment.
I checked the actual static init blocks in the FFI core files: container.cc, function.cc, and tensor.cc all use GlobalDef() (not ObjectDef), and dtype.cc/error.cc have no static init blocks at all. So none of them depend on ffi.GetKwargsObject during initialization, and the ordering within the FFI core group doesn't matter for correctness. The critical ordering is FFI core before runtime files (which do use ObjectDef), which is already handled.
|
@gnguralnick I updated the behavior here: apache/tvm-ffi#519. So this should be fixed once this lands: #18967. Is this still an issue? |
Summary
After tvm-ffi v0.1.9 (
6b39efb),ObjectDef::~ObjectDef()callsAutoRegisterInit()which eagerly resolvesffi.GetKwargsObjectviaGetGlobalRequired(). In the WASM build, all.ccfiles are#include'd into a single translation unit (wasm_runtime.cc), so__attribute__((constructor))functions run in deterministic source order.Runtime files like
file_utils.cc,profiling.cc, andrpc_session.cc(which useObjectDefin their static init blocks) were included beforeobject.cc(which registersffi.GetKwargsObject). This caused a fatalValueError: Function ffi.GetKwargsObject not foundduring WASM_initialize, crashing before the module could load.Fix: Move all tvm-ffi core includes before the runtime files so that
ffi.GetKwargsObjectis registered before anyObjectDefdestructor needs it.Error reproduced
This affects all WebGPU model compilation since the tvm-ffi bump in #18938.
Test plan