Browse Source

Patch add abort func (#120)

* 对于除了sigkill以外的信号,也加入队列

* bugfix:libc中,注册信号处理函数时,总是注册sigkill的问题

* 增加getpid系统调用

* 增加了raise、kill、abort
login 2 years ago
parent
commit
c588d6f77f

+ 51 - 27
kernel/src/ipc/signal.rs

@@ -64,6 +64,7 @@ pub static DEFAULT_SIGACTION_IGNORE: sigaction = sigaction {
 pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
     let pid: pid_t = regs.r8 as pid_t;
     let sig: SignalNumber = SignalNumber::from(regs.r9 as i32);
+
     if sig == SignalNumber::INVALID {
         // 传入的signal数值不合法
         kwarn!("Not a valid signal number");
@@ -86,29 +87,43 @@ pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
     };
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
 
-    let retval = signal_kill_something_info(sig, Some(&mut info), pid) as u64;
-
+    let retval = signal_kill_something_info(sig, Some(&mut info), pid);
+    let x;
+    if retval.is_ok() {
+        x = retval.unwrap();
+    } else {
+        x = retval.unwrap_err();
+    }
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
-    return retval;
+
+    return x as u64;
 }
 
 /// 通过kill的方式向目标进程发送信号
 /// @param sig 要发送的信号
 /// @param info 要发送的信息
 /// @param pid 进程id(目前只支持pid>0)
-fn signal_kill_something_info(sig: SignalNumber, info: Option<&mut siginfo>, pid: pid_t) -> i32 {
+fn signal_kill_something_info(
+    sig: SignalNumber,
+    info: Option<&mut siginfo>,
+    pid: pid_t,
+) -> Result<i32, i32> {
     // 暂时不支持特殊的kill操作
     if pid <= 0 {
         kwarn!("Kill operation not support: pid={}", pid);
-        return -(ENOTSUP as i32);
+        return Err(-(ENOTSUP as i32));
     }
 
     // kill单个进程
     return signal_kill_proc_info(sig, info, pid);
 }
 
-fn signal_kill_proc_info(sig: SignalNumber, info: Option<&mut siginfo>, pid: pid_t) -> i32 {
-    let mut retval: i32 = -(ESRCH as i32);
+fn signal_kill_proc_info(
+    sig: SignalNumber,
+    info: Option<&mut siginfo>,
+    pid: pid_t,
+) -> Result<i32, i32> {
+    let mut retval = Err(-(ESRCH as i32));
 
     // step1: 当进程管理模块拥有pcblist_lock之后,对其加锁
 
@@ -147,16 +162,16 @@ fn signal_send_sig_info(
     sig: SignalNumber,
     info: Option<&mut siginfo>,
     target_pcb: &mut process_control_block,
-) -> i32 {
+) -> Result<i32, i32> {
     // kdebug!("signal_send_sig_info");
     // 检查sig是否符合要求,如果不符合要求,则退出。
     if !verify_signal(sig) {
-        return -(EINVAL as i32);
+        return Err(-(EINVAL as i32));
     }
 
     // 信号符合要求,可以发送
 
-    let mut retval = -(ESRCH as i32);
+    let mut retval = Err(-(ESRCH as i32));
     let mut flags: u64 = 0;
     // 如果上锁成功,则发送信号
     if !lock_process_sighand(target_pcb, &mut flags).is_none() {
@@ -214,7 +229,7 @@ fn send_signal_locked(
     info: Option<&mut siginfo>,
     pcb: &mut process_control_block,
     pt: PidType,
-) -> i32 {
+) -> Result<i32, i32> {
     // 是否强制发送信号
     let mut force_send = false;
     // signal的信息为空
@@ -240,13 +255,12 @@ fn send_signal_locked(
 /// @return i32 错误码
 fn __send_signal_locked(
     sig: SignalNumber,
-    _info: Option<&mut siginfo>,
+    info: Option<&mut siginfo>,
     pcb: &mut process_control_block,
     pt: PidType,
     _force_send: bool,
-) -> i32 {
+) -> Result<i32, i32> {
     // kdebug!("__send_signal_locked");
-    let mut retval = 0;
 
     // 判断该进入该函数时,是否已经持有了锁
     assert!(spin_is_locked(unsafe { &(*pcb.sighand).siglock }));
@@ -257,11 +271,26 @@ fn __send_signal_locked(
     if sig == SignalNumber::SIGKILL || (pcb.flags & (PF_KTHREAD as u64)) != 0 {
         complete_signal(sig, pcb, pt);
     } else {
-        // todo: 如果是其他信号,则加入到sigqueue内,然后complete_signal
-        retval = -(ENOTSUP as i32);
+        // 如果是其他信号,则加入到sigqueue内,然后complete_signal
+        let mut q: siginfo;
+        match info {
+            Some(x) => {
+                // 已经显式指定了siginfo,则直接使用它。
+                q = x.clone();
+            }
+            None => {
+                // 不需要显示指定siginfo,因此设置为默认值
+                q = siginfo::new(sig, 0, si_code_val::SI_USER);
+                q._sinfo.data._sifields._kill._pid = current_pcb().pid;
+            }
+        }
+
+        let sq: &mut SigQueue = SigQueue::from_c_void(current_pcb().sig_pending.sigqueue);
+        sq.q.push(q);
+        complete_signal(sig, pcb, pt);
     }
     compiler_fence(core::sync::atomic::Ordering::SeqCst);
-    return retval;
+    return Ok(0);
 }
 
 /// @brief 将信号添加到目标进程的sig_pending。在引入进程组后,本函数还将负责把信号传递给整个进程组。
@@ -407,8 +436,7 @@ pub extern "C" fn do_signal(regs: &mut pt_regs) {
 
     // 做完上面的检查后,开中断
     sti();
-    // return;
-    // kdebug!("do_signal");
+
     let oldset = current_pcb().sig_blocked;
     loop {
         let (sig_number, info, ka) = get_signal_to_deliver(regs.clone());
@@ -790,7 +818,7 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
         }
         let mask: sigset_t = unsafe { (*act).sa_mask };
         let _input_sah = unsafe { (*act).sa_handler as u64 };
-
+        // kdebug!("_input_sah={}", _input_sah);
         match _input_sah {
             USER_SIG_DFL | USER_SIG_IGN => {
                 if _input_sah == USER_SIG_DFL {
@@ -818,6 +846,7 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
                 };
             }
         }
+        // kdebug!("new_ka={:?}", new_ka);
         // 如果用户手动给了sa_restorer,那么就置位SA_FLAG_RESTORER,否则报错。(用户必须手动指定restorer)
         if new_ka.sa_restorer != NULL as u64 {
             new_ka.sa_flags |= SA_FLAG_RESTORER;
@@ -875,6 +904,7 @@ pub extern "C" fn sys_sigaction(regs: &mut pt_regs) -> u64 {
             (*old_act).sa_restorer = old_ka.sa_restorer as *mut c_void;
         }
     }
+
     return retval as u64;
 }
 
@@ -946,8 +976,7 @@ fn do_sigaction(
             let mut mask: sigset_t = 0;
             sigset_clear(&mut mask);
             sigset_add(&mut mask, sig);
-            let sq = pcb.sig_pending.sigqueue as *mut SigQueue;
-            let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
+            let sq: &mut SigQueue = SigQueue::from_c_void(pcb.sig_pending.sigqueue);
             sq.flush_by_mask(&mask);
 
             // todo: 当有了多个线程后,在这里进行操作,把每个线程的sigqueue都进行刷新
@@ -966,11 +995,6 @@ pub fn sigmask(sig: SignalNumber) -> u64 {
 
 #[no_mangle]
 pub extern "C" fn sys_rt_sigreturn(regs: &mut pt_regs) -> u64 {
-    // kdebug!(
-    //     "sigreturn, pid={}, regs.rsp=0x{:018x}",
-    //     current_pcb().pid,
-    //     regs.rsp
-    // );
     let frame = regs.rsp as usize as *mut sigframe;
 
     // 如果当前的rsp不来自用户态,则认为产生了错误(或被SROP攻击)

+ 10 - 3
kernel/src/ipc/signal_types.rs

@@ -93,9 +93,9 @@ pub const SA_ALL_FLAGS: u64 = SA_FLAG_IGN | SA_FLAG_DFL | SA_FLAG_RESTORER | SA_
 // ============ sigaction结构体中的的sa_flags的可选值 end ===========
 
 /// 用户态程序传入的SIG_DFL的值
-pub const USER_SIG_DFL: u64 = 1u64 << 0;
+pub const USER_SIG_DFL: u64 = 0;
 /// 用户态程序传入的SIG_IGN的值
-pub const USER_SIG_IGN: u64 = 1u64 << 1;
+pub const USER_SIG_IGN: u64 = 1;
 
 /**
  * @brief 信号处理结构体
@@ -544,6 +544,13 @@ impl SigQueue {
             drop(x)
         }
     }
+
+    /// @brief 从C的void*指针转换为static生命周期的可变引用
+    pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue{
+        let sq = p as *mut SigQueue;
+        let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
+        return sq;
+    }
 }
 
 impl Default for SigQueue {
@@ -587,7 +594,7 @@ pub fn sigset_delmask(set: &mut sigset_t, mask: u64) {
 /// @brief 判断两个sigset是否相等
 #[inline]
 pub fn sigset_equal(a: &sigset_t, b: &sigset_t) -> bool {
-    if _NSIG_U64_CNT == 1{
+    if _NSIG_U64_CNT == 1 {
         return *a == *b;
     }
     return false;

+ 10 - 0
kernel/src/process/pid.rs

@@ -1,3 +1,5 @@
+use crate::{include::bindings::bindings::pt_regs, arch::x86_64::asm::current::current_pcb};
+
 #[allow(dead_code)]
 #[derive(Debug, Clone, Copy)]
 #[repr(u8)]
@@ -15,4 +17,12 @@ impl PartialEq for PidType {
     fn eq(&self, other: &PidType) -> bool {
         *self as u8 == *other as u8
     }
+}
+
+/**
+ * @brief 获取当前进程的pid
+ */
+#[no_mangle]
+pub extern "C" fn sys_getpid(_regs: &pt_regs)->u64{
+    return current_pcb().pid as u64;
 }

+ 3 - 1
kernel/src/syscall/syscall.c

@@ -22,6 +22,7 @@ extern uint64_t sys_unlink_at(struct pt_regs *regs);
 extern uint64_t sys_kill(struct pt_regs *regs);
 extern uint64_t sys_sigaction(struct pt_regs * regs);
 extern uint64_t sys_rt_sigreturn(struct pt_regs * regs);
+extern uint64_t sys_getpid(struct pt_regs * regs);
 
 /**
  * @brief 导出系统调用处理函数的符号
@@ -590,6 +591,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
     [23] = sys_kill,
     [24] = sys_sigaction,
     [25] = sys_rt_sigreturn,
-    [26 ... 254] = system_call_not_exists,
+    [26] = sys_getpid,
+    [27 ... 254] = system_call_not_exists,
     [255] = sys_ahci_end_req,
 };

+ 1 - 0
kernel/src/syscall/syscall_num.h

@@ -37,5 +37,6 @@
 #define SYS_KILL 23         // kill一个进程(向这个进程发出信号)
 #define SYS_SIGACTION 24    // 设置进程的信号处理动作
 #define SYS_RT_SIGRETURN 25 // 从信号处理函数返回
+#define SYS_GETPID 26 // 获取当前进程的pid(进程标识符)
 
 #define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用

+ 1 - 1
user/apps/shell/cmd.c

@@ -529,7 +529,7 @@ int shell_cmd_kill(int argc, char **argv)
         retval = -EINVAL;
         goto out;
     }
-    retval = syscall_invoke(SYS_KILL, atoi(argv[1]), SIGKILL, 0, 0, 0, 0, 0, 0);
+    retval = kill(atoi(argv[1]), SIGKILL);
 out:;
     free(argv);
     return retval;

+ 7 - 2
user/libs/libc/src/include/signal.h

@@ -40,7 +40,10 @@
 #define SIGRTMIN 32
 #define SIGRTMAX MAX_SIG_NUM
 
-typedef void (*__sighandler_t) (int);
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL ((__sighandler_t)0) /* Default action.  */
+#define SIG_IGN ((__sighandler_t)1) /* Ignore signal.  */
 
 // 注意,该结构体最大16字节
 union __sifields {
@@ -86,4 +89,6 @@ struct sigaction
 };
 
 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
-int signal(int signum, __sighandler_t handler);
+int signal(int signum, __sighandler_t handler);
+int raise(int sig);
+int kill(pid_t, int sig);

+ 29 - 6
user/libs/libc/src/signal.c

@@ -14,10 +14,10 @@ void __libc_sa_restorer()
 
 /**
  * @brief 设置信号处理动作(简单版本)
- * 
- * @param signum 
- * @param handler 
- * @return int 
+ *
+ * @param signum
+ * @param handler
+ * @return int
  */
 int signal(int signum, __sighandler_t handler)
 {
@@ -27,12 +27,12 @@ int signal(int signum, __sighandler_t handler)
     sa.sa_restorer = &__libc_sa_restorer;
     // printf("handler address: %#018lx\n", handler);
     // printf("restorer address: %#018lx\n", &__libc_sa_restorer);
-    sigaction(SIGKILL, &sa, NULL);
+    sigaction(signum, &sa, NULL);
 }
 
 /**
  * @brief 设置信号处理动作
- * 
+ *
  * @param signum 信号
  * @param act 处理动作(不可为NULL)
  * @param oldact 返回的旧的处理动作(若为NULL,则不返回)
@@ -41,4 +41,27 @@ int signal(int signum, __sighandler_t handler)
 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
 {
     return syscall_invoke(SYS_SIGACTION, (uint64_t)signum, (uint64_t)act, (uint64_t)oldact, 0, 0, 0, 0, 0);
+}
+
+/**
+ * @brief 向当前进程发送一个信号
+ *
+ * @param sig signal number
+ * @return int 错误码
+ */
+int raise(int sig)
+{
+    return kill(getpid(), sig);
+}
+
+/**
+ * @brief 
+ *
+ * @param pid 进程的标识符
+ * @param sig signal number
+ * @return int 错误码
+ */
+int kill(pid_t pid, int sig)
+{
+    syscall_invoke(SYS_KILL, pid, sig, 0, 0, 0, 0, 0, 0);
 }

+ 14 - 2
user/libs/libc/src/stdlib.c

@@ -1,7 +1,8 @@
-#include <libc/src/unistd.h>
-#include <libc/src/stdlib.h>
 #include <libc/src/ctype.h>
+#include <libc/src/stdlib.h>
+#include <libc/src/unistd.h>
 #include <libsystem/syscall.h>
+#include <libc/src/include/signal.h>
 
 int abs(int i)
 {
@@ -54,4 +55,15 @@ int atoi(const char *str)
 void exit(int status)
 {
     syscall_invoke(SYS_EXIT, status, 0, 0, 0, 0, 0, 0, 0);
+}
+
+/**
+ * @brief 通过发送SIGABRT,从而退出当前进程
+ *
+ */
+void abort()
+{
+    // step1:设置SIGABRT的处理函数为SIG_DFL
+    signal(SIGABRT, SIG_DFL);
+    raise(SIGABRT);
 }

+ 7 - 1
user/libs/libc/src/stdlib.h

@@ -39,4 +39,10 @@ int atoi(const char * str);
  * 
  * @param status 
  */
-void exit(int status);
+void exit(int status);
+
+/**
+ * @brief 通过发送SIGABRT,从而退出当前进程
+ * 
+ */
+void abort();

+ 17 - 7
user/libs/libc/src/unistd.c

@@ -1,10 +1,10 @@
-#include <libc/src/unistd.h>
-#include <libsystem/syscall.h>
 #include <libc/src/errno.h>
-#include <libc/src/stdio.h>
+#include <libc/src/fcntl.h>
 #include <libc/src/stddef.h>
+#include <libc/src/stdio.h>
 #include <libc/src/string.h>
-#include <libc/src/fcntl.h>
+#include <libc/src/unistd.h>
+#include <libsystem/syscall.h>
 
 /**
  * @brief 关闭文件接口
@@ -163,11 +163,11 @@ int rmdir(const char *path)
 
 /**
  * @brief 删除文件
- * 
+ *
  * @param path 绝对路径
- * @return int 
+ * @return int
  */
-int rm(const char * path)
+int rm(const char *path)
 {
     return syscall_invoke(SYS_UNLINK_AT, 0, (uint64_t)path, 0, 0, 0, 0, 0, 0);
 }
@@ -193,4 +193,14 @@ void swab(void *restrict src, void *restrict dest, ssize_t nbytes)
         _src += transfer;
         _dest += transfer;
     }
+}
+
+/**
+ * @brief 获取当前进程的pid(进程标识符)
+ * 
+ * @return pid_t 当前进程的pid
+ */
+pid_t getpid(void)
+{
+    syscall_invoke(SYS_GETPID, 0, 0, 0, 0, 0, 0, 0, 0);
 }

+ 3 - 1
user/libs/libc/src/unistd.h

@@ -114,4 +114,6 @@ int rm(const char * path);
  *  @param dest  目的地址
  * @param nbytes  交换字节数
  */
-void swab(void *restrict src, void *restrict dest, ssize_t nbytes);
+void swab(void *restrict src, void *restrict dest, ssize_t nbytes);
+
+pid_t getpid(void);

+ 1 - 0
user/libs/libsystem/syscall.h

@@ -31,6 +31,7 @@
 #define SYS_KILL 23         // kill一个进程(向这个进程发出信号)
 #define SYS_SIGACTION 24    // 设置进程的信号处理动作
 #define SYS_RT_SIGRETURN 25 // 从信号处理函数返回
+#define SYS_GETPID 26 // 获取当前进程的pid(进程标识符)
 
 /**
  * @brief 用户态系统调用函数