From b0c18d0362803b139be56c2a4abdf6a1185c7141 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 3 Jan 2013 20:45:43 +0100 Subject: [PATCH] Test case for failure detection detection --- base/src/test/segfault/main.cc | 15 ++++ base/src/test/segfault/target.mk | 3 + os/run/failsafe.run | 54 ++++++++++++ os/src/test/failsafe/main.cc | 143 +++++++++++++++++++++++++++++++ os/src/test/failsafe/target.mk | 3 + 5 files changed, 218 insertions(+) create mode 100644 base/src/test/segfault/main.cc create mode 100644 base/src/test/segfault/target.mk create mode 100644 os/run/failsafe.run create mode 100644 os/src/test/failsafe/main.cc create mode 100644 os/src/test/failsafe/target.mk diff --git a/base/src/test/segfault/main.cc b/base/src/test/segfault/main.cc new file mode 100644 index 0000000000..311be3bb7a --- /dev/null +++ b/base/src/test/segfault/main.cc @@ -0,0 +1,15 @@ +/* + * \brief Trigger segmentation fault + * \author Norman Feske + * \date 2012-11-01 + */ + +#include + +int main(int argc, char **argv) +{ + Genode::printf("going to produce a segmentation fault...\n"); + + *((int *)0x44) = 0x55; + return 0; +} diff --git a/base/src/test/segfault/target.mk b/base/src/test/segfault/target.mk new file mode 100644 index 0000000000..9294fe3e9c --- /dev/null +++ b/base/src/test/segfault/target.mk @@ -0,0 +1,3 @@ +TARGET = test-segfault +SRC_CC = main.cc +LIBS = cxx env diff --git a/os/run/failsafe.run b/os/run/failsafe.run new file mode 100644 index 0000000000..d46f3a5abb --- /dev/null +++ b/os/run/failsafe.run @@ -0,0 +1,54 @@ +# +# \brief Test reflection of segmentation faults to the user land +# \author Norman Feske +# \date 2012-11-01 +# + +# +# Build +# + +build { core init test/failsafe test/segfault } + +create_boot_directory + +# +# Generate config +# + +install_config { + + + + + + + + + + + + + + + + + + +} + +# +# Boot modules +# + +# generic modules +set boot_modules { core init test-failsafe test-segfault } + +build_boot_image $boot_modules + +# +# Execute test case +# + +run_genode_until "--- finished failsafe test ---.*\n" 10 + diff --git a/os/src/test/failsafe/main.cc b/os/src/test/failsafe/main.cc new file mode 100644 index 0000000000..b82323912b --- /dev/null +++ b/os/src/test/failsafe/main.cc @@ -0,0 +1,143 @@ +/* + * \brief Test program for failsafe monitoring + * \author Norman Feske + * \date 2013-01-03 + */ + +/* + * Copyright (C) 2008-2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +class Test_child : public Genode::Child_policy +{ + private: + + struct Resources + { + Genode::Ram_connection ram; + Genode::Cpu_connection cpu; + Genode::Rm_connection rm; + + Resources(Genode::Signal_context_capability sigh) + { + using namespace Genode; + + /* transfer some of our own ram quota to the new child */ + enum { CHILD_QUOTA = 1*1024*1024 }; + ram.ref_account(env()->ram_session_cap()); + env()->ram_session()->transfer_quota(ram.cap(), CHILD_QUOTA); + + /* + * Register default exception handler by specifying an invalid + * thread capability. + */ + cpu.exception_handler(Thread_capability(), sigh); + } + } _resources; + + Genode::Rom_connection _elf; + + Genode::Child _child; + + Genode::Parent_service _log_service; + + public: + + /** + * Constructor + */ + Test_child(Genode::Rpc_entrypoint &ep, + char const *elf_name, + Genode::Signal_context_capability sigh) + : + _resources(sigh), + _elf(elf_name), + _child(_elf.dataspace(), _resources.ram.cap(), + _resources.cpu.cap(), _resources.rm.cap(), &ep, this), + _log_service("LOG") + { } + + + /**************************** + ** Child-policy interface ** + ****************************/ + + const char *name() const { return "child"; } + + Genode::Service *resolve_session_request(const char *service, const char *) + { + /* forward log-session request to our parent */ + return !Genode::strcmp(service, "LOG") ? &_log_service : 0; + } + + void filter_session_args(const char *service, + char *args, Genode::size_t args_len) + { + /* define session label for sessions forwarded to our parent */ + Genode::Arg_string::set_arg(args, args_len, "label", "child"); + } +}; + + +int main(int argc, char **argv) +{ + using namespace Genode; + + printf("--- failsafe test started ---\n"); + + /* + * Entry point used for serving the parent interface + */ + enum { STACK_SIZE = 8*1024 }; + Cap_connection cap; + Rpc_entrypoint ep(&cap, STACK_SIZE, "child"); + + /* + * Signal receiver of CPU-session exception signals + */ + static Signal_receiver sig_rec; + + for (int i = 0; i < 5; i++) { + + PLOG("create child %d", i); + + Signal_context sig_ctx; + Signal_context_capability exception_sigh = sig_rec.manage(&sig_ctx); + + Test_child child(ep, "test-segfault", exception_sigh); + + Signal s = sig_rec.wait_for_signal(); + + if (s.num() && s.context() == &sig_ctx) { + PLOG("got exception for child %d", i); + } else { + PERR("got unexpected signal while waiting for child %d", i); + return -2; + } + + sig_rec.dissolve(&sig_ctx); + + /* + * When finishing the loop iteration, the local variables including + * 'child' will get destructed. A new child will be created at the + * beginning of the next iteration. + */ + } + + printf("--- finished failsafe test ---\n"); + return 0; +} + diff --git a/os/src/test/failsafe/target.mk b/os/src/test/failsafe/target.mk new file mode 100644 index 0000000000..b708aa84c5 --- /dev/null +++ b/os/src/test/failsafe/target.mk @@ -0,0 +1,3 @@ +TARGET = test-failsafe +SRC_CC = main.cc +LIBS = cxx env server signal child