Stream: git-wasmtime

Topic: wasmtime / PR #14304 Use bulk libunwind section registrat...


view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj opened PR #14304 from macovedj:bulk-libunwind-compat to bytecodealliance:main:

I encountered performance issues when working with large Wasm modules similar to those described in issue #6541. That issue led to a configuration fix making it possible to opt out of native unwinding on macOS.

However, libunwind provides whole-section APIs that Wasmtime currently doesn’t use: __unw_add_dynamic_eh_frame_section and __unw_remove_dynamic_eh_frame_section. These allow registering full .eh_frame sections rather than registering each frame description entry (FDE) individually.

Testing against my large Wasm module, I measured the following median total process wall times, including teardown. Most of the improvement comes from teardown after the workload finishes.

Host / unwinder Backend Metadata: before → after Object: before → after
ARM64 macOS, Apple libunwind Cranelift 2.941 s → 1.000 s 5.248 s → 3.340 s
ARM64 macOS, Apple libunwind Winch 2.011 s → 1.923 s 6.788 s → 6.590 s
x86-64 Linux, LLVM libunwind Cranelift 4.015 s → 1.266 s 7.207 s → 4.470 s
x86-64 Linux, LLVM libunwind Winch 4.569 s → 1.842 s 9.034 s → 6.296 s

For the x86-64 Linux measurements, I explicitly selected LLVM libunwind instead of the machine’s default libgcc. LLVM libunwind is also used by configurations such as Rust’s default static musl builds, Chimera Linux, and Gentoo’s LLVM profiles. The existing libgcc registration path is unchanged.

This PR checks whether both batch registration APIs are available and uses them when they are, falling back to the existing APIs otherwise.

The native_unwind_walks_nested_wasm_frames test currently runs on x86-64 macOS and Linux. Developing it exposed an existing native stack-walking bug on ARM64 macOS, addressed in https://github.com/bytecodealliance/wasmtime/pull/14303. Once that fix lands, I can enable the test on ARM64 macOS as well.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj requested pchickey for a review on PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj requested wasmtime-core-reviewers for a review on PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:59):

macovedj updated PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 14:46):

github-actions[bot] added the label wasmtime:api on PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 18:09):

pchickey unassigned pchickey from PR #14304 Use bulk libunwind section registration when available.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 18:09):

pchickey requested alexcrichton for a review on PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 18:42):

:memo: alexcrichton submitted PR review:

Thanks! At a high level this all seems fine to me, but I'll admit I'm pretty lost on the internals here. There's quite a lot going on here on the C side in addition to the testing side, and I'd like to better understand what's happening before landing this ideally. Some questions I have:

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 19:03):

bjorn3 commented on PR #14304:

Can you explain that more fully? Why aren't weak symbols used (like they are for __unw_add_dynamic_fde) or alternatively if they are used what are the consequences in terms of vesion support and such?

On macOS the linker still needs weak symbols to exist at link time unless you pass a cli arg to allow them to be undefined. So if you link against an older SDK without the symbol listed you get an error. Unless you pass extra cli args, weak symbols only allow the symbol to be missing later at runtime when running on an older OS.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 20:44):

macovedj requested alexcrichton for a review on PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 20:45):

macovedj requested wasmtime-default-reviewers for a review on PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 20:45):

macovedj updated PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 20:45):

macovedj commented on PR #14304:

Thanks for the review! I’ve implemented your suggested refactor, and I think it’s a lot cleaner now.

I moved the macOS API lookup and caching into Rust and replaced wasmtime_using_libunwind with a small C helper that returns the weakly linked function pointers. C now handles just the weak linkage, while Rust handles detection and registration.

I also made UnwindRegistration the enum directly, with separate variants for libgcc’s single registration, individual FDE registrations, and whole-section registration.

On the SDK question, @bjorn3 ’s explanation matches what I observed: the unmodified macOS 11.3 SDK includes __unw_add_dynamic_fde but lacks the section APIs. Weak imports for those newer APIs fail at link time with that SDK. Runtime lookup avoids requiring a newer build SDK while allowing us to use the section APIs when available at runtime. I clarified that in the code comment.

I removed the C compilation harness and fixtures and moved the behavioral tests into tests/all/module.rs. Previously, both tests shared a mutex to prevent interference from reusing dropped modules’ memory addresses. After moving them into the larger suite, unrelated tests wouldn’t acquire that mutex, so I changed the registration/removal test to run in a subprocess. I reproduced the address-reuse race with another thread allocating a module between the drop and the lookup. I also switched native stack capture to backtrace.

I deleted a couple fixtures that covered cases such as only one section API being available and mismatched unwinder providers. I don't suspect that those pathological cases are actually common on real platforms, but I haven't confirmed. If we wanted, we could consider adding a CI job that explicitly opts into libunwind on Linux, but I figured I'd check if that was actually worth the added CI cost before including it.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 20:57):

macovedj updated PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 21:22):

:memo: alexcrichton submitted PR review:

Thanks! For comparison how old is 11.3? I'm not actually sure what the current sdk version number is...

view this post on Zulip Wasmtime GitHub notifications bot (Sep 11 2026 at 21:22):

:speech_balloon: alexcrichton created PR review comment:

Oh I'm sorry about that I didn't realize that this was part of the previous tests. For use cases like this it's ok to have separate test suite files (e.g. tests/*.rs) and we've already got preexisting ones as rlimited-memory.rs and disable_host_trap_handler.rs. Could this test move to one of those dedicated files with a file-level comment explaining why it's a standalone test? That's generally easier to work with than the exec-self here.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:01):

macovedj updated PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:12):

macovedj commented on PR #14304:

Thanks! For comparison how old is 11.3? I'm not actually sure what the current sdk version number is...

I'm currently working with 26.5. Looks like it was released in April 2021, so a little over 5 years...

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:27):

:thumbs_up: alexcrichton submitted PR review:

Ok seems reasonable to keep compat with that for now and we can remove it in the future should it become onerous

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:27):

alexcrichton added PR #14304 Use bulk libunwind section registration when available to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:53):

:check: alexcrichton merged PR #14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:53):

alexcrichton removed PR #14304 Use bulk libunwind section registration when available from the merge queue.


Last updated: Sep 20 2026 at 18:08 UTC