Support SIGABRT when the application panics.

ch7-signal
Yifan Wu 3 years ago
parent 1f55fbe4a2
commit d1233cbb69

@ -6,6 +6,7 @@ const SYSCALL_READ: usize = 63;
const SYSCALL_WRITE: usize = 64;
const SYSCALL_EXIT: usize = 93;
const SYSCALL_YIELD: usize = 124;
const SYSCALL_KILL: usize = 129;
const SYSCALL_GET_TIME: usize = 169;
const SYSCALL_GETPID: usize = 172;
const SYSCALL_FORK: usize = 220;
@ -28,6 +29,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
SYSCALL_WRITE => sys_write(args[0], args[1] as *const u8, args[2]),
SYSCALL_EXIT => sys_exit(args[0] as i32),
SYSCALL_YIELD => sys_yield(),
SYSCALL_KILL => sys_kill(args[0], args[1] as u32),
SYSCALL_GET_TIME => sys_get_time(),
SYSCALL_GETPID => sys_getpid(),
SYSCALL_FORK => sys_fork(),

@ -1,8 +1,8 @@
use crate::fs::{open_file, OpenFlags};
use crate::mm::{translated_ref, translated_refmut, translated_str};
use crate::task::{
add_task, current_task, current_user_token, exit_current_and_run_next,
suspend_current_and_run_next,
add_task, current_task, current_user_token, exit_current_and_run_next, pid2task,
suspend_current_and_run_next, SignalFlags,
};
use crate::timer::get_time_ms;
use alloc::string::String;
@ -104,3 +104,16 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
}
// ---- release current PCB automatically
}
pub fn sys_kill(pid: usize, signal: u32) -> isize {
if let Some(task) = pid2task(pid) {
if let Some(flag) = SignalFlags::from_bits(signal) {
task.inner_exclusive_access().signals |= flag;
0
} else {
-1
}
} else {
-1
}
}

@ -1,6 +1,6 @@
use super::TaskControlBlock;
use crate::sync::UPSafeCell;
use alloc::collections::VecDeque;
use alloc::collections::{BTreeMap, VecDeque};
use alloc::sync::Arc;
use lazy_static::*;
@ -26,12 +26,29 @@ impl TaskManager {
lazy_static! {
pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
unsafe { UPSafeCell::new(TaskManager::new()) };
pub static ref PID2TCB: UPSafeCell<BTreeMap<usize, Arc<TaskControlBlock>>> =
unsafe { UPSafeCell::new(BTreeMap::new()) };
}
pub fn add_task(task: Arc<TaskControlBlock>) {
PID2TCB
.exclusive_access()
.insert(task.getpid(), Arc::clone(&task));
TASK_MANAGER.exclusive_access().add(task);
}
pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
TASK_MANAGER.exclusive_access().fetch()
}
pub fn pid2task(pid: usize) -> Option<Arc<TaskControlBlock>> {
let map = PID2TCB.exclusive_access();
map.get(&pid).map(|task| Arc::clone(task))
}
pub fn remove_from_pid2task(pid: usize) {
let mut map = PID2TCB.exclusive_access();
if map.remove(&pid).is_none() {
panic!("cannot find pid {} in pid2task!", pid);
}
}

@ -11,10 +11,11 @@ use alloc::sync::Arc;
pub use context::TaskContext;
use lazy_static::*;
use manager::fetch_task;
use manager::remove_from_pid2task;
use switch::__switch;
use task::{TaskControlBlock, TaskStatus};
pub use manager::add_task;
pub use manager::{add_task, pid2task};
pub use pid::{pid_alloc, KernelStack, PidHandle};
pub use processor::{
current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task,
@ -42,6 +43,8 @@ pub fn suspend_current_and_run_next() {
pub fn exit_current_and_run_next(exit_code: i32) {
// take from Processor
let task = take_current_task().unwrap();
// remove from pid2task
remove_from_pid2task(task.getpid());
// **** access current TCB exclusively
let mut inner = task.inner_exclusive_access();
// Change status to Zombie

@ -3,7 +3,7 @@ use bitflags::*;
bitflags! {
pub struct SignalFlags: u32 {
const SIGINT = 1 << 2;
const SIGILL = 1 << 4;
const SIGILL = 1 << 4;
const SIGABRT = 1 << 6;
const SIGFPE = 1 << 8;
const SIGSEGV = 1 << 11;

@ -3,7 +3,8 @@ 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_add_signal, SignalFlags, check_signals_of_current,
check_signals_of_current, current_add_signal, current_trap_cx, current_user_token,
exit_current_and_run_next, suspend_current_and_run_next, SignalFlags,
};
use crate::timer::set_next_trigger;
use core::arch::{asm, global_asm};

@ -1,4 +1,4 @@
use super::exit;
use super::{getpid, kill, SignalFlags};
#[panic_handler]
fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
@ -13,5 +13,6 @@ fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
} else {
println!("Panicked: {}", err);
}
exit(-1);
kill(getpid() as usize, SignalFlags::SIGABRT.bits());
unreachable!()
}

@ -127,9 +127,28 @@ pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize {
}
}
}
pub fn waitpid_nb(pid: usize, exit_code: &mut i32) -> isize {
sys_waitpid(pid as isize, exit_code as *mut _)
}
pub fn sleep(period_ms: usize) {
let start = sys_get_time();
while sys_get_time() < start + period_ms as isize {
sys_yield();
}
}
bitflags! {
pub struct SignalFlags: i32 {
const SIGINT = 1 << 2;
const SIGILL = 1 << 4;
const SIGABRT = 1 << 6;
const SIGFPE = 1 << 8;
const SIGSEGV = 1 << 11;
}
}
pub fn kill(pid: usize, signal: i32) -> isize {
sys_kill(pid, signal)
}

@ -8,6 +8,7 @@ const SYSCALL_READ: usize = 63;
const SYSCALL_WRITE: usize = 64;
const SYSCALL_EXIT: usize = 93;
const SYSCALL_YIELD: usize = 124;
const SYSCALL_KILL: usize = 129;
const SYSCALL_GET_TIME: usize = 169;
const SYSCALL_GETPID: usize = 172;
const SYSCALL_FORK: usize = 220;
@ -64,6 +65,10 @@ pub fn sys_yield() -> isize {
syscall(SYSCALL_YIELD, [0, 0, 0])
}
pub fn sys_kill(pid: usize, signal: i32) -> isize {
syscall(SYSCALL_KILL, [pid, signal as usize, 0])
}
pub fn sys_get_time() -> isize {
syscall(SYSCALL_GET_TIME, [0, 0, 0])
}

Loading…
Cancel
Save