Exception handling: Implemented RPC exception.

core0-buffer
pca006132 2020-07-06 15:34:49 +08:00
parent 1d975dd8bf
commit c59772dca3
3 changed files with 50 additions and 10 deletions

View File

@ -1,20 +1,38 @@
from artiq.experiment import *
from artiq.language.core import TerminationRequested
class ExceptionDemo(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("led0")
def foo(self):
print("raise error")
raise Exception
def termination(self):
raise TerminationRequested
@rpc
def remote(self):
raise Exception
@kernel
def run(self):
self.core.reset()
print("OK!")
try:
try:
raise Exception
self.foo()
except ValueError as e:
print("re-raise")
raise e
print("should not trigger this")
except:
print("error")
print("catch all")
try:
self.remote()
except:
print("Error!")
print("Uncaught error at last")
self.termination()

View File

@ -171,7 +171,9 @@ async fn handle_run_kernel(stream: &TcpStream, control: &Rc<RefCell<kernel::Cont
let line = read_i32(stream).await?;
let column = read_i32(stream).await?;
let function = read_string(stream, 16384).await?;
control.tx.async_send(kernel::Message::RpcRecvReply(Err(()))).await;
control.tx.async_send(kernel::Message::RpcRecvReply(Err(kernel::RPCException {
name, message, param, file, line, column, function
}))).await;
},
_ => {
error!("unexpected RPC request from host: {:?}", host_request);

View File

@ -1,7 +1,7 @@
use core::{ptr, mem};
use log::{debug, info, error};
use alloc::{vec::Vec, sync::Arc};
use cslice::CSlice;
use alloc::{vec::Vec, sync::Arc, string::String};
use cslice::{CSlice, AsCSlice};
use libcortex_a9::{enable_fpu, cache::dcci_slice, mutex::Mutex, sync_channel::{self, sync_channel}};
use libsupport_zynq::boot::Core1;
@ -11,6 +11,16 @@ use crate::eh_artiq;
use crate::rpc;
use crate::rtio;
#[derive(Debug)]
pub struct RPCException {
pub name: String,
pub message: String,
pub param: [i64; 3],
pub file: String,
pub line: i32,
pub column: i32,
pub function: String
}
#[derive(Debug)]
pub enum Message {
@ -22,7 +32,7 @@ pub enum Message {
KernelException(&'static eh_artiq::Exception<'static>, &'static [usize]),
RpcSend { is_async: bool, data: Arc<Vec<u8>> },
RpcRecvRequest(*mut ()),
RpcRecvReply(Result<usize, ()>),
RpcRecvReply(Result<usize, RPCException>),
}
static CHANNEL_0TO1: Mutex<Option<sync_channel::Receiver<Message>>> = Mutex::new(None);
@ -150,7 +160,17 @@ extern fn rpc_recv(slot: *mut ()) -> usize {
let reply = core1_rx.recv();
match *reply {
Message::RpcRecvReply(Ok(alloc_size)) => alloc_size,
Message::RpcRecvReply(Err(_)) => unimplemented!(),
Message::RpcRecvReply(Err(exception)) => unsafe {
eh_artiq::raise(&eh_artiq::Exception {
name: exception.name.as_bytes().as_c_slice(),
file: exception.file.as_bytes().as_c_slice(),
line: exception.line as u32,
column: exception.column as u32,
function: exception.function.as_bytes().as_c_slice(),
message: exception.message.as_bytes().as_c_slice(),
param: exception.param
})
},
_ => panic!("received unexpected reply to RpcRecvRequest: {:?}", reply)
}
}