From c5a39e09024abc21ef89e61209a5e341a56518d0 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Thu, 25 Apr 2019 18:30:49 +0200 Subject: [PATCH] Add a stack overflow integration test --- tests/stack_overflow.rs | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 tests/stack_overflow.rs diff --git a/tests/stack_overflow.rs b/tests/stack_overflow.rs new file mode 100644 index 00000000..14ad16a6 --- /dev/null +++ b/tests/stack_overflow.rs @@ -0,0 +1,64 @@ +#![no_std] +#![no_main] +#![feature(abi_x86_interrupt)] + +use blog_os::{exit_qemu, serial_print, serial_println, QemuExitCode}; +use core::panic::PanicInfo; +use lazy_static::lazy_static; + +#[no_mangle] +pub extern "C" fn _start() -> ! { + serial_print!("stack_overflow... "); + + blog_os::gdt::init(); + init_test_idt(); + + // trigger a stack overflow + stack_overflow(); + + serial_println!("[failed]"); + serial_println!("Execution continued after stack overflow"); + exit_qemu(QemuExitCode::Failed); + loop {} +} + +#[allow(unconditional_recursion)] +fn stack_overflow() { + stack_overflow(); // for each recursion, the return address is pushed +} + +#[panic_handler] +fn panic(info: &PanicInfo) -> ! { + serial_println!("[failed]"); + serial_println!("{}", info); + exit_qemu(QemuExitCode::Failed); + loop {} +} + +use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; + +lazy_static! { + static ref TEST_IDT: InterruptDescriptorTable = { + let mut idt = InterruptDescriptorTable::new(); + unsafe { + idt.double_fault + .set_handler_fn(double_fault_handler) + .set_stack_index(blog_os::gdt::DOUBLE_FAULT_IST_INDEX); + } + + idt + }; +} + +pub fn init_test_idt() { + TEST_IDT.load(); +} + +extern "x86-interrupt" fn double_fault_handler( + _stack_frame: &mut InterruptStackFrame, + _error_code: u64, +) { + serial_println!("[ok]"); + exit_qemu(QemuExitCode::Success); + loop {} +}