From e5d6c06f58725506fe4a9a418d916eb65d7b9b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Mon, 30 Jan 2017 11:07:48 +0100 Subject: [PATCH] Rework trace test and add to autopilot Issue #2260 --- repos/os/run/trace.run | 8 +- repos/os/src/test/trace/main.cc | 211 ++++++++++++++++++-------------- tool/autopilot.list | 1 + 3 files changed, 122 insertions(+), 98 deletions(-) diff --git a/repos/os/run/trace.run b/repos/os/run/trace.run index 1d4faae80..f3ccb1556 100644 --- a/repos/os/run/trace.run +++ b/repos/os/run/trace.run @@ -6,7 +6,7 @@ set build_components { core init drivers/timer test/trace - lib/trace/policy/rpc_name + lib/trace/policy/null } build $build_components @@ -41,7 +41,7 @@ append config { - + } @@ -57,11 +57,11 @@ set boot_modules { core ld.lib.so init timer test-trace - rpc_name + null } build_boot_image $boot_modules append qemu_args " -nographic -serial mon:stdio -m 256 " -run_genode_until "--- test-trace finished ---" 30 +run_genode_until {.*child "test-trace" exited with exit value 0.*} 30 diff --git a/repos/os/src/test/trace/main.cc b/repos/os/src/test/trace/main.cc index 7cdaf27ef..fae4ecc2b 100644 --- a/repos/os/src/test/trace/main.cc +++ b/repos/os/src/test/trace/main.cc @@ -73,13 +73,14 @@ class Trace_buffer_monitor _rm(rm), _id(id), _buffer(rm.attach(ds_cap)), _curr_entry(_buffer->first()) { - log("monitor subject:", _id.id, " buffer:", Hex((addr_t)_buffer)); + log("monitor " + "subject:", _id.id, " " + "buffer:", Hex((addr_t)_buffer)); } ~Trace_buffer_monitor() { - if (_buffer) - _rm.detach(_buffer); + if (_buffer) { _rm.detach(_buffer); } } Trace::Subject_id id() { return _id; }; @@ -88,15 +89,16 @@ class Trace_buffer_monitor { log("overflows: ", _buffer->wrapped()); log("read all remaining events"); + for (; !_curr_entry.last(); _curr_entry = _buffer->next(_curr_entry)) { /* omit empty entries */ if (_curr_entry.length() == 0) continue; - const char *data = _terminate_entry(_curr_entry); - if (data) - log(data); + char const * const data = _terminate_entry(_curr_entry); + if (data) { log(data); } } + /* reset after we read all available entries */ _curr_entry = _buffer->first(); } @@ -130,6 +132,7 @@ struct Test_out_of_metadata /* we should never arrive here */ struct Unexpectedly_got_no_exception{}; throw Unexpectedly_got_no_exception(); + } catch (Parent::Service_denied) { log("got Parent::Service_denied exception as expected"); } @@ -152,18 +155,19 @@ struct Test_out_of_metadata struct Test_tracing { - Env &env; - Attached_rom_dataspace config { env, "config" }; - Heap heap { env.ram(), env.rm() }; - Trace::Connection trace { env, 1024*1024, 64*1024, 0 }; - Timer::Connection timer { env }; - Test_thread::Name thread_name { "test-thread" }; - Test_thread thread { env, thread_name }; - Trace_buffer_monitor *test_monitor { nullptr }; - bool policy_set { false }; - Trace::Policy_id policy_id; - char policy_label[64]; - char policy_module[64]; + Env &env; + Attached_rom_dataspace config { env, "config" }; + Trace::Connection trace { env, 1024*1024, 64*1024, 0 }; + Timer::Connection timer { env }; + Test_thread::Name thread_name { "test-thread" }; + Test_thread thread { env, thread_name }; + Trace::Policy_id policy_id; + + Constructible test_monitor; + + typedef Genode::String<64> String; + String policy_label; + String policy_module; Rom_dataspace_capability policy_module_rom_ds; char const *state_name(Trace::Subject_info::State state) @@ -179,96 +183,115 @@ struct Test_tracing return "undefined"; } + template + void for_each_subject(Trace::Subject_id subjects[], + size_t max_subjects, FUNC const &func) + { + for (size_t i = 0; i < max_subjects; i++) { + Trace::Subject_info info = trace.subject_info(subjects[i]); + func(subjects[i].id, info); + } + } + + struct Failed : Genode::Exception { }; + Test_tracing(Env &env) : env(env) { + log("test Tracing"); + try { Xml_node policy = config.xml().sub_node("trace_policy"); - for (;; policy = policy.next("trace_policy")) { - try { - policy.attribute("label").value(policy_label, sizeof (policy_label)); - policy.attribute("module").value(policy_module, sizeof (policy_module)); + policy.attribute("label").value(&policy_label); + policy.attribute("module").value(&policy_module); - Rom_connection policy_rom(env, policy_module); - policy_module_rom_ds = policy_rom.dataspace(); + Rom_connection policy_rom(env, policy_module.string()); + policy_module_rom_ds = policy_rom.dataspace(); - size_t rom_size = Dataspace_client(policy_module_rom_ds).size(); + size_t rom_size = Dataspace_client(policy_module_rom_ds).size(); - policy_id = trace.alloc_policy(rom_size); - Dataspace_capability ds_cap = trace.policy(policy_id); + policy_id = trace.alloc_policy(rom_size); + Dataspace_capability ds_cap = trace.policy(policy_id); - if (ds_cap.valid()) { - void *ram = env.rm().attach(ds_cap); - void *rom = env.rm().attach(policy_module_rom_ds); - memcpy(ram, rom, rom_size); + if (ds_cap.valid()) { + void *ram = env.rm().attach(ds_cap); + void *rom = env.rm().attach(policy_module_rom_ds); + memcpy(ram, rom, rom_size); - env.rm().detach(ram); - env.rm().detach(rom); - } - } catch (...) { - error("could not load module '", Cstring(policy_module), "' for " - "label '", Cstring(policy_label), "'"); - } - - log("load module: '", Cstring(policy_module), "' for " - "label: '", Cstring(policy_label), "'"); - - if (policy.last("trace_policy")) break; + env.rm().detach(ram); + env.rm().detach(rom); } - } catch (...) { } - - for (size_t cnt = 0; cnt < 5; cnt++) { - - timer.msleep(3000); - - Trace::Subject_id subjects[32]; - size_t num_subjects = trace.subjects(subjects, 32); - - log(num_subjects, " tracing subjects present"); - - for (size_t i = 0; i < num_subjects; i++) { - - Trace::Subject_info info = trace.subject_info(subjects[i]); - log("ID:", subjects[i].id, " " - "label:\"", info.session_label(), "\" " - "name:\"", info.thread_name(), "\" " - "state:", state_name(info.state()), " " - "policy:", info.policy_id().id, " " - "time:", info.execution_time().value); - - /* enable tracing */ - if (!policy_set - && strcmp(info.session_label().string(), policy_label) == 0 - && strcmp(info.thread_name().string(), "test-thread") == 0) { - try { - log("enable tracing for " - "thread:'", info.thread_name().string(), "' with " - "policy:", policy_id.id); - - trace.trace(subjects[i].id, policy_id, 16384U); - - Dataspace_capability ds_cap = trace.buffer(subjects[i].id); - test_monitor = new (heap) - Trace_buffer_monitor(env.rm(), subjects[i].id, ds_cap); - - } catch (Trace::Source_is_dead) { error("source is dead"); } - - policy_set = true; - } - - /* read events from trace buffer */ - if (test_monitor) { - if (subjects[i].id == test_monitor->id().id) - test_monitor->dump(); - } - } + log("load module: '", policy_module, "' for " + "label: '", policy_label, "'"); + } catch (...) { + error("could not load module '", policy_module, "' for " + "label '", policy_label, "'"); + throw Failed(); } - if (test_monitor) - destroy(heap, test_monitor); + /* wait some time before querying the subjects */ + timer.msleep(3000); + + Trace::Subject_id subjects[32]; + size_t num_subjects = trace.subjects(subjects, 32); + + log(num_subjects, " tracing subjects present"); + + auto print_info = [this] (Trace::Subject_id id, Trace::Subject_info info) { + + log("ID:", id.id, " " + "label:\"", info.session_label(), "\" " + "name:\"", info.thread_name(), "\" " + "state:", state_name(info.state()), " " + "policy:", info.policy_id().id, " " + "time:", info.execution_time().value); + }; + + for_each_subject(subjects, num_subjects, print_info); + + /* enable tracing for test-thread */ + auto enable_tracing = [this, &env] (Trace::Subject_id id, + Trace::Subject_info info) { + + if ( info.session_label() != policy_label + || info.thread_name() != "test-thread") { + return; + } + + try { + log("enable tracing for " + "thread:'", info.thread_name().string(), "' with " + "policy:", policy_id.id); + + trace.trace(id.id, policy_id, 16384U); + + Dataspace_capability ds_cap = trace.buffer(id.id); + test_monitor.construct(env.rm(), id.id, ds_cap); + + } catch (Trace::Source_is_dead) { + error("source is dead"); + throw Failed(); + } + }; + + for_each_subject(subjects, num_subjects, enable_tracing); + + /* give the test thread some time to run */ + timer.msleep(3000); + + for_each_subject(subjects, num_subjects, print_info); + + /* read events from trace buffer */ + if (test_monitor.constructed()) { + test_monitor->dump(); + test_monitor.destruct(); + } + + log("passed Tracing test"); } }; + struct Main { Constructible test_1; @@ -276,12 +299,12 @@ struct Main Main(Env &env) { - log("--- test-trace started ---"); test_1.construct(env); test_1.destruct(); test_2.construct(env); test_2.destruct(); - log("--- test-trace finished ---"); + + env.parent().exit(0); } }; diff --git a/tool/autopilot.list b/tool/autopilot.list index 7b36b344b..abef880e1 100644 --- a/tool/autopilot.list +++ b/tool/autopilot.list @@ -84,3 +84,4 @@ rom_blk reconstructible synced_interface timer_accuracy +trace