Bug 290681
| Summary: | "call_indirect to a null table entry" after 230257 wasm table grows | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | terrorjack |
| Component: | WebAssembly | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW | ||
| Severity: | Normal | CC: | terrorjack, webkit-bug-importer, ysuzuki |
| Priority: | P2 | Keywords: | InRadar |
| Version: | Safari Technology Preview | ||
| Hardware: | Mac (Apple Silicon) | ||
| OS: | macOS 15 | ||
terrorjack
Hi folks, I'm running a wasm dynamic linker written in JS (https://gitlab.haskell.org/ghc/ghc/-/blob/master/utils/jsffi/dyld.mjs) in browser, which allocates an anyfunc table with initial size 1, and invokes table.grow(1, func) 230257 times, and the table growth is interleaved with wasm execution. Now, it works fine in firefox/chrome, but in safari (both 18.3.1 and TP215) I'm seeing spurious "call_indirect to a null table entry" panics when the wasm code attempts to call_indirect into small indices of the table. The panic can be worked around by allocating a huge table upfront and never growing it, only filling the slots in the dynamic linker logic.
I can provide more detailed instructions to reproduce if it helps, but it's not a single script and a bunch of wasm payloads, it requires installing a bunch of tools to proceed. So I'm just reporting the above information for now to see if it rings any bells.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Radar WebKit Bug Importer
<rdar://problem/148665183>
Yusuke Suzuki
Thanks! Can you attach the test case to reproduce the issue?
terrorjack
Hi, I've created a relocatable binary distribution of the ghc wasm toolchain on aarch64-darwin at https://drive.google.com/file/d/13Gi_-1lMqD-HUJhb_4YVgYffPteWqPVY/view?usp=sharing. Here are the steps to use it to reproduce the issue:
- Download and extract it to a temporary path
- `export PATH=$PWD/.ghc-wasm/nodejs/bin:$PATH`
- `export NODE_PATH=$PWD/.ghc-wasm/nodejs/lib/node_modules`
- `./.ghc-wasm/wasm32-wasi-ghc/bin/wasm32-wasi-ghc --interactive -fghci-browser -fghci-browser-port=8000`
You'll see a prompt like `Open http://127.0.0.1:8000/main.html or import http://127.0.0.1:8000/main.js to boot ghci`. You can now open Safari and open the inspector panel, open the page as instructed, the `wasm32-wasi-ghc` console will be unfrozen and accept user input. Now, the crash in this bug can be reproduced by typing the following two lines:
- `foreign import javascript "new Promise(res => setTimeout(res, 1024, 114514))" test :: IO Int`
- `test`
You can also modify `./.ghc-wasm/wasm32-wasi-ghc/lib/dyld.mjs` script in place, that's the dynamic linker program we're using. Let me know if there's any difficulty in the reproducer, thanks a lot!
terrorjack
So it turns out that the table.grow() JS API is broken, but the table.grow wasm instruction works, so this issue can be worked around by calling a wasm function that's in charge of growing the table. I've implemented the workaround in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/14988, but it would still be nice for upstream to fix it some day.