diff --git a/kernel/src/driver/tty/tty_device.rs b/kernel/src/driver/tty/tty_device.rs index 6f50bfc8..00303ba2 100644 --- a/kernel/src/driver/tty/tty_device.rs +++ b/kernel/src/driver/tty/tty_device.rs @@ -1,3 +1,5 @@ +use core::fmt::Debug; + use alloc::{ string::{String, ToString}, sync::{Arc, Weak}, @@ -97,7 +99,6 @@ pub enum PtyType { Pts, } -#[derive(Debug)] #[cast_to([sync] Device)] pub struct TtyDevice { name: String, @@ -144,6 +145,14 @@ impl TtyDevice { } } +impl Debug for TtyDevice { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("TtyDevice") + .field("name", &self.name) + .finish() + } +} + impl PollableInode for TtyDevice { fn poll(&self, private_data: &FilePrivateData) -> Result { let tty = TtyDevice::tty_core(private_data)?; diff --git a/kernel/src/filesystem/epoll/event_poll.rs b/kernel/src/filesystem/epoll/event_poll.rs index e53e0591..c93426b2 100644 --- a/kernel/src/filesystem/epoll/event_poll.rs +++ b/kernel/src/filesystem/epoll/event_poll.rs @@ -68,16 +68,13 @@ impl EventPoll { let fds: Vec = self.ep_items.keys().cloned().collect::>(); // 清理红黑树里面的epitems for fd in fds { - let file = ProcessManager::current_pcb() - .fd_table() - .read() - .get_file_by_fd(fd); + let fdtable = ProcessManager::current_pcb().basic().try_fd_table().clone(); + let file = fdtable.and_then(|fdtable| fdtable.read().get_file_by_fd(fd)); if let Some(file) = file { let epitm = self.ep_items.get(&fd).unwrap(); file.remove_epitem(epitm)?; } - self.ep_items.remove(&fd); } @@ -644,7 +641,12 @@ impl EventPoll { let epitems_guard = epitems.try_lock_irqsave()?; for epitem in epitems_guard.iter() { // The upgrade is safe because EventPoll always exists when the epitem is in the list - let epoll = epitem.epoll().upgrade().unwrap(); + let epoll = epitem.epoll().upgrade(); + if epoll.is_none() { + // 如果epoll已经被释放,则直接跳过 + continue; + } + let epoll = epoll.unwrap(); let mut epoll_guard = epoll.try_lock()?; let binding = epitem.clone(); let event_guard = binding.event().read(); diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 16682dc4..b19faef4 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -101,7 +101,6 @@ impl LockedFATFsInfo { } } -#[derive(Debug)] pub struct FATInode { /// 指向父Inode的弱引用 parent: Weak, @@ -128,6 +127,14 @@ pub struct FATInode { page_cache: Option>, } +impl Debug for FATInode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("FATInode") + .field("inode_id", &self.metadata.inode_id) + .finish() + } +} + impl FATInode { /// 将inode的元数据与磁盘同步 pub fn synchronize_metadata(&mut self) { diff --git a/kernel/src/filesystem/vfs/utils.rs b/kernel/src/filesystem/vfs/utils.rs index 770de48d..0487f1d6 100644 --- a/kernel/src/filesystem/vfs/utils.rs +++ b/kernel/src/filesystem/vfs/utils.rs @@ -45,7 +45,7 @@ pub fn user_path_at( let mut inode = ROOT_INODE(); let ret_path; // 如果path不是绝对路径,则需要拼接 - if path.as_bytes()[0] != b'/' { + if path.is_empty() || path.as_bytes()[0] != b'/' { // 如果dirfd不是AT_FDCWD,则需要检查dirfd是否是目录 if dirfd != AtFlags::AT_FDCWD.bits() { let binding = pcb.fd_table(); diff --git a/kernel/src/process/fork.rs b/kernel/src/process/fork.rs index 95b840ae..e1e34554 100644 --- a/kernel/src/process/fork.rs +++ b/kernel/src/process/fork.rs @@ -291,14 +291,14 @@ impl ProcessManager { ) -> Result<(), SystemError> { // 如果不共享文件描述符表,则拷贝文件描述符表 if !clone_flags.contains(CloneFlags::CLONE_FILES) { - let new_fd_table = current_pcb.basic().fd_table().unwrap().read().clone(); + let new_fd_table = current_pcb.basic().try_fd_table().unwrap().read().clone(); let new_fd_table = Arc::new(RwLock::new(new_fd_table)); new_pcb.basic_mut().set_fd_table(Some(new_fd_table)); } else { // 如果共享文件描述符表,则直接拷贝指针 new_pcb .basic_mut() - .set_fd_table(current_pcb.basic().fd_table().clone()); + .set_fd_table(current_pcb.basic().try_fd_table().clone()); } return Ok(()); diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index b86db46b..88535663 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -427,6 +427,7 @@ impl ProcessManager { // 关中断 let _irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() }; + let pid: Pid; { let pcb = ProcessManager::current_pcb(); @@ -472,7 +473,6 @@ impl ProcessManager { drop(thread); unsafe { pcb.basic_mut().set_user_vm(None) }; pcb.exit_files(); - // TODO 由于未实现进程组,tty记录的前台进程组等于当前进程,故退出前要置空 // 后续相关逻辑需要在SYS_EXIT_GROUP系统调用中实现 if let Some(tty) = pcb.sig_info_irqsave().tty() { @@ -483,7 +483,6 @@ impl ProcessManager { } } pcb.sig_info_mut().set_tty(None); - pcb.clear_pg_and_session_reference(); drop(pcb); ProcessManager::exit_notify(); @@ -1048,7 +1047,7 @@ impl ProcessControlBlock { /// 获取文件描述符表的Arc指针 #[inline(always)] pub fn fd_table(&self) -> Arc> { - return self.basic.read().fd_table().unwrap(); + return self.basic.read().try_fd_table().unwrap(); } #[inline(always)] @@ -1218,7 +1217,12 @@ impl ProcessControlBlock { /// Exit fd table when process exit fn exit_files(&self) { - self.basic.write_irqsave().set_fd_table(None); + // 关闭文件描述符表 + // 这里这样写的原因是避免某些inode在关闭时需要访问当前进程的basic,导致死锁 + let mut guard = self.basic.write_irqsave(); + let old = guard.set_fd_table(None); + drop(guard); + drop(old) } pub fn children_read_irqsave(&self) -> RwLockReadGuard> { @@ -1369,12 +1373,17 @@ impl ProcessBasicInfo { self.user_vm = user_vm; } - pub fn fd_table(&self) -> Option>> { + pub fn try_fd_table(&self) -> Option>> { return self.fd_table.clone(); } - pub fn set_fd_table(&mut self, fd_table: Option>>) { + pub fn set_fd_table( + &mut self, + fd_table: Option>>, + ) -> Option>> { + let old = self.fd_table.take(); self.fd_table = fd_table; + return old; } } diff --git a/user/dadk/config/held-0.1.0.toml b/user/dadk/config/held-0.1.0.toml index abcb97c0..25104f91 100644 --- a/user/dadk/config/held-0.1.0.toml +++ b/user/dadk/config/held-0.1.0.toml @@ -25,7 +25,7 @@ source = "git" source-path = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/Held.git" # git标签或分支 # 注意: branch和revision只能二选一,且source要设置为"git" -revision = "f192df4" +revision = "5163c56" # 构建相关信息 [build]