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

Fix sdk assertion macros #660

Conversation

tchataigner
Copy link
Contributor

While working on the High level Rust SDK I found out that low level macro were not working as expected. I started to fix their behavior but also found a problem in how things were handled.

At the time when we developed the macros, it seemed relevant to @raulk and myself to use catch_unwind to prevent a panic on an assert. But it seems that catch_unwind doesn't work in in WASM as it's behavior is panic=abort (rust-lang/rust#58874) which will throw an error before we have time to call the abort syscall.

I do not really see an easy way of solving this, opening a PR to share it with the team and (maybe) get some start of a solution.

@codecov-commenter
Copy link

codecov-commenter commented Jul 12, 2022

Codecov Report

Merging #660 (402af40) into master (e9657a7) will decrease coverage by 0.01%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #660      +/-   ##
==========================================
- Coverage   51.06%   51.05%   -0.02%     
==========================================
  Files         120      120              
  Lines        9694     9694              
==========================================
- Hits         4950     4949       -1     
- Misses       4744     4745       +1     
Impacted Files Coverage Δ
ipld/amt/src/node.rs 86.56% <0.00%> (-0.26%) ⬇️

@Stebalien
Copy link
Member

@Stebalien
Copy link
Member

Basically:

  1. Set panic=unwind (on build).
  2. Add a panic hook that aborts.

Comment on lines 25 to 28
let res = std::panic::catch_unwind(|| {
core::assert!($cond);
});
if res.is_err() {
let panic_msg = match res.err() {
Some(err) => match err.downcast::<String>() {
Ok(panic_msg_box) => Some(panic_msg_box.as_str()),
Err(err) => None,
},
None => unreachable!(),
};

$crate::vm::abort(
fvm_shared::error::ExitCode::USR_ASSERTION_FAILED.value(),
panic_msg,
);
}
$crate::testing::handle_assert_err(res);
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason we need to assert than catch it? Can't we just re-implement assert and abort directly? The implementation should be pretty simple.

@Stebalien
Copy link
Member

Is there any reason we need to assert than catch it? Can't we just re-implement assert and abort directly? The implementation should be pretty simple.

Alternatively, just drop the wrapping entirely. I.e.:

  1. Let the user call the builtin assert.
  2. Register a panic hook in invoke to turn all panics into aborts.

@tchataigner
Copy link
Contributor Author

Thanks for the tips @Stebalien ! Used them to fix it 👍

@tchataigner tchataigner marked this pull request as ready for review July 22, 2022 12:37
@raulk
Copy link
Member

raulk commented Aug 15, 2022

Conflicts developed :-(

@Stebalien
Copy link
Member

I think there's some confusion here. We shouldn't be setting a panic hook than immediately calling assert.

  • We should, ideally, not be overriding assert at all, instead setting a panic hook on invoke.
  • Or... we could override the assert macro to immediately call vm::abort.

But the former would be better.

However, setting a hook a hook, then immediately asserting, is a very round-about way of going about this. Does that make sense?

@Kubuxu
Copy link

Kubuxu commented Aug 17, 2022

Basically:
Set panic=unwind (on build).
Add a panic hook that aborts.

Does that mean we carry unwind information within actor bundles?

@Stebalien
Copy link
Member

Does that mean we carry unwind information within actor bundles?

Not the deployed ones, no. However, asserts will still give you nice errors even without actual backtraces.

Stebalien added a commit that referenced this pull request Sep 19, 2022
This replaces the custom assert macros. Instead of overriding the assert
macros, the user would:

1. Call `fvm_sdk::initialize()` at the top of their actor/tests.
2. Use the default `assert` macros.

replaces #660
@Stebalien
Copy link
Member

See #896.

@Stebalien Stebalien closed this Sep 19, 2022
Stebalien added a commit that referenced this pull request Oct 6, 2022
This replaces the custom assert macros. Instead of overriding the assert
macros, the user would:

1. Call `fvm_sdk::initialize()` at the top of their actor/tests.
2. Use the default `assert` macros.

replaces #660
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.

5 participants