From 8ec5d4726b49b4ce4e76308ffe40cd6f5aaa61f5 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Sun, 22 Oct 2017 21:13:29 -0600 Subject: [PATCH] Hack to allow rustc to wait on non-child process. Add sys:syscall for seeing active system calls --- src/context/context.rs | 3 + src/scheme/pipe.rs | 1 - src/scheme/sys/iostat.rs | 1 - src/scheme/sys/mod.rs | 8 +-- src/scheme/sys/syscall.rs | 42 ++++++++++++++ src/syscall/debug.rs | 116 +++++++++++++++++++------------------- src/syscall/mod.rs | 16 ++++++ src/syscall/process.rs | 21 ++++++- 8 files changed, 138 insertions(+), 70 deletions(-) create mode 100644 src/scheme/sys/syscall.rs diff --git a/src/context/context.rs b/src/context/context.rs index 3eda179e..6702be37 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -53,6 +53,8 @@ pub struct Context { pub running: bool, /// CPU ID, if locked pub cpu_id: Option<usize>, + /// Current system call + pub syscall: Option<(usize, usize, usize, usize, usize, usize)>, /// Context is halting parent pub vfork: bool, /// Context is being waited on @@ -112,6 +114,7 @@ impl Context { status: Status::Blocked, running: false, cpu_id: None, + syscall: None, vfork: false, waitpid: Arc::new(WaitMap::new()), pending: VecDeque::new(), diff --git a/src/scheme/pipe.rs b/src/scheme/pipe.rs index f30a901a..d39de348 100644 --- a/src/scheme/pipe.rs +++ b/src/scheme/pipe.rs @@ -238,7 +238,6 @@ impl PipeRead { } else { match self.condition.wait() { SwitchResult::Signal => { - println!("Received signal during pipe read"); return Err(Error::new(EINTR)); }, _ => () diff --git a/src/scheme/sys/iostat.rs b/src/scheme/sys/iostat.rs index c365acdf..b0b49ada 100644 --- a/src/scheme/sys/iostat.rs +++ b/src/scheme/sys/iostat.rs @@ -15,7 +15,6 @@ pub fn resource() -> Result<Vec<u8>> { let contexts = context::contexts(); for (id, context_lock) in contexts.iter() { let context = context_lock.read(); - rows.push((*id, context.name.lock().clone(), context.files.lock().clone())); } } diff --git a/src/scheme/sys/mod.rs b/src/scheme/sys/mod.rs index 22426f44..e85202d9 100644 --- a/src/scheme/sys/mod.rs +++ b/src/scheme/sys/mod.rs @@ -15,10 +15,8 @@ mod exe; mod iostat; mod scheme; mod scheme_num; +mod syscall; mod uname; -//mod interrupt; -//mod log; -//mod test; struct Handle { path: &'static [u8], @@ -46,10 +44,8 @@ impl SysScheme { files.insert(b"iostat", Box::new(move || iostat::resource())); files.insert(b"scheme", Box::new(move || scheme::resource())); files.insert(b"scheme_num", Box::new(move || scheme_num::resource())); + files.insert(b"syscall", Box::new(move || syscall::resource())); files.insert(b"uname", Box::new(move || uname::resource())); - //files.insert(b"interrupt", Box::new(move || interrupt::resource())); - //files.insert(b"log", Box::new(move || log::resource())); - //files.insert(b"test", Box::new(move || test::resource())); SysScheme { next_id: AtomicUsize::new(0), diff --git a/src/scheme/sys/syscall.rs b/src/scheme/sys/syscall.rs new file mode 100644 index 00000000..1556e395 --- /dev/null +++ b/src/scheme/sys/syscall.rs @@ -0,0 +1,42 @@ +use collections::{String, Vec}; +use core::fmt::Write; +use core::str; + +use context; +use syscall; +use syscall::error::Result; + +pub fn resource() -> Result<Vec<u8>> { + let mut string = String::new(); + + { + let mut rows = Vec::new(); + { + let contexts = context::contexts(); + for (id, context_lock) in contexts.iter() { + let context = context_lock.read(); + rows.push((*id, context.name.lock().clone(), context.syscall.clone())); + } + } + + for row in rows.iter() { + let id: usize = row.0.into(); + let name = str::from_utf8(&row.1).unwrap_or("."); + + let _ = writeln!(string, "{}: {}", id, name); + + if let Some((a, b, c, d, e, f)) = row.2 { + match syscall::debug::format_call(a, b, c, d, e, f) { + Ok(data) => { + let _ = writeln!(string, " {}", data); + }, + Err(err) => { + let _ = writeln!(string, " error: {}", err); + } + }; + } + } + } + + Ok(string.into_bytes()) +} diff --git a/src/syscall/debug.rs b/src/syscall/debug.rs index fbb0a53d..6787ae22 100644 --- a/src/syscall/debug.rs +++ b/src/syscall/debug.rs @@ -1,6 +1,6 @@ use core::mem; use core::ops::Range; -use collections::Vec; +use collections::{String, Vec}; use super::data::{Stat, TimeSpec}; use super::error::Result; @@ -58,53 +58,53 @@ impl<'a> ::core::fmt::Debug for ByteStr<'a> { } -pub fn print_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> Result<()> { - match a { - SYS_OPEN => print!( +pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> Result<String> { + Ok(match a { + SYS_OPEN => format!( "open({:?}, {:#X})", validate_slice(b as *const u8, c).map(ByteStr), d ), - SYS_CHMOD => print!( + SYS_CHMOD => format!( "chmod({:?}, {:#o})", validate_slice(b as *const u8, c).map(ByteStr), d ), - SYS_RMDIR => print!( + SYS_RMDIR => format!( "rmdir({:?})", validate_slice(b as *const u8, c).map(ByteStr) ), - SYS_UNLINK => print!( + SYS_UNLINK => format!( "unlink({:?})", validate_slice(b as *const u8, c).map(ByteStr) ), - SYS_CLOSE => print!( + SYS_CLOSE => format!( "close({})", b ), - SYS_DUP => print!( + SYS_DUP => format!( "dup({}, {:?})", b, validate_slice(c as *const u8, d).map(ByteStr) ), - SYS_DUP2 => print!( + SYS_DUP2 => format!( "dup2({}, {}, {:?})", b, c, validate_slice(d as *const u8, e).map(ByteStr) ), - SYS_READ => print!( + SYS_READ => format!( "read({}, {:#X}, {})", b, c, d ), - SYS_WRITE => print!( + SYS_WRITE => format!( "write({}, {:#X}, {})", b, c, d ), - SYS_LSEEK => print!( + SYS_LSEEK => format!( "lseek({}, {}, {} ({}))", b, c as isize, @@ -116,7 +116,7 @@ pub fn print_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> }, d ), - SYS_FCNTL => print!( + SYS_FCNTL => format!( "fcntl({}, {} ({}), {:#X})", b, match c { @@ -130,28 +130,28 @@ pub fn print_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> c, d ), - SYS_FEVENT => print!( + SYS_FEVENT => format!( "fevent({}, {:#X})", b, c ), - SYS_FMAP => print!( + SYS_FMAP => format!( "fmap({}, {:#X}, {})", b, c, d ), - SYS_FUNMAP => print!( + SYS_FUNMAP => format!( "funmap({:#X})", b ), - SYS_FPATH => print!( + SYS_FPATH => format!( "fpath({}, {:#X}, {})", b, c, d ), - SYS_FSTAT => print!( + SYS_FSTAT => format!( "fstat({}, {:?})", b, validate_slice( @@ -159,41 +159,41 @@ pub fn print_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> d/mem::size_of::<Stat>() ), ), - SYS_FSTATVFS => print!( + SYS_FSTATVFS => format!( "fstatvfs({}, {:#X}, {})", b, c, d ), - SYS_FSYNC => print!( + SYS_FSYNC => format!( "fsync({})", b ), - SYS_FTRUNCATE => print!( + SYS_FTRUNCATE => format!( "ftruncate({}, {})", b, c ), - SYS_BRK => print!( + SYS_BRK => format!( "brk({:#X})", b ), - SYS_CHDIR => print!( + SYS_CHDIR => format!( "chdir({:?})", validate_slice(b as *const u8, c).map(ByteStr) ), - SYS_CLOCK_GETTIME => print!( + SYS_CLOCK_GETTIME => format!( "clock_gettime({}, {:?})", b, validate_slice_mut(c as *mut TimeSpec, 1) ), - SYS_CLONE => print!( + SYS_CLONE => format!( "clone({})", b ), //TODO: Cleanup, do not allocate - SYS_EXECVE => print!( + SYS_EXECVE => format!( "execve({:?}, {:?})", validate_slice(b as *const u8, c).map(ByteStr), validate_slice( @@ -206,11 +206,11 @@ pub fn print_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> .and_then(|s| ::core::str::from_utf8(s).ok()) ).collect::<Vec<Option<&str>>>() ), - SYS_EXIT => print!( + SYS_EXIT => format!( "exit({})", b ), - SYS_FUTEX => print!( + SYS_FUTEX => format!( "futex({:#X} [{:?}], {}, {}, {}, {})", b, validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0]), @@ -219,96 +219,96 @@ pub fn print_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> e, f ), - SYS_GETCWD => print!( + SYS_GETCWD => format!( "getcwd({:#X}, {})", b, c ), - SYS_GETEGID => print!("getgid()"), - SYS_GETENS => print!("getens()"), - SYS_GETEUID => print!("geteuid()"), - SYS_GETGID => print!("getgid()"), - SYS_GETNS => print!("getns()"), - SYS_GETPID => print!("getpid()"), - SYS_GETUID => print!("getuid()"), - SYS_IOPL => print!( + SYS_GETEGID => format!("getgid()"), + SYS_GETENS => format!("getens()"), + SYS_GETEUID => format!("geteuid()"), + SYS_GETGID => format!("getgid()"), + SYS_GETNS => format!("getns()"), + SYS_GETPID => format!("getpid()"), + SYS_GETUID => format!("getuid()"), + SYS_IOPL => format!( "iopl({})", b ), - SYS_KILL => print!( + SYS_KILL => format!( "kill({}, {})", b, c ), - SYS_SIGRETURN => print!("sigreturn()"), - SYS_SIGACTION => print!( + SYS_SIGRETURN => format!("sigreturn()"), + SYS_SIGACTION => format!( "sigaction({}, {:#X}, {:#X}, {:#X})", b, c, d, e ), - SYS_MKNS => print!( + SYS_MKNS => format!( "mkns({:?})", validate_slice(b as *const [usize; 2], c) ), - SYS_NANOSLEEP => print!( + SYS_NANOSLEEP => format!( "nanosleep({:?}, ({}, {}))", validate_slice(b as *const TimeSpec, 1), c, d ), - SYS_PHYSALLOC => print!( + SYS_PHYSALLOC => format!( "physalloc({})", b ), - SYS_PHYSFREE => print!( + SYS_PHYSFREE => format!( "physfree({:#X}, {})", b, c ), - SYS_PHYSMAP => print!( + SYS_PHYSMAP => format!( "physmap({:#X}, {}, {:#X})", b, c, d ), - SYS_PHYSUNMAP => print!( + SYS_PHYSUNMAP => format!( "physunmap({:#X})", b ), - SYS_VIRTTOPHYS => print!( + SYS_VIRTTOPHYS => format!( "virttophys({:#X})", b ), - SYS_PIPE2 => print!( + SYS_PIPE2 => format!( "pipe2({:?}, {})", validate_slice_mut(b as *mut usize, 2), c ), - SYS_SETREGID => print!( + SYS_SETREGID => format!( "setregid({}, {})", b, c ), - SYS_SETRENS => print!( + SYS_SETRENS => format!( "setrens({}, {})", b, c ), - SYS_SETREUID => print!( + SYS_SETREUID => format!( "setreuid({}, {})", b, c ), - SYS_WAITPID => print!( - "waitpid({}, {}, {})", + SYS_WAITPID => format!( + "waitpid({}, {:#X}, {})", b, c, d ), - SYS_YIELD => print!("yield()"), - _ => print!( + SYS_YIELD => format!("yield()"), + _ => format!( "UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X})", a, a, b, @@ -317,7 +317,5 @@ pub fn print_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> e, f ) - } - - Ok(()) + }) } diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index ba851872..22e62b1c 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -168,8 +168,24 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize } */ + { + let contexts = ::context::contexts(); + if let Some(context_lock) = contexts.current() { + let mut context = context_lock.write(); + context.syscall = Some((a, b, c, d, e, f)); + } + } + let result = inner(a, b, c, d, e, f, bp, stack); + { + let contexts = ::context::contexts(); + if let Some(context_lock) = contexts.current() { + let mut context = context_lock.write(); + context.syscall = None; + } + } + /* if debug { let contexts = ::context::contexts(); diff --git a/src/syscall/process.rs b/src/syscall/process.rs index b312ec82..2add5cdd 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -1130,11 +1130,11 @@ fn reap(pid: ContextId) -> Result<ContextId> { } pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<ContextId> { - let waitpid = { + let (ppid, waitpid) = { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - context.waitpid.clone() + (context.id, context.waitpid.clone()) }; let mut tmp = [0]; @@ -1158,7 +1158,22 @@ pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<Contex reap(w_pid) } } else { - if flags & WNOHANG == WNOHANG { + let status = { + let contexts = context::contexts(); + let context_lock = contexts.get(pid).ok_or(Error::new(ECHILD))?; + let mut context = context_lock.write(); + if context.ppid != ppid { + println!("Hack for rustc - changing ppid of {} from {} to {}", context.id.into(), context.ppid.into(), ppid.into()); + context.ppid = ppid; + //return Err(Error::new(ECHILD)); + } + context.status.clone() + }; + + if let context::Status::Exited(status) = status { + status_slice[0] = status; + reap(pid) + } else if flags & WNOHANG == WNOHANG { if let Some(status) = waitpid.receive_nonblock(&pid) { status_slice[0] = status; reap(pid) -- GitLab