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

Implement Make handle_alloc_error default to panic (for no_std + liballoc) #76448

Merged
merged 1 commit into from
Oct 4, 2020

Conversation

haraldh
Copy link
Contributor

@haraldh haraldh commented Sep 7, 2020

Related: #66741

Guarded with #![feature(default_alloc_error_handler)] a default
alloc_error_handler is called, if a custom allocator is used and no
other custom #[alloc_error_handler] is defined.

@rust-highfive
Copy link
Collaborator

r? @nikomatsakis

(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 Sep 7, 2020
@haraldh haraldh force-pushed the default_alloc_error_handler_reduced branch from 962e10b to 6379296 Compare September 7, 2020 16:17
@haraldh haraldh marked this pull request as draft September 11, 2020 05:53
@haraldh haraldh force-pushed the default_alloc_error_handler_reduced branch 6 times, most recently from 15e2e25 to 4bca7fa Compare September 11, 2020 09:37
@haraldh
Copy link
Contributor Author

haraldh commented Sep 11, 2020

Hmm, seems like library/alloc stage1 gets tested with cargo and rustc from stage0 without --cfg bootstrap set.

2020-09-11T09:57:49.7283157Z Testing alloc stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
2020-09-11T09:58:15.7745629Z command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "test" "--target" "x86_64-unknown-linux-gnu" "-Zbinary-dep-depinfo" "-j" "16" "--release" "--locked" "--color" "always" "--features" "panic-unwind backtrace compiler-builtins-c" "--manifest-path" "/checkout/library/test/Cargo.toml" "-p" "alloc" "--" "--quiet"

@haraldh
Copy link
Contributor Author

haraldh commented Sep 11, 2020

@nikomatsakis @Amanieu need some help here.

@haraldh
Copy link
Contributor Author

haraldh commented Sep 11, 2020

or maybe @SimonSapin can help

@Amanieu
Copy link
Member

Amanieu commented Sep 11, 2020

Under #[cfg(test)] I think you need to import handle_alloc_error from libstd instead of defining it yourself.

@haraldh
Copy link
Contributor Author

haraldh commented Sep 11, 2020

So, this one passes.

$ python x.py test  --exclude library/alloc --exclude src/tools/linkchecker

@Amanieu will try, thanks

@haraldh haraldh force-pushed the default_alloc_error_handler_reduced branch 2 times, most recently from d77f320 to 5ac1d78 Compare September 11, 2020 14:33
@haraldh haraldh marked this pull request as ready for review September 11, 2020 15:04
@haraldh
Copy link
Contributor Author

haraldh commented Sep 11, 2020

ready for review 😀

@jonas-schievink
Copy link
Contributor

r? @Amanieu

unsafe {
__rust_alloc_error_handler(layout.size(), layout.align());
}
}
Copy link
Member

Choose a reason for hiding this comment

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

For tests you can just do:

pub use std::alloc::handle_alloc_error;

This works since std is imported by tests: https://github.com/haraldh/rust-1/blob/5ac1d7867411e1f28d3cee45df8c219fb39f414e/library/alloc/src/lib.rs#L146

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, changed

tcx.sess.err("`#[alloc_error_handler]` function required, but not found");
if !tcx.features().default_alloc_error_handler {
tcx.sess.err("`#[alloc_error_handler]` function required, but not found.");
tcx.sess.err("Use `#![feature(default_alloc_error_handler)]` for a default error handler.");
Copy link
Member

Choose a reason for hiding this comment

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

Could this be a note or suggestion instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to tcx.sess.note_without_error

@haraldh haraldh force-pushed the default_alloc_error_handler_reduced branch 2 times, most recently from a9efe49 to 8e46ce0 Compare September 14, 2020 08:50
@Amanieu
Copy link
Member

Amanieu commented Sep 14, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Sep 14, 2020

📌 Commit 8e46ce0d22b01bb32adc20b4e911f129da65ed44 has been approved by Amanieu

@bors
Copy link
Contributor

bors commented Oct 1, 2020

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 1, 2020
@haraldh
Copy link
Contributor Author

haraldh commented Oct 1, 2020

target arm-unknown-linux-gnueabihf:

undefined reference to `__aeabi_unwind_cpp_pr0'

Hmpf... seems like I need help with my test cases... @Amanieu @SimonSapin ... they work on x86_64-linux ... no idea what is wrong here.

@Amanieu
Copy link
Member

Amanieu commented Oct 1, 2020

It seems that this symbol is required on ARM. You can just define it as an empty function like here: https://github.com/rust-lang/compiler-builtins/blob/7b996ca0fa969199332d703b81fb411d85e5f7c4/examples/intrinsics.rs#L383

…balloc)

Related: rust-lang#66741

Guarded with `#![feature(default_alloc_error_handler)]` a default
`alloc_error_handler` is called, if a custom allocator is used and no
other custom `#[alloc_error_handler]` is defined.

The panic message does not contain the size anymore, because it would
pull in the fmt machinery, which would blow up the code size
significantly.
@haraldh haraldh force-pushed the default_alloc_error_handler_reduced branch from 7de481e to cadd12b Compare October 2, 2020 07:00
@haraldh
Copy link
Contributor Author

haraldh commented Oct 2, 2020

@Amanieu thanks a lot for the link. I thought I messed up some unwind internals, which only show up on some architectures.

Added those stubs. Let's see what is missing with the next bors run.

@Amanieu
Copy link
Member

Amanieu commented Oct 2, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Oct 2, 2020

📌 Commit cadd12b has been approved by Amanieu

@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 Oct 2, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Oct 3, 2020
…_reduced, r=Amanieu

Implement Make `handle_alloc_error` default to panic (for no_std + liballoc)

Related: rust-lang#66741

Guarded with `#![feature(default_alloc_error_handler)]` a default
`alloc_error_handler` is called, if a custom allocator is used and no
other custom `#[alloc_error_handler]` is defined.
@bors
Copy link
Contributor

bors commented Oct 4, 2020

⌛ Testing commit cadd12b with merge 0d37dca...

@bors
Copy link
Contributor

bors commented Oct 4, 2020

☀️ Test successful - checks-actions, checks-azure
Approved by: Amanieu
Pushing 0d37dca to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Oct 4, 2020
@bors bors merged commit 0d37dca into rust-lang:master Oct 4, 2020
@rustbot rustbot added this to the 1.49.0 milestone Oct 4, 2020
@haraldh haraldh deleted the default_alloc_error_handler_reduced branch October 4, 2020 12:07
@@ -82,4 +88,41 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut ModuleLlvm, kind: Alloc
}
llvm::LLVMDisposeBuilder(llbuilder);
}

