Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graceful Handling of OOM in table.grow #5394

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

charmitro
Copy link
Contributor

This commit modifies the grow method in VMTable to handle out-of-memory (OOM) errors gracefully by using fallible memory reservation. Previously, Vec::resize would panic on OOM, causing a crash instead of returning -1 as required by the WebAssembly specification. The changes ensure that:

  1. Fallible Memory Reservation
    • "try_reserve_exact" is used to check if the system can allocate the required memory before resizing.
    • If allocation fails, the method returns None, adhering to the spec.
  2. Safe Resize
    • If memory reservation succeeds, resize is performed safely without panicking
  3. Platform-Specific Behavior
    • On macOS, due to virtual memory overcommit, large allocations may succeed unexpectedly
    • On Linux, stricter memory allocation checks prevent overcommit, correctly failing with -1

This fix addresses issues where large allocations (e.g., 0xff_ff_ff_ff) would crash on Linux due to stricter memory allocation checks, while macOS's virtual memory overcommit might mask the problem.

Closes #5297

This commit modifies the grow method in VMTable to handle
out-of-memory (OOM) errors gracefully by using fallible memory
reservation. Previously, Vec::resize would panic on OOM, causing a
crash instead of returning -1 as required by the WebAssembly
specification. The changes ensure that:

1. Fallible Memory Reservation
   * "try_reserve_exact" is used to check if the system can allocate
     the required memory before resizing.
   * If allocation fails, the method returns None, adhering to the
     spec.
2. Safe Resize
   * If memory reservation succeeds, resize is performed safely
     without panicking

This fix addresses issues where large allocations (e.g.,
0xff_ff_ff_ff) would crash on Linux due to stricter memory allocation
checks, while macOS's virtual memory overcommit might mask the
problem.

Signed-off-by: Charalampos Mitrodimas <[email protected]>
Adds a new test to verify table.grow behavior with very large
delta (0xff_ff_ff_ff) across different platforms. On Linux this should
return -1, while on macOS it returns 0. The test includes
platform-specific assertions to verify this behavior.
Comment on lines +35 to +47
#[cfg(target_os = "macos")]
assert_eq!(
result[0],
wasmer::Value::I32(0),
"On macOS, table.grow should return 0"
);

#[cfg(target_os = "linux")]
assert_eq!(
result[0],
wasmer::Value::I32(-1),
"On Linux, table.grow should return -1"
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't happen (different output for same program, under different OSs). Good catch.
We need to make the API deterministic no matter what OS is running on

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure/haven't put more thought into whether this is possible.

Pasting the scenarios here (before this PRs changes), since I have them handy, for some food for thought.

Linux:

  • Linux with vm.overcommit_memory = 0 results in memory allocation of ... bytes failed
  • Linux with vm.overcommit_memory = 1 results in killed
  • Linux with vm.overcommit_memory = 2 results in memory allocation of ... bytes failed

MacOS always works without exiting.

Maybe there's not much we can do here. But doing nothing will not adere the specification (i.e. The table.grow instruction grows table by a given delta and returns the previous size, or −1 if enough space cannot be allocated).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

IOT instruction (core dumped) when using table.grow
2 participants