Merge pull request #170 from phil-opp/cargo-panic-abort

Use the `panic=abort` option instead of `-Z no-landing-pads`
This commit is contained in:
Philipp Oppermann
2016-05-29 18:49:30 +02:00
5 changed files with 33 additions and 35 deletions

View File

@@ -22,3 +22,9 @@ version = "0.7.0"
[lib] [lib]
crate-type = ["staticlib"] crate-type = ["staticlib"]
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"

View File

@@ -49,7 +49,7 @@ $(kernel): cargo $(rust_os) $(assembly_object_files) $(linker_script)
@ld -n --gc-sections -T $(linker_script) -o $(kernel) $(assembly_object_files) $(rust_os) @ld -n --gc-sections -T $(linker_script) -o $(kernel) $(assembly_object_files) $(rust_os)
cargo: cargo:
@cargo rustc --target $(target) -- -Z no-landing-pads @cargo build --target $(target)
# compile assembly files # compile assembly files
build/arch/$(arch)/%.o: src/arch/$(arch)/%.asm build/arch/$(arch)/%.o: src/arch/$(arch)/%.asm

View File

@@ -1,6 +1,7 @@
+++ +++
title = "Set Up Rust" title = "Set Up Rust"
date = "2015-09-02" date = "2015-09-02"
updated = "2015-05-29"
aliases = [ aliases = [
"/2015/09/02/setup-rust/", "/2015/09/02/setup-rust/",
"/setup-rust.html", "/setup-rust.html",
@@ -21,6 +22,8 @@ This blog post tries to set up Rust step-by-step and point out the different pro
[file an issue]: https://github.com/phil-opp/blog_os/issues [file an issue]: https://github.com/phil-opp/blog_os/issues
[Github repository]: https://github.com/phil-opp/blog_os/tree/set_up_rust [Github repository]: https://github.com/phil-opp/blog_os/tree/set_up_rust
**Update**: We now use the `panic=abort` cargo option instead of `-Z no-landing-pads`. See [#170](https://github.com/phil-opp/blog_os/pull/170).
## Installing Rust ## Installing Rust
We need a nightly compiler, as we will use many unstable features. To manage Rust installations I highly recommend brson's [multirust]. It allows you to install nightly, beta, and stable compilers side-by-side and makes it easy to update them. To use a nightly compiler for the current directory, you can run `multirust override nightly`. We need a nightly compiler, as we will use many unstable features. To manage Rust installations I highly recommend brson's [multirust]. It allows you to install nightly, beta, and stable compilers side-by-side and makes it easy to update them. To use a nightly compiler for the current directory, you can run `multirust override nightly`.
@@ -219,17 +222,31 @@ target/debug/libblog_os.a(blog_os.0.o):
/home/.../src/libcore/iter.rs:654: /home/.../src/libcore/iter.rs:654:
undefined reference to `_Unwind_Resume' undefined reference to `_Unwind_Resume'
``` ```
So the linker can't find a function named `_Unwind_Resume` that is referenced in `iter.rs:654` in libcore. This reference is not really there at [line 654 of libcore's `iter.rs`][iter.rs:654]. Instead, it is a compiler inserted _landing pad_, which is used for exception handling. So the linker can't find a function named `_Unwind_Resume` that is referenced in `iter.rs:654` in libcore. This reference is not really there at [line 654 of libcore's `iter.rs`][iter.rs:654]. Instead, it is a compiler inserted _landing pad_, which is used for panic handling by default.
[iter.rs:654]: https://github.com/rust-lang/rust/blob/b0ca03923359afc8df92a802b7cc1476a72fb2d0/src/libcore/iter.rs#L654 [iter.rs:654]: https://github.com/rust-lang/rust/blob/b0ca03923359afc8df92a802b7cc1476a72fb2d0/src/libcore/iter.rs#L654
The easiest way of fixing this problem is to disable the landing pad creation since we don't supports panics anyway right now. We can do this by passing a `-Z no-landing-pads` flag to `rustc` (the actual Rust compiler below cargo). To do this we replace the `cargo build` command in our Makefile with the `cargo rustc` command, which does the same but allows passing flags to `rustc`: By default, the destructors of all stack variables are run when a `panic` occurs. This is called _unwinding_ and allows parent threads to [recover from panics]. However, it requires a platform specific gcc library, which isn't available in our kernel.
```make [recover from panics]: https://doc.rust-lang.org/book/concurrency.html#panics
cargo:
@cargo rustc --target $(target) -- -Z no-landing-pads Fortunately, Rust allows us to disable unwinding. We just need to add some entries in our `Cargo.toml`:
```toml
# The development profile, used for `cargo build`.
[profile.dev]
panic = "abort"
# The release profile, used for `cargo build --release`.
[profile.release]
panic = "abort"
``` ```
Now we fixed all linking issues and our kernel should _build_ again. But instead of displaying `Hello World`, it constantly reboots itself when we start it.
These [profile sections] specify options for `cargo build` and `cargo release`. By setting the `panic` option to `abort`, we disable all unwinding in our kernel.
[profile sections]: http://doc.crates.io/manifest.html#the-profile-sections
Now we fixed all linking issues and our kernel builds again. But instead of displaying `Hello World`, it constantly reboots itself when we start it.
## Debugging the Boot Loop ## Debugging the Boot Loop
Such a boot loop is most likely caused by some [CPU exception][exception table]. When these exceptions aren't handled, a [Triple Fault] occurs and the processor resets itself. We can look at generated CPU interrupts/exceptions using QEMU: Such a boot loop is most likely caused by some [CPU exception][exception table]. When these exceptions aren't handled, a [Triple Fault] occurs and the processor resets itself. We can look at generated CPU interrupts/exceptions using QEMU:

View File

@@ -317,31 +317,11 @@ use alloc::boxed::Box;
let heap_test = Box::new(42); let heap_test = Box::new(42);
``` ```
When we try to compile it using `make run`, we get several linker errors about a function named `_Unwind_Resume`: (If you're getting a linker error about `_Unwind_Resume`, try to use the [panic=abort cargo option].)
``` [panic=abort cargo option]: https://github.com/phil-opp/blog_os/pull/170
target/x86_64-unknown-linux-gnu/debug/libblog_os.a(bump_allocator-[…].0.o):
In function `bump_allocator::__rust_allocate':
/home/…/blog_os/libs/bump_allocator/src/lib.rs:19:
undefined reference to `_Unwind_Resume'
```
This function is part of Rust's unwinding machinery. We disabled most of by passing `-Z no-landing-pads` to rustc, but apparently our precompiled `libcollections` still links to it. When we run it, a triple fault occurs and causes permanent rebooting. Let's try debug it using QEMU and objdump as described [in the previous post][qemu debugging]:
To work around this issue for now, we add a dummy function:
```rust
// in libs/bump_allocator/src/lib.rs
#[no_mangle]
pub extern fn _Unwind_Resume() -> ! {
loop{}
}
```
This is just a temporary fix to keep this post simple. We will resolve this issue in a better way in a future post.
Now our kernel compiles again. But when we run it, a triple fault occurs and causes permanent rebooting. We use QEMU for debugging as described [in the previous post][qemu debugging]:
[qemu debugging]: http://os.phil-opp.com/remap-the-kernel.html#debugging [qemu debugging]: http://os.phil-opp.com/remap-the-kernel.html#debugging

View File

@@ -84,8 +84,3 @@ extern "C" fn panic_fmt(fmt: core::fmt::Arguments, file: &str, line: u32) -> ! {
println!(" {}", fmt); println!(" {}", fmt);
loop {} loop {}
} }
#[no_mangle]
pub extern "C" fn _Unwind_Resume() -> ! {
loop {}
}