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

Allow unwinding from OOM hooks #92535

Merged
merged 3 commits into from
Feb 6, 2022
Merged

Conversation

Amanieu
Copy link
Member

@Amanieu Amanieu commented Jan 3, 2022

This is split off from #88098 and contains just the bare minimum to allow specifying a custom OOM hook with set_alloc_error_hook which unwinds instead of aborting.

See #88098 for an actual command-line flag which switches the default OOM behavior to unwind instead of aborting.

Previous perf results show a negligible impact on performance.

@rust-highfive
Copy link
Collaborator

r? @m-ou-se

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 3, 2022
@Amanieu Amanieu mentioned this pull request Jan 3, 2022
@m-ou-se
Copy link
Member

m-ou-se commented Jan 5, 2022

From your description I assumed that this program would abort in the current version of rust, and would succeed after the change in this PR:

#![feature(alloc_error_hook)]

fn main() {
    std::alloc::set_alloc_error_hook(|_| {
        panic!("oh no");
    });
    assert!(std::panic::catch_unwind(|| {
        vec![0u8; 12345678901234567890];
    }).is_err());
    println!("i'm ok :)");
}

But it already succeeds on the current version of rust:

thread 'main' panicked at 'oh no', src/main.rs:5:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
i'm ok :)

Am I misunderstanding the purpose of this PR?

@bjorn3
Copy link
Member

bjorn3 commented Jan 5, 2022

I think panicking inside the alloc error hook is currently UB.

@Amanieu
Copy link
Member Author

Amanieu commented Jan 5, 2022

Yes, it's currently UB due to extern "C" and #[rustc_allocator_nounwind] which imply nounwind but don't actually enforce it.

@Amanieu
Copy link
Member Author

Amanieu commented Jan 5, 2022

If you try using a type with Drop you will see that the drop gets optimized away because the compiler assumes the allocator doesn't unwind.

@m-ou-se
Copy link
Member

m-ou-se commented Jan 5, 2022

Ah, interesting. I didn't manage to make it fail on x86_64-unknown-linux-gnu, aarch64-apple-darwin, nor x86_64-pc-windows-gnu, but it does indeed fail on aarch64-unknown-linux-musl and x86_64-unknown-linux-musl. With this patch applied, it succeeds on all of them.

@bors r+

@bors
Copy link
Contributor

bors commented Jan 5, 2022

📌 Commit f4545cc has been approved by m-ou-se

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 5, 2022
@m-ou-se
Copy link
Member

m-ou-se commented Jan 5, 2022

If you try using a type with Drop you will see that the drop gets optimized away because the compiler assumes the allocator doesn't unwind.

If I add a let _a = String::new(); in main, it seems to abort without unwinding before this patch. After this patch, it works fine.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 5, 2022
Allow unwinding from OOM hooks

This is split off from rust-lang#88098 and contains just the bare minimum to allow specifying a custom OOM hook with `set_alloc_error_hook` which unwinds instead of aborting.

See rust-lang#88098 for an actual command-line flag which switches the default OOM behavior to unwind instead of aborting.

Previous perf results show a negligible impact on performance.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 5, 2022
Allow unwinding from OOM hooks

This is split off from rust-lang#88098 and contains just the bare minimum to allow specifying a custom OOM hook with `set_alloc_error_hook` which unwinds instead of aborting.

See rust-lang#88098 for an actual command-line flag which switches the default OOM behavior to unwind instead of aborting.

Previous perf results show a negligible impact on performance.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 6, 2022
Allow unwinding from OOM hooks

This is split off from rust-lang#88098 and contains just the bare minimum to allow specifying a custom OOM hook with `set_alloc_error_hook` which unwinds instead of aborting.

See rust-lang#88098 for an actual command-line flag which switches the default OOM behavior to unwind instead of aborting.

Previous perf results show a negligible impact on performance.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Jan 9, 2022
Allow unwinding from OOM hooks

This is split off from rust-lang#88098 and contains just the bare minimum to allow specifying a custom OOM hook with `set_alloc_error_hook` which unwinds instead of aborting.

See rust-lang#88098 for an actual command-line flag which switches the default OOM behavior to unwind instead of aborting.

Previous perf results show a negligible impact on performance.
@ehuss
Copy link
Contributor

ehuss commented Jan 12, 2022

Oh, sorry, I didn't see that.

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Jan 12, 2022
@hkratz
Copy link
Contributor

hkratz commented Jan 12, 2022

Not really on Windows much these days, maybe someone from the Windows notification group can help?

@rustbot ping windows

@rustbot
Copy link
Collaborator

rustbot commented Jan 12, 2022

Error: Only Rust team members can ping teams.

Please let @rust-lang/release know if you're having trouble with this bot.

@Amanieu
Copy link
Member Author

Amanieu commented Jan 12, 2022

Just a backtrace at the point where it is hanging would be a good start to figuring out what the problem is.

@bjorn3
Copy link
Member

