-
Notifications
You must be signed in to change notification settings - Fork 44
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
Add segfault catcher. #1053
base: main
Are you sure you want to change the base?
Add segfault catcher. #1053
Conversation
Benchmark results Main vs HEAD.Base
Head
Base
Head
Base
Head
Base
Head
Base
Head
Base
Head
|
Benchmarking resultsBenchmark for program
|
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
Cairo-vm (Rust, Cairo 1) |
20.517 ± 0.139 | 20.415 | 20.874 | 5.49 ± 0.05 |
cairo-native (embedded AOT) |
3.739 ± 0.018 | 3.700 | 3.766 | 1.00 |
cairo-native (embedded JIT using LLVM's ORC Engine) |
3.798 ± 0.019 | 3.770 | 3.821 | 1.02 ± 0.01 |
Benchmark for program dict_snapshot
Open benchmarks
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
Cairo-vm (Rust, Cairo 1) |
5.750 ± 0.043 | 5.672 | 5.794 | 1.60 ± 0.02 |
cairo-native (embedded AOT) |
3.594 ± 0.025 | 3.563 | 3.650 | 1.00 |
cairo-native (embedded JIT using LLVM's ORC Engine) |
3.677 ± 0.012 | 3.657 | 3.695 | 1.02 ± 0.01 |
Benchmark for program factorial_2M
Open benchmarks
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
Cairo-vm (Rust, Cairo 1) |
14.203 ± 0.104 | 14.059 | 14.454 | 3.55 ± 0.03 |
cairo-native (embedded AOT) |
4.000 ± 0.024 | 3.970 | 4.044 | 1.00 |
cairo-native (embedded JIT using LLVM's ORC Engine) |
4.040 ± 0.036 | 4.015 | 4.138 | 1.01 ± 0.01 |
Benchmark for program fib_2M
Open benchmarks
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
Cairo-vm (Rust, Cairo 1) |
14.094 ± 0.034 | 14.040 | 14.143 | 3.97 ± 0.03 |
cairo-native (embedded AOT) |
3.551 ± 0.027 | 3.508 | 3.589 | 1.00 |
cairo-native (embedded JIT using LLVM's ORC Engine) |
3.578 ± 0.021 | 3.544 | 3.610 | 1.01 ± 0.01 |
Benchmark for program linear_search
Open benchmarks
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
Cairo-vm (Rust, Cairo 1) |
5.733 ± 0.026 | 5.679 | 5.781 | 1.57 ± 0.01 |
cairo-native (embedded AOT) |
3.641 ± 0.013 | 3.624 | 3.660 | 1.00 |
cairo-native (embedded JIT using LLVM's ORC Engine) |
3.772 ± 0.031 | 3.736 | 3.844 | 1.04 ± 0.01 |
Benchmark for program logistic_map
Open benchmarks
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
Cairo-vm (Rust, Cairo 1) |
5.678 ± 0.041 | 5.621 | 5.759 | 1.54 ± 0.02 |
cairo-native (embedded AOT) |
3.684 ± 0.024 | 3.659 | 3.748 | 1.00 |
cairo-native (embedded JIT using LLVM's ORC Engine) |
3.884 ± 0.038 | 3.850 | 3.967 | 1.05 ± 0.01 |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1053 +/- ##
==========================================
- Coverage 80.93% 80.87% -0.06%
==========================================
Files 108 108
Lines 29605 29599 -6
==========================================
- Hits 23961 23939 -22
- Misses 5644 5660 +16 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to add a test that segfaults? Or too tricky?
It is technically possible, but it'd require a way to initialize the signal handler globally when testing, potentially messing up the test harness's signal handler (ex. when using nextest). Instead, if we just initialized every (segfaulting) test then we'd end up initializing it multiple times, which could also cause problems. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add some comments explaining how it works? For someone not familiar with the signal or de jmp API (like me), its a bit tricky to understand.
Is this implementation threadsafe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hadn't really considered thread safety. I think it should be safe because the jmp_buf is a thread local, so it shouldn't be possible to transfer it across thread boundaries.
src/executor/contract.rs
Outdated
unsafe { | ||
crate::utils::safe_runner::run_safely(|| unsafe { | ||
invoke_trampoline( | ||
function_ptr, | ||
invoke_data.as_ptr().cast(), | ||
invoke_data.len() >> 3, | ||
ret_registers.as_mut_ptr(), | ||
); | ||
} | ||
}) | ||
.map_err(Error::SafeRunner)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we gate this under a feature flag? Or maybe provide an API instead of using directly?
unsafe extern "C" fn segfault_handler(_sig: c_int, _info: &siginfo_t, _context: &mut ucontext_t) { | ||
match STATE.with(|x| &mut *x.get()) { | ||
SafeRunnerState::Inactive => libc::abort(), | ||
SafeRunnerState::Active(jmp_buf) => longjmp(jmp_buf.as_mut_ptr().cast(), 1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 1
value is then returned as jmp_ret
in the setjmp
call, right? If so, could you add a small comment mentioning it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it does exactly that. Even if you pass a 0 to longjmp
it'll return a 1. In other words, the only time it'll return 0 is when setjmp
is initializing stuff, but never when returning from a longjmp
.
2bbdaff
to
d005b80
Compare
Simplified version of #959. Does not attempt to grow the stack, just catches segfaults and returns an error.
Checklist