fn run_task(task_owner: TaskOwner, exceptions: zx::Channel) -> Result<i32, Error> {
    let task = &task_owner.task;
    let mut buffer = zx::MessageBuf::new();
    loop {
        read_channel_sync(&exceptions, &mut buffer)?;

        let info = as_exception_info(&buffer);
        assert!(buffer.n_handles() == 1);
        let exception = zx::Exception::from(buffer.take_handle(0).unwrap());

        if info.type_ != ZX_EXCP_POLICY_ERROR {
            info!("exception type: 0x{:x}", info.type_);
            exception.set_exception_state(&ZX_EXCEPTION_STATE_TRY_NEXT)?;
            continue;
        }

        let thread = exception.get_thread()?;
        assert!(
            thread.get_koid() == task.thread.get_koid(),
            "Exception thread did not match task thread."
        );

        let report = thread.get_exception_report()?;
        if report.context.synth_code != ZX_EXCP_POLICY_CODE_BAD_SYSCALL {
            info!("exception synth_code: {}", report.context.synth_code);
            exception.set_exception_state(&ZX_EXCEPTION_STATE_TRY_NEXT)?;
            continue;
        }

        let syscall_number = report.context.synth_data as u64;
        let mut ctx = SyscallContext { task, registers: thread.read_state_general_regs()? };

        let regs = &ctx.registers;
        let args = (regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9);
        strace!(
            "{}({:#x}, {:#x}, {:#x}, {:#x}, {:#x}, {:#x})",
            SyscallDecl::from_number(syscall_number).name,
            args.0,
            args.1,
            args.2,
            args.3,
            args.4,
            args.5
        );
        match dispatch_syscall(&mut ctx, syscall_number, args) {
            Ok(SyscallResult::Exit(error_code)) => {
                strace!("-> exit {:#x}", error_code);
                // TODO: Set the error_code on the Zircon process object. Currently missing a way
                //       to do this in Zircon. Might be easier in the new execution model.
                if let Some(parent) = task.get_task(task.parent) {
                    // TODO: Clean up the resources associated with the process.
                    let _ = ctx.task.thread_group.process.kill();
                    parent.zombie_tasks.write().push(task_owner);
                }
                return Ok(error_code);
            }
            Ok(SyscallResult::Success(return_value)) => {
                strace!("-> {:#x}", return_value);
                ctx.registers.rax = return_value;
            }
            Ok(SyscallResult::SigReturn) => {
                // Do not modify the register state of the thread. The sigreturn syscall has
                // restored the proper register state for the thread to continue with.
                strace!("-> sigreturn");
            }
            Err(errno) => {
                strace!("!-> {}", errno);
                ctx.registers.rax = (-errno.value()) as u64;
            }
        }

        dequeue_signal(&mut ctx);

        thread.write_state_general_regs(ctx.registers)?;
        exception.set_exception_state(&ZX_EXCEPTION_STATE_HANDLED)?;
    }
}
/// Runs the given task.
///
/// The task is expected to already have been started. This function listens to
/// the exception channel for the process (`exceptions`) and handles each
///  exception by:
///
///   - verifying that the exception represents a `ZX_EXCP_POLICY_CODE_BAD_SYSCALL`
///   - reading the thread's registers
///   - executing the appropriate syscall
///   - setting the thread's registers to their post-syscall values
///   - setting the exception state to `ZX_EXCEPTION_STATE_HANDLED`
///
/// Once this function has completed, the process' exit code (if one is available) can be read from
/// `process_context.exit_code`.
Runs the given task.
The task is expected to already have been started. This function listens to
the exception channel for the process (`exceptions`) and handles each
exception by.

verifying that the exception represents a `ZX_EXCP_POLICY_CODE_BAD_SYSCALL`
reading the thread's registers
executing the appropriate syscall
setting the thread's registers to their post-syscall values
setting the exception state to `ZX_EXCEPTION_STATE_HANDLED`

Once this function has completed, the process' exit code (if one is available) can be read from
`process_context.exit_code`.
Runs the given task . The task is expected to already have been started . This function listens to the exception channel for the process ( ` exceptions ` ) and handles each exception by . verifying that the exception represents a ` ZX_EXCP_POLICY_CODE_BAD_SYSCALL ` reading the thread ' s registers executing the appropriate syscall setting the thread ' s registers to their post - syscall values setting the exception state to ` ZX_EXCEPTION_STATE_HANDLED ` Once this function has completed the process ' exit code ( if one is available ) can be read from ` process_context . exit_code ` .
fn run_task(task_owner: TaskOwner, exceptions: zx::Channel) -> Result<i32, Error> {
    let task = &task_owner.task;
    let mut buffer = zx::MessageBuf::new();
    loop {
        read_channel_sync(&exceptions, &mut buffer)?;
        let info = as_exception_info(&buffer);
        assert!(buffer.n_handles() == 1);
        let exception = zx::Exception::from(buffer.take_handle(0).unwrap());
        if info.type_ != ZX_EXCP_POLICY_ERROR {
            info!("exception type: 0x{:x}", info.type_);
            exception.set_exception_state(&ZX_EXCEPTION_STATE_TRY_NEXT)?;
            continue;
        }
        let thread = exception.get_thread()?;
        assert!(
            thread.get_koid() == task.thread.get_koid(),
            "Exception thread did not match task thread."
        );
        let report = thread.get_exception_report()?;
        if report.context.synth_code != ZX_EXCP_POLICY_CODE_BAD_SYSCALL {
            info!("exception synth_code: {}", report.context.synth_code);
            exception.set_exception_state(&ZX_EXCEPTION_STATE_TRY_NEXT)?;
            continue;
        }
        let syscall_number = report.context.synth_data as u64;
        let mut ctx = SyscallContext { task, registers: thread.read_state_general_regs()? };
        let regs = &ctx.registers;
        let args = (regs.rdi, regs.rsi, regs.rdx, regs.r10, regs.r8, regs.r9);
        strace!(
            "{}({:#x}, {:#x}, {:#x}, {:#x}, {:#x}, {:#x})",
            SyscallDecl::from_number(syscall_number).name,
            args.0,
            args.1,
            args.2,
            args.3,
            args.4,
            args.5
        );
        match dispatch_syscall(&mut ctx, syscall_number, args) {
            Ok(SyscallResult::Exit(error_code)) => {
                strace!("-> exit {:#x}", error_code);
                // TODO: Set the error_code on the Zircon process object. Currently missing a way
                //       to do this in Zircon. Might be easier in the new execution model.
                if let Some(parent) = task.get_task(task.parent) {
                    // TODO: Clean up the resources associated with the process.
                    let _ = ctx.task.thread_group.process.kill();
                    parent.zombie_tasks.write().push(task_owner);
                }
                return Ok(error_code);
            }
            Ok(SyscallResult::Success(return_value)) => {
                strace!("-> {:#x}", return_value);
                ctx.registers.rax = return_value;
            }
            Ok(SyscallResult::SigReturn) => {
                // Do not modify the register state of the thread. The sigreturn syscall has
                // restored the proper register state for the thread to continue with.
                strace!("-> sigreturn");
            }
            Err(errno) => {
                strace!("!-> {}", errno);
                ctx.registers.rax = (-errno.value()) as u64;
            }
        }
        dequeue_signal(&mut ctx);
        thread.write_state_general_regs(ctx.registers)?;
        exception.set_exception_state(&ZX_EXCEPTION_STATE_HANDLED)?;
    }
}
fn run_task ( task_owner : TaskOwner , exceptions : zx :: Channel ) -> Result < i32 , Error > { let task = & task_owner . task ; let mut buffer = zx :: MessageBuf :: new ( ) ; loop { read_channel_sync ( & exceptions , & mut buffer ) ? ; let info = as_exception_info ( & buffer ) ; assert ! ( buffer n_handles ( ) 1 ) ; let exception = zx :: Exception :: from ( buffer . take_handle ( 0 ) . unwrap ( ) ) ; if info . type_ != ZX_EXCP_POLICY_ERROR { info ! ( " " info type_ ) ; exception . set_exception_state ( & ZX_EXCEPTION_STATE_TRY_NEXT ) ? ; continue ; } let thread = exception . get_thread ( ) ? ; assert ! ( thread get_koid ( ) task thread get_koid ( ) " " ) ; let report = thread . get_exception_report ( ) ? ; if report . context . synth_code != ZX_EXCP_POLICY_CODE_BAD_SYSCALL { info ! ( " " report context synth_code ) ; exception . set_exception_state ( & ZX_EXCEPTION_STATE_TRY_NEXT ) ? ; continue ; } let syscall_number = report . context . synth_data as u64 ; let mut ctx = SyscallContext { task , registers : thread . read_state_general_regs ( ) ? } ; let regs = & ctx . registers ; let args = ( regs . rdi , regs . rsi , regs . rdx , regs . r10 , regs . r8 , regs . r9 ) ; strace ! ( " " SyscallDecl from_number ( syscall_number ) name args 0 args 1 args 2 args 3 args 4 args 5 ) ; match dispatch_syscall ( & mut ctx , syscall_number , args ) { Ok ( SyscallResult :: Exit ( error_code ) ) => { strace ! ( " " error_code ) ; // TODO: Set the error_code on the Zircon process object. Currently missing a way //       to do this in Zircon. Might be easier in the new execution model. if let Some ( parent ) = task . get_task ( task . parent ) { // TODO: Clean up the resources associated with the process. let _ = ctx . task . thread_group . process . kill ( ) ; parent . zombie_tasks . write ( ) . push ( task_owner ) ; } return Ok ( error_code ) ; } Ok ( SyscallResult :: Success ( return_value ) ) => { strace ! ( " " return_value ) ; ctx . registers . rax = return_value ; } Ok ( SyscallResult :: SigReturn ) => { // Do not modify the register state of the thread. The sigreturn syscall has // restored the proper register state for the thread to continue with. strace ! ( " " ) ; } Err ( errno ) => { strace ! ( " " errno ) ; ctx . registers . rax = ( - errno . value ( ) ) as u64 ; } } dequeue_signal ( & mut ctx ) ; thread . write_state_general_regs ( ctx . registers ) ? ; exception . set_exception_state ( & ZX_EXCEPTION_STATE_HANDLED ) ? ; } }
Runs the given task.
Runs the given task .
task_owner
TaskOwner
exceptions
zx::Channel
task_owner
TaskOwner
exceptions
zx::Channel