bjorn3 commented Jan 12, 2022

I can see this error in the log when it tries to build rls:

error[E0635]: unknown feature `thread_local_const_init`
  --> C:\Users\runneradmin\.cargo\registry\src\github.com-1ecc6299db9ec823\rustc-ap-rustc_span-722.0.0\src\lib.rs:23:12
   |
23 | #![feature(thread_local_const_init)]
   |            ^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0635`.

Could this somehow be causing the hang?

Otherwise I have no idea how to go about debugging this.

No, rls fails to build on master too. See #91543.

@ehuss
Copy link
Contributor

ehuss commented Jan 12, 2022

I'm able to reproduce locally. At a minimum it required llvm assertions, though it may also require parallel-compiler.

The reason it is hanging is because it pops open a helpful dialog box.

image

In this particular instance, it was hung building tracing-subscriber.

Here is a stack trace:

win32u.dll!NtUserWaitMessage+0x14
USER32.dll!DialogBoxIndirectParamAorW+0x431
USER32.dll!DialogBoxIndirectParamAorW+0x1a1
USER32.dll!SoftModalMessageBox+0x85b
USER32.dll!DrawStateA+0x1e25
USER32.dll!MessageBoxTimeoutW+0x1a7
USER32.dll!MessageBoxW+0x4e
rustc_driver-9acede3d415bc9ac.dll!__acrt_MessageBoxW+0x56
rustc_driver-9acede3d415bc9ac.dll!__acrt_show_wide_message_box+0x7c
rustc_driver-9acede3d415bc9ac.dll!common_assert_to_message_box<wchar_t>+0x74
rustc_driver-9acede3d415bc9ac.dll!llvm::InlineFunction+0x8366
rustc_driver-9acede3d415bc9ac.dll!llvm::InlinerPass::run+0x15d8
rustc_driver-9acede3d415bc9ac.dll!llvm::detail::PassModel<llvm::LazyCallGraph::SCC,llvm::InlinerPass,llvm::PreservedAnalyses,llvm::AnalysisManager<llvm::LazyCallGraph::SCC,llvm::LazyCallGraph & __ptr64>,llvm::LazyCallGraph & __ptr64,llvm::CGSCCUpdateResul
rustc_driver-9acede3d415bc9ac.dll!llvm::PassManager<llvm::LazyCallGraph::SCC,llvm::AnalysisManager<llvm::LazyCallGraph::SCC,llvm::LazyCallGraph & __ptr64>,llvm::LazyCallGraph & __ptr64,llvm::CGSCCUpdateResult & __ptr64>::run+0x30b
rustc_driver-9acede3d415bc9ac.dll!llvm::detail::PassModel<llvm::LazyCallGraph::SCC,llvm::PassManager<llvm::LazyCallGraph::SCC,llvm::AnalysisManager<llvm::LazyCallGraph::SCC,llvm::LazyCallGraph & __ptr64>,llvm::LazyCallGraph & __ptr64,llvm::CGSCCUpdateResu
rustc_driver-9acede3d415bc9ac.dll!llvm::DevirtSCCRepeatedPass::run+0x200
rustc_driver-9acede3d415bc9ac.dll!llvm::detail::PassModel<llvm::LazyCallGraph::SCC,llvm::DevirtSCCRepeatedPass,llvm::PreservedAnalyses,llvm::AnalysisManager<llvm::LazyCallGraph::SCC,llvm::LazyCallGraph & __ptr64>,llvm::LazyCallGraph & __ptr64,llvm::CGSCCU
rustc_driver-9acede3d415bc9ac.dll!llvm::ModuleToPostOrderCGSCCPassAdaptor::run+0x114b
rustc_driver-9acede3d415bc9ac.dll!llvm::detail::PassModel<llvm::Module,llvm::ModuleToPostOrderCGSCCPassAdaptor,llvm::PreservedAnalyses,llvm::AnalysisManager<llvm::Module> >::run+0x11
rustc_driver-9acede3d415bc9ac.dll!llvm::PassManager<llvm::Module,llvm::AnalysisManager<llvm::Module> >::run+0x2a2
rustc_driver-9acede3d415bc9ac.dll!llvm::ModuleInlinerWrapperPass::run+0x24c
rustc_driver-9acede3d415bc9ac.dll!llvm::detail::PassModel<llvm::Module,llvm::ModuleInlinerWrapperPass,llvm::PreservedAnalyses,llvm::AnalysisManager<llvm::Module> >::run+0x11
rustc_driver-9acede3d415bc9ac.dll!llvm::PassManager<llvm::Module,llvm::AnalysisManager<llvm::Module> >::run+0x2a2
rustc_driver-9acede3d415bc9ac.dll!LLVMRustOptimizeWithNewPassManager+0x1f0e
rustc_driver-9acede3d415bc9ac.dll!RNvNtNtCs8Ww9ijeY60a_18rustc_codegen_llvm4back5write35optimize_with_new_llvm_pass_manager+0x400
rustc_driver-9acede3d415bc9ac.dll!RNvNtNtCs8Ww9ijeY60a_18rustc_codegen_llvm4back3lto16run_pass_manager+0x242
rustc_driver-9acede3d415bc9ac.dll!RNvNtNtCs8Ww9ijeY60a_18rustc_codegen_llvm4back3lto20optimize_thin_module+0x2051
rustc_driver-9acede3d415bc9ac.dll!RNvMs_NtNtCs5mXDuW1fxtA_17rustc_codegen_ssa4back3ltoINtB4_16LtoModuleCodegenNtCs8Ww9ijeY60a_18rustc_codegen_llvm18LlvmCodegenBackendE8optimizeB1e_+0x2a
rustc_driver-9acede3d415bc9ac.dll!RINvNtNtCs5mXDuW1fxtA_17rustc_codegen_ssa4back5write17execute_work_itemNtCs8Ww9ijeY60a_18rustc_codegen_llvm18LlvmCodegenBackendEB19_+0x2fc
rustc_driver-9acede3d415bc9ac.dll!RINvNtNtCsbfuXEFdO0KO_3std10sys_common9backtrace28___rust_begin_short_backtraceNCINvXs0_Cs8Ww9ijeY60a_18rustc_codegen_llvmNtB1o_18LlvmCodegenBackendNtNtNtCs5mXDuW1fxtA_17rustc_codegen_ssa6traits7backend19ExtraBackendMetho
rustc_driver-9acede3d415bc9ac.dll!RINvXss_Cs6sEOyLJiBiG_8smallvecINtB6_8SmallVecARNtNtCsg0nmUIWefZS_12rustc_middle2ty3TySj8_EINtNtNtNtCscKNrPtuGzPt_4core4iter6traits7collect6ExtendBJ_E6extendINtNtNtB1y_8adapters5chain5ChainINtNtNtB1y_7sources4once4OnceBJ_
std-fbf1316f493850ac.dll!std::sys::windows::thread::impl$0::new::thread_start+0x4c
KERNEL32.DLL!BaseThreadInitThunk+0x14
ntdll.dll!RtlUserThreadStart+0x21

I'm pretty much out of my depth when it comes to digging into LLVM, though.

@nikic
Copy link
Contributor

nikic commented Jan 13, 2022

@ehuss Could you please rerun the asserting rustc command with -C save-temps and zip the results? Hopefully this is reproducible on the bitcode.

@ehuss
Copy link
Contributor

ehuss commented Jan 14, 2022

Here are the temp files:
libtracing_subscriber-1e4a1d5d5521f0b9.zip

@ehuss
Copy link
Contributor

ehuss commented Jan 14, 2022

I confirmed the only non-default setting needed to trigger it is llvm.assertions, and building tracing-subscriber 0.3.3 with --release.

@nikic
Copy link
Contributor

nikic commented Jan 14, 2022

Best reduction I have for now is https://gist.github.com/nikic/2ff417bd7df48d660f5af0ea47ee3c89 with -passes="cgscc(inline,early-cse<memssa>)".

Edit: https://gist.github.com/nikic/65871cd4c29ded2d1b21cebbdab3f052 asserts under opt -inline.

@nikic
Copy link
Contributor

nikic commented Jan 14, 2022

I filed llvm/llvm-project#53206.

@nikic
Copy link
Contributor

nikic commented Jan 31, 2022

Fixed upstream by llvm/llvm-project@4810051.

@Amanieu
Copy link
Member Author

Amanieu commented Feb 5, 2022

Thanks @nikic!

Let's try this again.

@bors r=m-ou-se

@bors
Copy link
Contributor

bors commented Feb 5, 2022

📌 Commit 2082842 has been approved by m-ou-se

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 5, 2022
@bors
Copy link
Contributor

bors commented Feb 6, 2022

⌛ Testing commit 2082842 with merge 719b04c...

@bors
Copy link
Contributor

bors commented Feb 6, 2022

☀️ Test successful - checks-actions
Approved by: m-ou-se
Pushing 719b04c to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Feb 6, 2022
@bors bors merged commit 719b04c into rust-lang:master Feb 6, 2022
@rustbot rustbot added this to the 1.60.0 milestone Feb 6, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (719b04c): comparison url.

Summary: This benchmark run shows 34 relevant regressions 😿 to instruction counts.

  • Average relevant regression: 0.8%
  • Average relevant improvement: -0.3%
  • Largest regression in instruction counts: 1.9% on incr-patched: println builds of regression-31157 opt

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Next Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression-triaged along with sufficient written justification. If you cannot justify the regressions please open an issue or create a new PR that fixes the regressions, add a comment linking to the newly created issue or PR, and then add the perf-regression-triaged label to this PR.

@rustbot label: +perf-regression

@rustbot rustbot added the perf-regression Performance regression. label Feb 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet