From 0de54cddaa3c5629ac1dc7613b60103b9decd7cc Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Fri, 15 May 2020 15:13:19 +0200 Subject: [PATCH] gdb_monitor: hide exceptions during create_thread This patch is a workaround for the missing implementation of 'Pd_session::transfer_quota' interface by the GDB monitor's PD service. The missing implementation becomes problematic with the changes of #3750 that enabled the cap-quota accounting for core's CPU service. In regular scenarios without the GDB monitor, the client of 'Cpu_session::create_thread' deals with Out_of_caps or Out_of_ram by upgrading the CPU session's cap and RAM quotas. This, in turn, results in a sequence of 'transfer_quota' operations at the parent. Since GDB monitor implements a custom PD service, these 'transfer_quota' calls try to transfer quota between sessions provided by core and those provided by the GDB monitor. This does of course not work. To fix this issue, the GDB monitor needs a major overhaul. This patch side-steps the problem by handing Out_of_caps and Out_of_ram from the debuging target. --- repos/ports/run/gdb_monitor.run | 2 +- .../app/gdb_monitor/cpu_session_component.cc | 2 +- .../app/gdb_monitor/cpu_session_component.h | 31 ++++++++++++++++++- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/repos/ports/run/gdb_monitor.run b/repos/ports/run/gdb_monitor.run index 002c796d2..bb0d6b28a 100644 --- a/repos/ports/run/gdb_monitor.run +++ b/repos/ports/run/gdb_monitor.run @@ -119,7 +119,7 @@ append qemu_args " -serial stdio " append qemu_args " -serial chardev:uart " append qemu_args " -chardev socket,id=uart,port=$local_port,host=localhost,server,nowait,ipv4 " -run_genode_until {.*\[init -> gdb_monitor\].*} 30 +run_genode_until {.*\[init -> gdb_monitor\] Remote debugging using /dev/terminal.*} 30 set genode_id [output_spawn_id] puts "GDB monitor is up, starting GDB" diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc index a228d582b..22e8fa18d 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc @@ -320,7 +320,7 @@ Cpu_session_component::Cpu_session_component(Env &env, _ep(ep), _md_alloc(md_alloc), _core_pd(core_pd), - _parent_cpu_session(env.session(_id_space_element.id(), args, affinity)), + _parent_cpu_session(env.session(_id_space_element.id(), args, affinity), *this), _signal_ep(signal_ep), _new_thread_pipe_write_end(new_thread_pipe_write_end), _breakpoint_len(breakpoint_len), diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.h b/repos/ports/src/app/gdb_monitor/cpu_session_component.h index 39b144961..31d846f5a 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.h +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,35 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object Pd_session_capability _core_pd; - Cpu_session_client _parent_cpu_session; + struct Expanding_parent_cpu_session : Cpu_session_client + { + Cpu_session_component &_component; + + Expanding_parent_cpu_session(Cpu_session_capability cap, + Cpu_session_component &component) + : + Cpu_session_client(cap), _component(component) { } + + Thread_capability create_thread(Capability pd, + Cpu_session::Name const &name, + Affinity::Location affinity, + Weight weight, + addr_t utcb) override + { + enum { UPGRADE_ATTEMPTS = ~0U }; + return Genode::retry( + [&] () { + return Genode::retry( + [&] () { return Cpu_session_client::create_thread(pd, name, affinity, weight, utcb); }, + [&] () { _component._env.upgrade(_component._id_space_element.id(), "cap_quota=3"); }, + UPGRADE_ATTEMPTS); + }, + [&] () { _component._env.upgrade(_component._id_space_element.id(), "ram_quota=8K"); }, + UPGRADE_ATTEMPTS); + } + }; + + Expanding_parent_cpu_session _parent_cpu_session; Entrypoint &_signal_ep; int const _new_thread_pipe_write_end;