mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 04:56:30 +00:00
signal的处理(kill命令)以及一些其他的改进 (#100)
* 将entry.S中冗余的ret_from_syscall代码删除,改为jmp Restore_all * new: 增加判断pt_regs是否来自用户态的函数 * new: rust的cli和sti封装 * 将原有的判断pt_regs是否来自用户态的代码,统一改为调用user_mode函数 * ffz函数:获取u64中的第一个值为0的bit * spinlock增加 spinlock irq spin_unlock_irq * 临时解决显示刷新线程迟迟不运行的问题 * 更改ffi_convert的生命周期标签 * new: 测试signal用的app * 解决由于编译器优化导致local_irq_restore无法获取到正确的rflags的值的问题 * new: exec命令增加"&"后台运行选项 * procfs->status增加显示preempt和虚拟运行时间 * 更改引用计数的FFIBind2Rust trait中的生命周期标签 * new: signal处理(kill) * 更正在review中发现的一些细节问题
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
use core::ptr::null_mut;
|
||||
use core::{ffi::c_void, ptr::null_mut, sync::atomic::compiler_fence};
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
@ -8,10 +8,9 @@ use crate::{
|
||||
process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD, ENOMEM,
|
||||
},
|
||||
ipc::{
|
||||
signal::DEFAULT_SIGACTION,
|
||||
signal_types::{sigaction, sighand_struct, signal_struct},
|
||||
signal::{flush_signal_handlers, DEFAULT_SIGACTION},
|
||||
signal_types::{sigaction, sighand_struct, signal_struct, SigQueue},
|
||||
},
|
||||
kdebug,
|
||||
libs::{
|
||||
atomic::atomic_set,
|
||||
ffi_convert::FFIBind2Rust,
|
||||
@ -22,29 +21,38 @@ use crate::{
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
|
||||
kdebug!("process_copy_sighand");
|
||||
// kdebug!("process_copy_sighand");
|
||||
|
||||
if (clone_flags & (CLONE_SIGHAND as u64)) != 0 {
|
||||
let r = RefCount::convert_mut(unsafe { &mut (*(current_pcb().sighand)).count }).unwrap();
|
||||
refcount_inc(r);
|
||||
}
|
||||
|
||||
// 在这里使用Box::leak将动态申请的内存的生命周期转换为static的
|
||||
let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default()));
|
||||
if (sig as *mut sighand_struct) == null_mut() {
|
||||
return -(ENOMEM as i32);
|
||||
}
|
||||
|
||||
// 将新的sighand赋值给pcb
|
||||
unsafe {
|
||||
(*pcb).sighand = sig as *mut sighand_struct as usize
|
||||
as *mut crate::include::bindings::bindings::sighand_struct;
|
||||
}
|
||||
|
||||
// kdebug!("DEFAULT_SIGACTION.sa_flags={}", DEFAULT_SIGACTION.sa_flags);
|
||||
|
||||
// 拷贝sigaction
|
||||
let mut flags: u64 = 0;
|
||||
|
||||
spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags);
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
for (index, x) in unsafe { (*current_pcb().sighand).action }
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
if !(x as *const crate::include::bindings::bindings::sigaction).is_null() {
|
||||
sig.action[index] =
|
||||
*sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction)
|
||||
@ -53,20 +61,26 @@ pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_contr
|
||||
sig.action[index] = DEFAULT_SIGACTION;
|
||||
}
|
||||
}
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, &flags);
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
// 将所有屏蔽的信号的处理函数设置为default
|
||||
// 将信号的处理函数设置为default(除了那些被手动屏蔽的)
|
||||
if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 {
|
||||
todo!();
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
flush_signal_handlers(pcb, false);
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
|
||||
kdebug!("process_copy_signal");
|
||||
// kdebug!("process_copy_signal");
|
||||
// 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号)
|
||||
if (clone_flags & (CLONE_THREAD as u64)) != 0 {
|
||||
return 0;
|
||||
@ -81,6 +95,13 @@ pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_contro
|
||||
(*pcb).signal = sig as *mut signal_struct as usize
|
||||
as *mut crate::include::bindings::bindings::signal_struct;
|
||||
}
|
||||
|
||||
// 创建新的sig_pending->sigqueue
|
||||
unsafe {
|
||||
(*pcb).sig_pending.signal = 0;
|
||||
(*pcb).sig_pending.sigqueue =
|
||||
Box::leak(Box::new(SigQueue::default())) as *mut SigQueue as *mut c_void;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -88,9 +109,15 @@ pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_contro
|
||||
pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) {
|
||||
// 回收进程的信号结构体
|
||||
unsafe {
|
||||
// 回收sighand
|
||||
let sighand = Box::from_raw((*pcb).sighand as *mut sighand_struct);
|
||||
|
||||
drop(sighand);
|
||||
(*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct;
|
||||
|
||||
// 回收sigqueue
|
||||
let queue = Box::from_raw((*pcb).sig_pending.sigqueue as *mut SigQueue);
|
||||
drop(queue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
use core::ffi::c_void;
|
||||
|
||||
use alloc::boxed::Box;
|
||||
|
||||
use crate::{
|
||||
include::bindings::bindings::{atomic_t, spinlock_t},
|
||||
ipc::signal::DEFAULT_SIGACTION,
|
||||
include::bindings::bindings::{atomic_t, process_control_block, spinlock_t},
|
||||
ipc::{signal::DEFAULT_SIGACTION, signal_types::SigQueue},
|
||||
};
|
||||
|
||||
use crate::ipc::signal_types::{sighand_struct, signal_struct, MAX_SIG_NUM};
|
||||
|
||||
/// @brief 初始进程的signal结构体
|
||||
#[no_mangle]
|
||||
pub static INITIAL_SIGNALS: signal_struct = signal_struct {
|
||||
pub static mut INITIAL_SIGNALS: signal_struct = signal_struct {
|
||||
sig_cnt: atomic_t { value: 0 },
|
||||
};
|
||||
|
||||
@ -18,3 +22,25 @@ pub static mut INITIAL_SIGHAND: sighand_struct = sighand_struct {
|
||||
siglock: spinlock_t { lock: 1 },
|
||||
action: [DEFAULT_SIGACTION; MAX_SIG_NUM as usize],
|
||||
};
|
||||
|
||||
/// @brief 初始化pid=0的进程的信号相关的信息
|
||||
#[no_mangle]
|
||||
pub extern "C" fn initial_proc_init_signal(pcb: *mut process_control_block) {
|
||||
|
||||
// 所设置的pcb的pid一定为0
|
||||
assert_eq!(unsafe { (*pcb).pid }, 0);
|
||||
|
||||
// 设置init进程的sighand和signal
|
||||
unsafe {
|
||||
(*pcb).sighand = &mut INITIAL_SIGHAND as *mut sighand_struct as usize
|
||||
as *mut crate::include::bindings::bindings::sighand_struct;
|
||||
(*pcb).signal = &mut INITIAL_SIGNALS as *mut signal_struct as usize
|
||||
as *mut crate::include::bindings::bindings::signal_struct;
|
||||
}
|
||||
// 创建新的sig_pending->sigqueue
|
||||
unsafe {
|
||||
(*pcb).sig_pending.signal = 0;
|
||||
(*pcb).sig_pending.sigqueue =
|
||||
Box::leak(Box::new(SigQueue::default())) as *mut SigQueue as *mut c_void;
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ struct thread_struct
|
||||
#define PF_NOFREEZE (1UL << 4) // 当前进程不能被冻结
|
||||
#define PF_EXITING (1UL << 5) // 进程正在退出
|
||||
#define PF_WAKEKILL (1UL << 6) // 进程由于接收到终止信号唤醒
|
||||
#define PF_SIGNALED (1UL << 7) // 进程由于接收到信号而退出
|
||||
/**
|
||||
* @brief 进程控制块
|
||||
*
|
||||
|
@ -49,6 +49,7 @@ extern struct sighand_struct INITIAL_SIGHAND;
|
||||
|
||||
extern void process_exit_sighand(struct process_control_block *pcb);
|
||||
extern void process_exit_signal(struct process_control_block *pcb);
|
||||
extern void initial_proc_init_signal(struct process_control_block *pcb);
|
||||
|
||||
// 设置初始进程的PCB
|
||||
#define INITIAL_PROC(proc) \
|
||||
@ -439,7 +440,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
|
||||
regs->rsi = (uint64_t)dst_argv;
|
||||
}
|
||||
// kdebug("execve ok");
|
||||
|
||||
// 设置进程的段选择子为用户态可访问
|
||||
regs->cs = USER_CS | 3;
|
||||
regs->ds = USER_DS | 3;
|
||||
regs->ss = USER_DS | 0x3;
|
||||
@ -464,7 +465,7 @@ exec_failed:;
|
||||
#pragma GCC optimize("O0")
|
||||
ul initial_kernel_thread(ul arg)
|
||||
{
|
||||
kinfo("initial proc running...\targ:%#018lx", arg);
|
||||
kinfo("initial proc running...\targ:%#018lx, vruntime=%d", arg, current_pcb->virtual_runtime);
|
||||
|
||||
scm_enable_double_buffer();
|
||||
|
||||
@ -624,6 +625,8 @@ void process_init()
|
||||
list_init(&initial_proc_union.pcb.list);
|
||||
wait_queue_init(&initial_proc_union.pcb.wait_child_proc_exit, NULL);
|
||||
|
||||
// 初始化init进程的signal相关的信息
|
||||
initial_proc_init_signal(current_pcb);
|
||||
// 临时设置IDLE进程的的虚拟运行时间为0,防止下面的这些内核线程的虚拟运行时间出错
|
||||
current_pcb->virtual_runtime = 0;
|
||||
barrier();
|
||||
|
@ -8,30 +8,41 @@
|
||||
|
||||
struct pt_regs
|
||||
{
|
||||
unsigned long r15;
|
||||
unsigned long r14;
|
||||
unsigned long r13;
|
||||
unsigned long r12;
|
||||
unsigned long r11;
|
||||
unsigned long r10;
|
||||
unsigned long r9;
|
||||
unsigned long r8;
|
||||
unsigned long rbx;
|
||||
unsigned long rcx;
|
||||
unsigned long rdx;
|
||||
unsigned long rsi;
|
||||
unsigned long rdi;
|
||||
unsigned long rbp;
|
||||
unsigned long ds;
|
||||
unsigned long es;
|
||||
unsigned long rax;
|
||||
unsigned long func;
|
||||
unsigned long errcode;
|
||||
unsigned long rip;
|
||||
unsigned long cs;
|
||||
unsigned long rflags;
|
||||
unsigned long rsp;
|
||||
unsigned long ss;
|
||||
unsigned long r15;
|
||||
unsigned long r14;
|
||||
unsigned long r13;
|
||||
unsigned long r12;
|
||||
unsigned long r11;
|
||||
unsigned long r10;
|
||||
unsigned long r9;
|
||||
unsigned long r8;
|
||||
unsigned long rbx;
|
||||
unsigned long rcx;
|
||||
unsigned long rdx;
|
||||
unsigned long rsi;
|
||||
unsigned long rdi;
|
||||
unsigned long rbp;
|
||||
unsigned long ds;
|
||||
unsigned long es;
|
||||
unsigned long rax;
|
||||
unsigned long func;
|
||||
unsigned long errcode;
|
||||
unsigned long rip;
|
||||
unsigned long cs;
|
||||
unsigned long rflags;
|
||||
unsigned long rsp;
|
||||
unsigned long ss;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 判断pt_regs是否来自用户态
|
||||
*
|
||||
* @param regs
|
||||
* @return __always_inline
|
||||
*/
|
||||
static inline int user_mode(struct pt_regs *regs)
|
||||
{
|
||||
return !!(regs->cs & 3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user