Hack to allow rustc to wait on non-child process.

Add sys:syscall for seeing active system calls
This commit is contained in:
Jeremy Soller
2017-10-22 21:13:29 -06:00
parent ef70cd257c
commit 8ec5d4726b
8 changed files with 138 additions and 70 deletions

View File

@@ -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(),

View File

@@ -238,7 +238,6 @@ impl PipeRead {
} else {
match self.condition.wait() {
SwitchResult::Signal => {
println!("Received signal during pipe read");
return Err(Error::new(EINTR));
},
_ => ()

View File

@@ -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()));
}
}

View File

@@ -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),

42
src/scheme/sys/syscall.rs Normal file
View File

@@ -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())
}

View File

@@ -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(())
})
}

View File

@@ -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();

View File

@@ -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)