// rust alloc error handler
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 you duplicated this code rather than adding a new entry to ALLOCATOR_METHODS?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bjorn3

  1. ALLOCATOR_METHODS is also used elsewhere to build other stuff, which I didn't want to clobber
  2. the alloc error handler has a different function signature
  3. the alloc error handler has a different name

Copy link
Member

Choose a reason for hiding this comment

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

Ah, ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bjorn3 feel free to refactor the stuff without side effects

#[lang = "oom"]
fn oom_impl(layout: Layout) -> !;
}
unsafe { oom_impl(layout) }
Copy link
Member

Choose a reason for hiding this comment

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

Does this mean that, unlike before, the #[alloc_error_handler] is now allowed to unwind? There's no #[rustc_allocator_nounwind] any more.

Copy link
Member

Choose a reason for hiding this comment

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

Hm, but __rust_alloc_error_handler above still has #[rustc_allocator_nounwind]. How is that not UB when it ends up calling __rdl_oom?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I blindly copied #[rustc_allocator_nounwind]. Sorry. Remove it, if it is safe.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, or the other way round, I might have missed it.


// if there is a `#[alloc_error_handler]`
#[rustc_std_internal_symbol]
pub unsafe extern "C" fn __rg_oom(size: usize, align: usize) -> ! {
Copy link
Member

@RalfJung RalfJung Oct 9, 2020

Choose a reason for hiding this comment

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

Nothing like this exists for the allocator, right? There the generated __rust_alloc etc symbols directly call the lang item? Looks like this is needed because the argument types differ; is there any plan to get rid of that mismatch (and the resulting two indirections through unknown extern functions)?

Copy link
Member

@RalfJung RalfJung Oct 9, 2020

Choose a reason for hiding this comment

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

Ah no, the __rd functions are just generated by the macro expansion code. That has the advantage that they do not themselves call an unknown extern function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This can be removed, if compiler/rustc_codegen_llvm/src/allocator.rs calls directly into the lang item, but with the extern "Rust" API and a Layout object reference.

I just didn't know, how to generate a extern "Rust" fn in compiler/rustc_codegen_llvm/src/allocator.rs.

Copy link
Member

Choose a reason for hiding this comment

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

I think the symmetric thing to do (when compared with #[global_allocator]) would be for the #[alloc_error_handler] attribute to generate __rg_oom, but I guess it doesn't really matter.

It is just somewhat dissatisfying that the very same problem is solved three times in slightly different ways with various amounts of code sharing (global allocator, alloc error handler, panic handler).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think the symmetric thing to do (when compared with #[global_allocator]) would be for the #[alloc_error_handler] attribute to generate __rg_oom, but I guess it doesn't really matter.

It is just somewhat dissatisfying that the very same problem is solved three times in slightly different ways with various amounts of code sharing (global allocator, alloc error handler, panic handler).

I agree, but to implement it efficiently, I lack the expertise to redirect it via the rust ABI.

#[doc(hidden)]
#[allow(unused_attributes)]
#[unstable(feature = "alloc_internals", issue = "none")]
pub mod __default_lib_allocator {
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand this module name, given that this is not an allocator, but an alloc-error handler.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-allocators Area: Custom and system allocators merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.