blob: 963cd46be64c04ea50057adc8d24366137ff529e [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License..
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use std::backtrace::{self, PrintFormat};
use std::panic;
use sgx_signal::ContinueType;
use sgx_signal::exception::{register_exception, unregister};
use sgx_types::sgx_exception_info_t;
use sgx_trts::enclave;
#[no_mangle]
#[inline(never)]
fn test_abort() -> ! {
let td = enclave::SgxThreadData::current();
println!("test_abort stack: {:x}-{:x}", td.stack_base(), td.stack_limit());
std::intrinsics::abort()
}
#[cfg_attr(not(feature = "hw_test"), allow(unreachable_code))]
pub fn test_exception_handler() {
#[cfg(not(feature = "hw_test"))]
return;
let _ = backtrace::enable_backtrace("enclave.signed.so", PrintFormat::Full);
let status = Arc::new(AtomicUsize::new(2));
let handler1 = {
let status = Arc::clone(&status);
move |_info: &mut sgx_exception_info_t| {
status.fetch_add(2, Ordering::Relaxed);
ContinueType::Search
}
};
let handler2 = {
let status = Arc::clone(&status);
move |_info: &mut sgx_exception_info_t| {
status.store(1, Ordering::Relaxed);
ContinueType::Search
}
};
let r1 = register_exception(false, handler1);
let r2 = register_exception(true, handler2);
panic::catch_unwind(||{
test_abort()
}).ok();
for _ in 0..10 {
thread::sleep(Duration::from_millis(100));
let current = status.load(Ordering::Relaxed);
match current {
// Not yet
0 => continue,
// Good, we are done with the correct result
_ if current == 3 => return,
_ => panic!("Wrong result value {}", current),
}
}
unregister(r1.unwrap());
unregister(r2.unwrap());
panic!("Timed out waiting for the exception");
}