Skip to content

G008-componentize-py-resource-drop-binding-unpacks-none-aborting-runtime #234

Description

@xiaozzzZZzzz240

componentize-py: generated resource __exit__ drop binding unpacks None, causing TypeError and a libcomponentize_py_runtime abort instead of an invalid-handle trap under jco

Reproduction of a componentize-py bug where generated Python import bindings mismanage resource handles, so dropping a resource unpacks a None handle pair and aborts the guest runtime under jco.

Both G007:#233 and G008 are componentize-py 0.17.2 bugs from the illegal suite: an intentional invalid resource-handle operation should trap cleanly with invalid handle, but instead the Python side sees a None handle and aborts. They differ in code path: G007 crashes while lowering a handle into an imported method call — the Rust runtime's ToCanonHandle unwraps a TypeError and panics at lib.rs:1217. G008 crashes while dropping a resource — the generated exit binding unpacks a None handle pair, and the runtime panics at lib.rs:515. G007 is filed upstream (issue #233); G008 isn't yet.

Environment

component version
OS macOS 15.7 (Darwin 24.6.0), x86_64
jco 1.16.1 (source checkout, tag jco-v1.16.1)
Node.js v22.22.2
wac wac-cli 0.8.1
componentize-py componentize-py 0.17.2

Steps to reproduce

The full chain is: compile the guest sources into a provider component and a consumer component, compose them with wac, then run the composed component. Prebuilt copies of every artifact are included (components/provider.wasm, components/consumer.wasm, composed.wasm), so you can also skip straight to step 5.

Github repo:https://github.com/xiaozzzZZzzz240/G008-componentize-py-resource-drop-binding-unpacks-none-aborting-runtime

  1. Clone this repository:

    git clone <THIS_REPO_URL>
    cd <THIS_REPO_DIR>
  2. Compile the provider component from the JavaScript sources in src/provider-JavaScript/ (toolchain versions in the table above; the WIT package is in wit/):

    jco componentize src/provider-JavaScript/world7-t8b6pjs1_generated.js --wit wit --world-name world7-t8b6pjs1 --disable http fetch-event --out components/provider.wasm
  3. Compile the consumer component from the Python sources in src/consumer-Python/:

    (cd src/consumer-Python && componentize-py --wit-path ../../wit --world world7b-awp0lf7x componentize world7b-awp0lf7x_generated -o ../../components/consumer.wasm)
  4. Compose the two components into one runnable component with wac 0.8.1:

    wac plug components/consumer.wasm --plug components/provider.wasm -o composed.wasm
  5. Run the composed component with jco:

    npm install -g @bytecodealliance/jco@1.16.1
    jco run composed.wasm

Expected result

This test case intentionally performs an invalid resource-handle operation at the very end, so the expected behavior is: print the prefix below, then trap cleanly with invalid handle.

"resinst0"
"resinst0"
resource("temres7")
resource("temres9")
true
"alpha"
resource("temres111")
true
true
"alpha"
"bar"
true
true
"temres150"
trap(invalid handle)

Actual result

Under jco the same composed.wasm exits with rc=1. stdout:

"resinst0"
"temres2"
resource("resinst0")
resource("temres9")
true
"alpha"
resource("temres111")
true
true
"alpha"
"bar"
true
true
"temres7"

stderr:

Traceback (most recent call last):
  File "/0/world7b-awp0lf7x_generated.py", line 264, in run
  File "/0/world7b-awp0lf7x_generated.py", line 22, in _skel_drop
  File "/world/wit_world/imports/itf_hthdp03eh5.py", line 56, in __exit__
TypeError: cannot unpack non-iterable NoneType object

