Hack to allow rustc to wait on non-child process.
Add sys:syscall for seeing active system calls
This commit is contained in:
@@ -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(),
|
||||
|
||||
@@ -238,7 +238,6 @@ impl PipeRead {
|
||||
} else {
|
||||
match self.condition.wait() {
|
||||
SwitchResult::Signal => {
|
||||
println!("Received signal during pipe read");
|
||||
return Err(Error::new(EINTR));
|
||||
},
|
||||
_ => ()
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
42
src/scheme/sys/syscall.rs
Normal 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())
|
||||
}
|
||||
@@ -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(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user