mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 17:36:25 +04:00
Add some tests from ch2 && support SIGSEGV&SIGILL
This commit is contained in:
parent
4a169450f8
commit
1f55fbe4a2
@ -2,6 +2,7 @@ mod context;
|
||||
mod manager;
|
||||
mod pid;
|
||||
mod processor;
|
||||
mod signal;
|
||||
mod switch;
|
||||
mod task;
|
||||
|
||||
@ -18,6 +19,7 @@ pub use pid::{pid_alloc, KernelStack, PidHandle};
|
||||
pub use processor::{
|
||||
current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task,
|
||||
};
|
||||
pub use signal::SignalFlags;
|
||||
|
||||
pub fn suspend_current_and_run_next() {
|
||||
// There must be an application running.
|
||||
@ -83,3 +85,15 @@ lazy_static! {
|
||||
pub fn add_initproc() {
|
||||
add_task(INITPROC.clone());
|
||||
}
|
||||
|
||||
pub fn check_signals_of_current() -> Option<(i32, &'static str)> {
|
||||
let task = current_task().unwrap();
|
||||
let task_inner = task.inner_exclusive_access();
|
||||
task_inner.signals.check_error()
|
||||
}
|
||||
|
||||
pub fn current_add_signal(signal: SignalFlags) {
|
||||
let task = current_task().unwrap();
|
||||
let mut task_inner = task.inner_exclusive_access();
|
||||
task_inner.signals |= signal;
|
||||
}
|
||||
|
29
os/src/task/signal.rs
Normal file
29
os/src/task/signal.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use bitflags::*;
|
||||
|
||||
bitflags! {
|
||||
pub struct SignalFlags: u32 {
|
||||
const SIGINT = 1 << 2;
|
||||
const SIGILL = 1 << 4;
|
||||
const SIGABRT = 1 << 6;
|
||||
const SIGFPE = 1 << 8;
|
||||
const SIGSEGV = 1 << 11;
|
||||
}
|
||||
}
|
||||
|
||||
impl SignalFlags {
|
||||
pub fn check_error(&self) -> Option<(i32, &'static str)> {
|
||||
if self.contains(Self::SIGINT) {
|
||||
Some((-2, "Killed, SIGINT=2"))
|
||||
} else if self.contains(Self::SIGILL) {
|
||||
Some((-4, "Illegal Instruction, SIGILL=4"))
|
||||
} else if self.contains(Self::SIGABRT) {
|
||||
Some((-6, "Aborted, SIGABRT=6"))
|
||||
} else if self.contains(Self::SIGFPE) {
|
||||
Some((-8, "Erroneous Arithmetic Operation, SIGFPE=8"))
|
||||
} else if self.contains(Self::SIGSEGV) {
|
||||
Some((-11, "Segmentation Fault, SIGSEGV=11"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use super::TaskContext;
|
||||
use super::{pid_alloc, KernelStack, PidHandle};
|
||||
use super::{pid_alloc, KernelStack, PidHandle, SignalFlags};
|
||||
use crate::config::TRAP_CONTEXT;
|
||||
use crate::fs::{File, Stdin, Stdout};
|
||||
use crate::mm::{translated_refmut, MemorySet, PhysPageNum, VirtAddr, KERNEL_SPACE};
|
||||
@ -29,6 +29,7 @@ pub struct TaskControlBlockInner {
|
||||
pub children: Vec<Arc<TaskControlBlock>>,
|
||||
pub exit_code: i32,
|
||||
pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
|
||||
pub signals: SignalFlags,
|
||||
}
|
||||
|
||||
impl TaskControlBlockInner {
|
||||
@ -90,6 +91,7 @@ impl TaskControlBlock {
|
||||
// 2 -> stderr
|
||||
Some(Arc::new(Stdout)),
|
||||
],
|
||||
signals: SignalFlags::empty(),
|
||||
})
|
||||
},
|
||||
};
|
||||
@ -191,6 +193,7 @@ impl TaskControlBlock {
|
||||
children: Vec::new(),
|
||||
exit_code: 0,
|
||||
fd_table: new_fd_table,
|
||||
signals: SignalFlags::empty(),
|
||||
})
|
||||
},
|
||||
});
|
||||
|
@ -3,7 +3,7 @@ mod context;
|
||||
use crate::config::{TRAMPOLINE, TRAP_CONTEXT};
|
||||
use crate::syscall::syscall;
|
||||
use crate::task::{
|
||||
current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next,
|
||||
current_trap_cx, current_user_token, exit_current_and_run_next, suspend_current_and_run_next, current_add_signal, SignalFlags, check_signals_of_current,
|
||||
};
|
||||
use crate::timer::set_next_trigger;
|
||||
use core::arch::{asm, global_asm};
|
||||
@ -59,19 +59,18 @@ pub fn trap_handler() -> ! {
|
||||
| Trap::Exception(Exception::InstructionPageFault)
|
||||
| Trap::Exception(Exception::LoadFault)
|
||||
| Trap::Exception(Exception::LoadPageFault) => {
|
||||
/*
|
||||
println!(
|
||||
"[kernel] {:?} in application, bad addr = {:#x}, bad instruction = {:#x}, kernel killed it.",
|
||||
scause.cause(),
|
||||
stval,
|
||||
current_trap_cx().sepc,
|
||||
);
|
||||
// page fault exit code
|
||||
exit_current_and_run_next(-2);
|
||||
*/
|
||||
current_add_signal(SignalFlags::SIGSEGV);
|
||||
}
|
||||
Trap::Exception(Exception::IllegalInstruction) => {
|
||||
println!("[kernel] IllegalInstruction in application, kernel killed it.");
|
||||
// illegal instruction exit code
|
||||
exit_current_and_run_next(-3);
|
||||
current_add_signal(SignalFlags::SIGILL);
|
||||
}
|
||||
Trap::Interrupt(Interrupt::SupervisorTimer) => {
|
||||
set_next_trigger();
|
||||
@ -85,7 +84,11 @@ pub fn trap_handler() -> ! {
|
||||
);
|
||||
}
|
||||
}
|
||||
//println!("before trap_return");
|
||||
// check signals
|
||||
if let Some((errno, msg)) = check_signals_of_current() {
|
||||
println!("[kernel] {}", msg);
|
||||
exit_current_and_run_next(errno);
|
||||
}
|
||||
trap_return();
|
||||
}
|
||||
|
||||
|
@ -8,4 +8,5 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
buddy_system_allocator = "0.6"
|
||||
bitflags = "1.2.1"
|
||||
bitflags = "1.2.1"
|
||||
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
|
||||
|
17
user/src/bin/priv_csr.rs
Normal file
17
user/src/bin/priv_csr.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use riscv::register::sstatus::{self, SPP};
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
println!("Try to access privileged CSR in U Mode");
|
||||
println!("Kernel should kill this application!");
|
||||
unsafe {
|
||||
sstatus::set_spp(SPP::User);
|
||||
}
|
||||
0
|
||||
}
|
17
user/src/bin/priv_inst.rs
Normal file
17
user/src/bin/priv_inst.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
println!("Try to execute privileged instruction in U Mode");
|
||||
println!("Kernel should kill this application!");
|
||||
unsafe {
|
||||
asm!("sret");
|
||||
}
|
||||
0
|
||||
}
|
15
user/src/bin/store_fault.rs
Normal file
15
user/src/bin/store_fault.rs
Normal file
@ -0,0 +1,15 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
#[macro_use]
|
||||
extern crate user_lib;
|
||||
|
||||
#[no_mangle]
|
||||
fn main() -> i32 {
|
||||
println!("Into Test store_fault, we will insert an invalid store operation...");
|
||||
println!("Kernel should kill this application!");
|
||||
unsafe {
|
||||
core::ptr::null_mut::<u8>().write_volatile(0);
|
||||
}
|
||||
0
|
||||
}
|
Loading…
Reference in New Issue
Block a user