thread '<unnamed>' panicked at runtime/src/lib.rs:515:25:
Python function threw an unexpected exception
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
RuntimeError: unreachable
    at libc.so.abort (wasm://wasm/libc.so-001e65fe:wasm-function[458]:0x1041d)
    at wasm://wasm/02947686:wasm-function[306]:0xf8e8
    at libcomponentize_py_runtime.so.std::sys::pal::wasi::helpers::abort_internal::h118dde344a79086c (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[2193]:0xceb72)
    at libcomponentize_py_runtime.so.std::process::abort::h2738589d00d7233e (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[1645]:0xb87f6)
    at libcomponentize_py_runtime.so.__rustc::__rust_abort (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[2002]:0xc7330)
    at libcomponentize_py_runtime.so.__rustc::__rust_start_panic (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[2208]:0xcfc4c)
    at libcomponentize_py_runtime.so.__rustc::rust_panic (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[2035]:0xc8a1e)
    at libcomponentize_py_runtime.so.std::panicking::rust_panic_with_hook::h02d894de16d94192 (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[2034]:0xc899c)
    at libcomponentize_py_runtime.so.std::panicking::begin_panic_handler::_$u7b$$u7b$closure$u7d$$u7d$::he125d401eefa4f33 (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[1573]:0xb451a)
    at libcomponentize_py_runtime.so.std::sys::backtrace::__rust_end_short_backtrace::h31a9416a2c4ea1cb (wasm://wasm/libcomponentize_py_runtime.so-0052fcc2:wasm-function[1572]:0xb4442)

wasmtime on the exact same file: rc=134

"resinst0"
"resinst0"
resource("temres7")
resource("temres9")
true
"alpha"
resource("temres111")
true
true
"alpha"
"bar"
true
true
"temres150"

--- stderr ---
Traceback (most recent call last):
  File "/0/world7b-awp0lf7x_generated.py", line 264, in run
  File "/0/world7b-awp0lf7x_generated.py", line 22, in _skel_drop
  File "/world/wit_world/imports/itf_hthdp03eh5.py", line 56, in __exit__
TypeError: cannot unpack non-iterable NoneType object

thread '<unnamed>' panicked at runtime/src/lib.rs:515:25:
Python function threw an unexpected exception
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: failed to run main module `/Users/myuser/WASM/myProject/Wasm_component_testing/mycode/execute/reportrepo/G008-componentize-py-resource-drop-binding-unpacks-none-aborting-runtime/composed.wasm`

Caused by:
    0: failed to invoke `run` function
    1: error while executing at wasm backtrace:
           0: 0x2e3e21e - libc.so!abort
           1: 0xccb64e - <unknown>!<wasm function 306>
           2: 0x17ece14 - libcomponentize_py_runtime.so!std::sys::pal::wasi::helpers::abort_internal::h118dde344a79086c
           3: 0x17d6a98 - libcomponentize_py_runtime.so!std::process::abort::h2738589d00d7233e
           4: 0x17e55d2 - libcomponentize_py_runtime.so!__rustc::__rust_abort
           5: 0x17edeee - libcomponentize_py_runtime.so!__rustc::__rust_start_panic
           6: 0x17e6cc0 - libcomponentize_py_runtime.so!__rustc::rust_panic
           7: 0x17e6c3e - libcomponentize_py_runtime.so!std::panicking::rust_panic_with_hook::h02d894de16d94192
           8: 0x17d27bc - libcomponentize_py_runtime.so!std::panicking::begin_panic_handler::_$u7b$$u7b$closure$u7d$$u7d$::he125d401eefa4f33
           9: 0x17d26e4 - libcomponentize_py_runtime.so!std::sys::backtrace::__rust_end_short_backtrace::h31a9416a2c4ea1cb
          10: 0x17e6536 - libcomponentize_py_runtime.so!__rustc::rust_begin_unwind
          11: 0x1807b5f - libcomponentize_py_runtime.so!core::panicking::panic_fmt::h52dbee1629029330
          12: 0x175ea2d - libcomponentize_py_runtime.so!componentize-py#Dispatch
          13: 0x2eb330e - libcomponentize_py_bindings.so!wasi:cli/run@0.2.0#run-export
       note: using the `WASMTIME_BACKTRACE_DETAILS=1` environment variable may show more debugging information
    2: wasm trap: wasm `unreachable` instruction executed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions