Add some tests from ch2 && support SIGSEGV&SIGILL

This commit is contained in:
Yifan Wu 2022-01-22 15:13:15 -08:00
parent 4a169450f8
commit 1f55fbe4a2
8 changed files with 108 additions and 9 deletions

View File

@ -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
View 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
}
}
}

View File

@ -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(),
})
},
});

View File

@ -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();
}

View File

@ -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
View 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
View 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
}

View 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
}