mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-15 23:17:14 +00:00
parent
5f1f67153b
commit
486e534df0
@ -230,13 +230,13 @@ puts "\n"
|
||||
puts "----- test: thread info -----"
|
||||
puts ""
|
||||
|
||||
send "b Test_thread::entry()\n"
|
||||
send "b test_thread_start\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
send "c\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
if {![regexp {Breakpoint 4, Test_thread::entry()} $output]} {
|
||||
if {![regexp {Breakpoint 4, test_thread_start} $output]} {
|
||||
puts stderr "*** Error: Breakpoint in test thread did not trigger"
|
||||
exit -1
|
||||
}
|
||||
@ -245,7 +245,7 @@ send "info threads\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
if {![regexp { 4 Thread 3} $output] ||
|
||||
![regexp {\* 3 Thread 4 Test_thread::entry} $output] ||
|
||||
![regexp {\* 3 Thread 4 test_thread_start} $output] ||
|
||||
![regexp { 2 Thread 2} $output] ||
|
||||
![regexp { 1 Thread 1} $output]} {
|
||||
puts stderr "*** Error: Thread info is not as expected"
|
||||
@ -262,7 +262,7 @@ run_genode_until {\(gdb\)} 30 $gdb_id
|
||||
send "thread 2\n"
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
if {![regexp {Test_thread::step_func} $output]} {
|
||||
if {![regexp {test_thread_step} $output]} {
|
||||
puts stderr "*** Error: Step into function didn't result in the expected output"
|
||||
exit -1
|
||||
}
|
||||
@ -293,8 +293,9 @@ if {![have_spec arm]} {
|
||||
run_genode_until {\(gdb\)} 20 $gdb_id
|
||||
|
||||
if {![regexp {Genode::Cancelable_lock::lock\(\)} $output] ||
|
||||
![regexp {Genode::Thread::join\(\)} $output] ||
|
||||
![regexp {in main \(\)} $output]} {
|
||||
![regexp {Genode::Signal_receiver::block_for_signal\(\)} $output] ||
|
||||
![regexp {Genode::Entrypoint::_wait_and_dispatch_one_io_signal\(bool\)} $output] ||
|
||||
![regexp {Libc::Kernel::run\(Libc::Application_code&\)} $output] } {
|
||||
|
||||
puts stderr "*** Error: Stack trace when in syscall is not as expected"
|
||||
exit -1
|
||||
|
@ -40,8 +40,8 @@ namespace Gdb_monitor {
|
||||
class Gdb_monitor::App_child : public Child_policy,
|
||||
public Async_service::Wakeup,
|
||||
public Init::Report_update_trigger,
|
||||
public Init::Routed_service::Ram_accessor,
|
||||
public Init::Routed_service::Pd_accessor
|
||||
public Init::Routed_service::Pd_accessor,
|
||||
public Init::Routed_service::Ram_accessor
|
||||
{
|
||||
private:
|
||||
|
||||
@ -62,27 +62,28 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
|
||||
Local_env(Env &genode_env) : genode_env(genode_env) { }
|
||||
|
||||
Parent &parent() { return genode_env.parent(); }
|
||||
Ram_session &ram() { return genode_env.ram(); }
|
||||
Cpu_session &cpu() { return genode_env.cpu(); }
|
||||
Region_map &rm() { return genode_env.rm(); }
|
||||
Pd_session &pd() { return genode_env.pd(); }
|
||||
Entrypoint &ep() { return local_ep; }
|
||||
Ram_session_capability ram_session_cap() { return genode_env.ram_session_cap(); }
|
||||
Cpu_session_capability cpu_session_cap() { return genode_env.cpu_session_cap(); }
|
||||
Pd_session_capability pd_session_cap() { return genode_env.pd_session_cap(); }
|
||||
Id_space<Parent::Client> &id_space() { return genode_env.id_space(); }
|
||||
Parent &parent() override { return genode_env.parent(); }
|
||||
Cpu_session &cpu() override { return genode_env.cpu(); }
|
||||
Region_map &rm() override { return genode_env.rm(); }
|
||||
Pd_session &pd() override { return genode_env.pd(); }
|
||||
Entrypoint &ep() override { return local_ep; }
|
||||
Cpu_session_capability cpu_session_cap() override { return genode_env.cpu_session_cap(); }
|
||||
Pd_session_capability pd_session_cap() override { return genode_env.pd_session_cap(); }
|
||||
Id_space<Parent::Client> &id_space() override { return genode_env.id_space(); }
|
||||
|
||||
Pd_session_capability ram_session_cap() { return pd_session_cap(); }
|
||||
Pd_session &ram() { return pd(); }
|
||||
|
||||
Session_capability session(Parent::Service_name const &service_name,
|
||||
Parent::Client::Id id,
|
||||
Parent::Session_args const &session_args,
|
||||
Affinity const &affinity)
|
||||
Affinity const &affinity) override
|
||||
{ return genode_env.session(service_name, id, session_args, affinity); }
|
||||
|
||||
void upgrade(Parent::Client::Id id, Parent::Upgrade_args const &args)
|
||||
void upgrade(Parent::Client::Id id, Parent::Upgrade_args const &args) override
|
||||
{ return genode_env.upgrade(id, args); }
|
||||
|
||||
void close(Parent::Client::Id id) { return genode_env.close(id); }
|
||||
void close(Parent::Client::Id id) override { return genode_env.close(id); }
|
||||
|
||||
void exec_static_constructors() override { }
|
||||
|
||||
@ -120,7 +121,7 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
|
||||
Genode_child_resources _genode_child_resources;
|
||||
|
||||
Signal_dispatcher<App_child> _unresolved_page_fault_dispatcher;
|
||||
Signal_handler<App_child> _unresolved_page_fault_handler;
|
||||
|
||||
Dataspace_pool _managed_ds_map;
|
||||
|
||||
@ -147,7 +148,7 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
|
||||
Child *_child;
|
||||
|
||||
void _dispatch_unresolved_page_fault(unsigned)
|
||||
void _handle_unresolved_page_fault()
|
||||
{
|
||||
_genode_child_resources.cpu_session_component().handle_unresolved_page_fault();
|
||||
}
|
||||
@ -177,30 +178,63 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
void trigger_report_update() override { }
|
||||
void trigger_immediate_report_update() override { }
|
||||
|
||||
/**
|
||||
* Init::Routed_service::Ram_accessor interface
|
||||
*/
|
||||
Ram_session &ram() override { return _child->ram(); }
|
||||
Ram_session_capability ram_cap() const override { return _child->ram_session_cap(); }
|
||||
|
||||
/**
|
||||
* Init::Routed_service::Pd_accessor interface
|
||||
*/
|
||||
Pd_session &pd() override { return _child->pd(); }
|
||||
Pd_session_capability pd_cap() const override { return _child->pd_session_cap(); }
|
||||
|
||||
/**
|
||||
* Init::Routed_service::Ram_accessor interface
|
||||
*/
|
||||
Pd_session &ram() override { return _child->pd(); }
|
||||
Pd_session_capability ram_cap() const override { return _child->pd_session_cap(); }
|
||||
|
||||
Service &_matching_service(Service::Name const &service_name,
|
||||
Session_label const &label)
|
||||
{
|
||||
Service *service = nullptr;
|
||||
|
||||
/* check for config file request */
|
||||
if ((service = _config_policy.resolve_session_request_with_label(service_name, label)))
|
||||
return *service;
|
||||
|
||||
/* check for "session_requests" ROM request */
|
||||
if ((service_name == Genode::Rom_session::service_name()) &&
|
||||
(label.last_element() == Genode::Session_requester::rom_name()))
|
||||
return _session_requester.service();
|
||||
|
||||
if (service_name == "CPU")
|
||||
return _cpu_service;
|
||||
|
||||
if (service_name == "PD")
|
||||
return _pd_service;
|
||||
|
||||
if (service_name == "ROM")
|
||||
return _rom_service;
|
||||
|
||||
service = _find_service(_parent_services, service_name);
|
||||
if (!service)
|
||||
service = new (_alloc) Parent_service(_parent_services, _env, service_name);
|
||||
|
||||
if (!service)
|
||||
throw Service_denied();
|
||||
|
||||
return *service;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
App_child(Env &env,
|
||||
Allocator &alloc,
|
||||
char const *unique_name,
|
||||
Ram_quota ram_quota,
|
||||
Cap_quota cap_quota,
|
||||
Signal_receiver &signal_receiver,
|
||||
Xml_node target_node)
|
||||
App_child(Env &env,
|
||||
Allocator &alloc,
|
||||
char const *unique_name,
|
||||
Ram_quota ram_quota,
|
||||
Cap_quota cap_quota,
|
||||
Entrypoint &signal_ep,
|
||||
Xml_node target_node)
|
||||
:
|
||||
_env(env),
|
||||
_alloc(alloc),
|
||||
@ -209,15 +243,14 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
_ram_quota(ram_quota), _cap_quota(cap_quota),
|
||||
_child_config(_env.ram(), _rm, target_node),
|
||||
_config_policy("config", _child_config.dataspace(), &_env.ep().rpc_ep()),
|
||||
_unresolved_page_fault_dispatcher(signal_receiver,
|
||||
*this,
|
||||
&App_child::_dispatch_unresolved_page_fault),
|
||||
_unresolved_page_fault_handler(signal_ep, *this,
|
||||
&App_child::_handle_unresolved_page_fault),
|
||||
_cpu_factory(_env, _env.ep().rpc_ep(), _alloc, _pd.core_pd_cap(),
|
||||
signal_receiver, &_genode_child_resources),
|
||||
signal_ep, &_genode_child_resources),
|
||||
_rom_factory(_env, _env.ep().rpc_ep(), _alloc)
|
||||
{
|
||||
_genode_child_resources.region_map_component(&_pd.region_map());
|
||||
_pd.region_map().fault_handler(_unresolved_page_fault_dispatcher);
|
||||
_pd.region_map().fault_handler(_unresolved_page_fault_handler);
|
||||
}
|
||||
|
||||
~App_child()
|
||||
@ -267,38 +300,12 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
});
|
||||
}
|
||||
|
||||
Service &resolve_session_request(Service::Name const &service_name,
|
||||
Session_state::Args const &args) override
|
||||
Route resolve_session_request(Service::Name const &service_name,
|
||||
Session_label const &label) override
|
||||
{
|
||||
Service *service = nullptr;
|
||||
|
||||
/* check for config file request */
|
||||
if ((service = _config_policy.resolve_session_request(service_name.string(), args.string())))
|
||||
return *service;
|
||||
|
||||
/* check for "session_requests" ROM request */
|
||||
Genode::Session_label const label(Genode::label_from_args(args.string()));
|
||||
if ((service_name == Genode::Rom_session::service_name()) &&
|
||||
(label.last_element() == Genode::Session_requester::rom_name()))
|
||||
return _session_requester.service();
|
||||
|
||||
if (service_name == "CPU")
|
||||
return _cpu_service;
|
||||
|
||||
if (service_name == "PD")
|
||||
return _pd_service;
|
||||
|
||||
if (service_name == "ROM")
|
||||
return _rom_service;
|
||||
|
||||
service = _find_service(_parent_services, service_name);
|
||||
if (!service)
|
||||
service = new (_alloc) Parent_service(_parent_services, _env, service_name);
|
||||
|
||||
if (!service)
|
||||
throw Service_denied();
|
||||
|
||||
return *service;
|
||||
return Route { .service = _matching_service(service_name, label),
|
||||
.label = label,
|
||||
.diag = Session::Diag() };
|
||||
}
|
||||
|
||||
void announce_service(Service::Name const &service_name) override
|
||||
@ -310,8 +317,7 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
|
||||
new (_alloc) Init::Routed_service(_child_services,
|
||||
"target",
|
||||
*this,
|
||||
*this,
|
||||
*this, *this,
|
||||
_session_requester.id_space(),
|
||||
_child->session_factory(),
|
||||
service_name,
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include <util/xml_node.h>
|
||||
#include <base/attached_dataspace.h>
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <base/ram_allocator.h>
|
||||
|
||||
namespace Init { class Child_config; }
|
||||
|
||||
@ -27,7 +27,7 @@ class Init::Child_config
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Ram_session &_ram;
|
||||
Genode::Ram_allocator &_ram;
|
||||
|
||||
typedef Genode::String<64> Rom_name;
|
||||
Rom_name const _rom_name;
|
||||
@ -51,7 +51,7 @@ class Init::Child_config
|
||||
*/
|
||||
Genode::Ram_dataspace_capability
|
||||
_ram_ds_from_start_node(Genode::Xml_node start,
|
||||
Genode::Ram_session &ram, Genode::Region_map &rm)
|
||||
Genode::Ram_allocator &ram, Genode::Region_map &rm)
|
||||
{
|
||||
/*
|
||||
* If the start node contains a 'config' entry, we copy this entry
|
||||
@ -75,8 +75,8 @@ class Init::Child_config
|
||||
*/
|
||||
Genode::Attached_dataspace attached(rm, ram_ds);
|
||||
|
||||
Genode::memcpy(attached.local_addr<char>(),
|
||||
config.addr(), config.size());
|
||||
config.with_raw_node([&] (char const *start, size_t length) {
|
||||
Genode::memcpy(attached.local_addr<char>(), start, length); });
|
||||
|
||||
attached.local_addr<char>()[config.size()] = 0;
|
||||
|
||||
@ -105,7 +105,7 @@ class Init::Child_config
|
||||
* If the start node contains a 'filename' entry, we only keep the
|
||||
* information about the ROM module name.
|
||||
*/
|
||||
Child_config(Genode::Ram_session &ram, Genode::Region_map &local_rm,
|
||||
Child_config(Genode::Ram_allocator &ram, Genode::Region_map &local_rm,
|
||||
Genode::Xml_node start)
|
||||
:
|
||||
_ram(ram),
|
||||
|
@ -43,9 +43,9 @@ Rpc_entrypoint &Cpu_session_component::thread_ep()
|
||||
}
|
||||
|
||||
|
||||
Signal_receiver &Cpu_session_component::exception_signal_receiver()
|
||||
Entrypoint &Cpu_session_component::signal_ep()
|
||||
{
|
||||
return _exception_signal_receiver;
|
||||
return _signal_ep;
|
||||
}
|
||||
|
||||
|
||||
@ -306,7 +306,7 @@ Cpu_session_component::Cpu_session_component(Env &env,
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator &md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver &exception_signal_receiver,
|
||||
Entrypoint &signal_ep,
|
||||
const char *args,
|
||||
Affinity const &affinity)
|
||||
: _env(env),
|
||||
@ -314,7 +314,7 @@ Cpu_session_component::Cpu_session_component(Env &env,
|
||||
_md_alloc(md_alloc),
|
||||
_core_pd(core_pd),
|
||||
_parent_cpu_session(env.session<Cpu_session>(_id_space_element.id(), args, affinity)),
|
||||
_exception_signal_receiver(exception_signal_receiver),
|
||||
_signal_ep(signal_ep),
|
||||
_native_cpu_cap(_setup_native_cpu())
|
||||
{
|
||||
_ep.manage(this);
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/service.h>
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <cpu_session/client.h>
|
||||
#include <parent/parent.h>
|
||||
#include <pd_session/capability.h>
|
||||
@ -59,7 +58,7 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
Pd_session_capability _core_pd;
|
||||
|
||||
Cpu_session_client _parent_cpu_session;
|
||||
Signal_receiver &_exception_signal_receiver;
|
||||
Entrypoint &_signal_ep;
|
||||
|
||||
Append_list<Cpu_thread_component> _thread_list;
|
||||
|
||||
@ -80,7 +79,7 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator &md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver &exception_signal_receiver,
|
||||
Entrypoint &signal_ep,
|
||||
const char *args,
|
||||
Affinity const &affinity);
|
||||
|
||||
@ -91,7 +90,7 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
|
||||
Cpu_session &parent_cpu_session();
|
||||
Rpc_entrypoint &thread_ep();
|
||||
Signal_receiver &exception_signal_receiver();
|
||||
Entrypoint &signal_ep();
|
||||
Thread_capability thread_cap(unsigned long lwpid);
|
||||
unsigned long lwpid(Thread_capability thread_cap);
|
||||
Cpu_thread_component *lookup_cpu_thread(unsigned long lwpid);
|
||||
@ -137,7 +136,7 @@ class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory
|
||||
|
||||
Allocator &_md_alloc;
|
||||
Pd_session_capability _core_pd;
|
||||
Signal_receiver &_signal_receiver;
|
||||
Entrypoint &_signal_ep;
|
||||
Genode_child_resources *_genode_child_resources;
|
||||
|
||||
|
||||
@ -147,12 +146,12 @@ class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator &md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver &signal_receiver,
|
||||
Entrypoint &signal_ep,
|
||||
Genode_child_resources *genode_child_resources)
|
||||
: _env(env), _ep(ep),
|
||||
_md_alloc(md_alloc),
|
||||
_core_pd(core_pd),
|
||||
_signal_receiver(signal_receiver),
|
||||
_signal_ep(signal_ep),
|
||||
_genode_child_resources(genode_child_resources)
|
||||
{ }
|
||||
|
||||
@ -168,7 +167,7 @@ class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory
|
||||
_ep,
|
||||
_md_alloc,
|
||||
_core_pd,
|
||||
_signal_receiver,
|
||||
_signal_ep,
|
||||
args.string(),
|
||||
affinity);
|
||||
_genode_child_resources->cpu_session_component(cpu_session_component);
|
||||
|
@ -42,13 +42,13 @@ bool Cpu_thread_component::_set_breakpoint_at_first_instruction(addr_t ip)
|
||||
|
||||
if (genode_read_memory(_breakpoint_ip, _original_instructions,
|
||||
breakpoint_len) != 0) {
|
||||
PWRN("%s: could not read memory at thread start address", __PRETTY_FUNCTION__);
|
||||
warning(__PRETTY_FUNCTION__, ": could not read memory at thread start address");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (genode_write_memory(_breakpoint_ip, breakpoint_data,
|
||||
breakpoint_len) != 0) {
|
||||
PWRN("%s: could not set breakpoint at thread start address", __PRETTY_FUNCTION__);
|
||||
warning(__PRETTY_FUNCTION__, ": could not set breakpoint at thread start address");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -60,23 +60,23 @@ void Cpu_thread_component::_remove_breakpoint_at_first_instruction()
|
||||
{
|
||||
if (genode_write_memory(_breakpoint_ip, _original_instructions,
|
||||
breakpoint_len) != 0)
|
||||
PWRN("%s: could not remove breakpoint at thread start address", __PRETTY_FUNCTION__);
|
||||
warning(__PRETTY_FUNCTION__, ": could not remove breakpoint at thread start address");
|
||||
}
|
||||
|
||||
|
||||
void Cpu_thread_component::_dispatch_exception(unsigned)
|
||||
void Cpu_thread_component::_handle_exception()
|
||||
{
|
||||
deliver_signal(SIGTRAP);
|
||||
}
|
||||
|
||||
|
||||
void Cpu_thread_component::_dispatch_sigstop(unsigned)
|
||||
void Cpu_thread_component::_handle_sigstop()
|
||||
{
|
||||
deliver_signal(SIGSTOP);
|
||||
}
|
||||
|
||||
|
||||
void Cpu_thread_component::_dispatch_sigint(unsigned)
|
||||
void Cpu_thread_component::_handle_sigint()
|
||||
{
|
||||
deliver_signal(SIGINT);
|
||||
}
|
||||
@ -88,25 +88,20 @@ Cpu_thread_component::Cpu_thread_component(Cpu_session_component &cpu_session_
|
||||
Affinity::Location affinity,
|
||||
Cpu_session::Weight weight,
|
||||
addr_t utcb)
|
||||
: _cpu_session_component(cpu_session_component),
|
||||
_parent_cpu_thread(
|
||||
_cpu_session_component.parent_cpu_session().create_thread(pd,
|
||||
name,
|
||||
affinity,
|
||||
weight,
|
||||
utcb)),
|
||||
_exception_dispatcher(
|
||||
_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_exception),
|
||||
_sigstop_dispatcher(
|
||||
_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_sigstop),
|
||||
_sigint_dispatcher(
|
||||
_cpu_session_component.exception_signal_receiver(),
|
||||
*this,
|
||||
&Cpu_thread_component::_dispatch_sigint)
|
||||
:
|
||||
_cpu_session_component(cpu_session_component),
|
||||
_parent_cpu_thread(
|
||||
_cpu_session_component.parent_cpu_session().create_thread(pd,
|
||||
name,
|
||||
affinity,
|
||||
weight,
|
||||
utcb)),
|
||||
_exception_handler(_cpu_session_component.signal_ep(), *this,
|
||||
&Cpu_thread_component::_handle_exception),
|
||||
_sigstop_handler(_cpu_session_component.signal_ep(), *this,
|
||||
&Cpu_thread_component::_handle_sigstop),
|
||||
_sigint_handler(_cpu_session_component.signal_ep(), *this,
|
||||
&Cpu_thread_component::_handle_sigint)
|
||||
{
|
||||
_cpu_session_component.thread_ep().manage(this);
|
||||
|
||||
|
@ -42,16 +42,16 @@ class Gdb_monitor::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
/*
|
||||
* SIGTRAP, SIGSTOP and SIGINT must get delivered to the gdbserver code
|
||||
* in the same order that they were generated. Since these signals are
|
||||
* generated by different threads, the exception signal receiver is
|
||||
* used as synchronization point.
|
||||
* generated by different threads, the signal ep is used as
|
||||
* synchronization point.
|
||||
*/
|
||||
Signal_dispatcher<Cpu_thread_component> _exception_dispatcher;
|
||||
Signal_dispatcher<Cpu_thread_component> _sigstop_dispatcher;
|
||||
Signal_dispatcher<Cpu_thread_component> _sigint_dispatcher;
|
||||
Signal_handler<Cpu_thread_component> _exception_handler;
|
||||
Signal_handler<Cpu_thread_component> _sigstop_handler;
|
||||
Signal_handler<Cpu_thread_component> _sigint_handler;
|
||||
|
||||
int _pipefd[2];
|
||||
bool _initial_sigtrap_pending = true;
|
||||
bool _initial_breakpoint_handled = false;
|
||||
int _pipefd[2];
|
||||
bool _initial_sigtrap_pending = true;
|
||||
bool _initial_breakpoint_handled = false;
|
||||
|
||||
/* data for breakpoint at first instruction */
|
||||
enum { MAX_BREAKPOINT_LEN = 8 }; /* value from mem-break.c */
|
||||
@ -61,9 +61,9 @@ class Gdb_monitor::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
bool _set_breakpoint_at_first_instruction(addr_t ip);
|
||||
void _remove_breakpoint_at_first_instruction();
|
||||
|
||||
void _dispatch_exception(unsigned);
|
||||
void _dispatch_sigstop(unsigned);
|
||||
void _dispatch_sigint(unsigned);
|
||||
void _handle_exception();
|
||||
void _handle_sigstop();
|
||||
void _handle_sigint();
|
||||
|
||||
public:
|
||||
|
||||
@ -78,23 +78,26 @@ class Gdb_monitor::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
|
||||
Signal_context_capability exception_signal_context_cap()
|
||||
{
|
||||
return _exception_dispatcher;
|
||||
return _exception_handler;
|
||||
}
|
||||
|
||||
Signal_context_capability sigstop_signal_context_cap()
|
||||
{
|
||||
return _sigstop_dispatcher;
|
||||
return _sigstop_handler;
|
||||
}
|
||||
|
||||
Signal_context_capability sigint_signal_context_cap()
|
||||
{
|
||||
return _sigint_dispatcher;
|
||||
return _sigint_handler;
|
||||
}
|
||||
|
||||
Thread_capability thread_cap() { return cap(); }
|
||||
unsigned long lwpid() { return _lwpid; }
|
||||
|
||||
Thread_capability parent_thread_cap() { return _parent_cpu_thread; }
|
||||
Thread_capability parent_thread_cap()
|
||||
{
|
||||
return _parent_cpu_thread.rpc_cap();
|
||||
}
|
||||
|
||||
int signal_pipe_read_fd() { return _pipefd[0]; }
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "app_child.h"
|
||||
#include "cpu_thread_component.h"
|
||||
#include "genode_child_resources.h"
|
||||
#include "signal_handler_thread.h"
|
||||
|
||||
/* libc includes */
|
||||
#include <sys/ptrace.h>
|
||||
@ -441,17 +440,23 @@ extern "C" int fork()
|
||||
|
||||
/* extract target filename from config file */
|
||||
|
||||
static char filename[32] = "";
|
||||
typedef String<32> Filename;
|
||||
Filename filename { };
|
||||
|
||||
Genode::Attached_rom_dataspace config { *genode_env, "config" };
|
||||
|
||||
try {
|
||||
config.xml().sub_node("target").attribute("name").value(filename, sizeof(filename));
|
||||
Xml_node const target = config.xml().sub_node("target");
|
||||
|
||||
if (!target.has_attribute("name")) {
|
||||
error("missing 'name' attribute of '<target>' sub node");
|
||||
return -1;
|
||||
}
|
||||
filename = target.attribute_value("name", Filename());
|
||||
|
||||
} catch (Xml_node::Nonexistent_sub_node) {
|
||||
error("missing '<target>' sub node");
|
||||
return -1;
|
||||
} catch (Xml_node::Nonexistent_attribute) {
|
||||
error("missing 'name' attribute of '<target>' sub node");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* extract target node from config file */
|
||||
@ -465,7 +470,7 @@ extern "C" int fork()
|
||||
try {
|
||||
Xml_node preserve_node = config.xml().sub_node("preserve");
|
||||
if (preserve_node.attribute("name").has_value("RAM"))
|
||||
preserve_node.attribute("quantum").value(&preserved_ram_quota);
|
||||
preserve_node.attribute("quantum").value(preserved_ram_quota);
|
||||
else
|
||||
throw Xml_node::Exception();
|
||||
} catch (...) {
|
||||
@ -473,7 +478,7 @@ extern "C" int fork()
|
||||
return -1;
|
||||
}
|
||||
|
||||
Number_of_bytes ram_quota = genode_env->ram().avail_ram().value - preserved_ram_quota;
|
||||
Number_of_bytes ram_quota = genode_env->pd().avail_ram().value - preserved_ram_quota;
|
||||
|
||||
Cap_quota const avail_cap_quota = genode_env->pd().avail_caps();
|
||||
|
||||
@ -490,18 +495,16 @@ extern "C" int fork()
|
||||
|
||||
static Heap alloc(genode_env->ram(), genode_env->rm());
|
||||
|
||||
static Signal_receiver signal_receiver;
|
||||
|
||||
static Gdb_monitor::Signal_handler_thread
|
||||
signal_handler_thread(*genode_env, signal_receiver);
|
||||
signal_handler_thread.start();
|
||||
enum { SIGNAL_EP_STACK_SIZE = 2*1024*sizeof(addr_t) };
|
||||
static Entrypoint signal_ep { *genode_env, SIGNAL_EP_STACK_SIZE,
|
||||
"sig_handler", Affinity::Location() };
|
||||
|
||||
App_child *child = new (alloc) App_child(*genode_env,
|
||||
alloc,
|
||||
filename,
|
||||
filename.string(),
|
||||
Ram_quota{ram_quota},
|
||||
cap_quota,
|
||||
signal_receiver,
|
||||
signal_ep,
|
||||
target_node);
|
||||
|
||||
_genode_child_resources = child->genode_child_resources();
|
||||
|
@ -55,9 +55,9 @@ class Gdb_monitor::Pd_session_component : public Rpc_object<Pd_session>
|
||||
_ep(ep),
|
||||
_alloc(alloc),
|
||||
_pd(env, binary_name),
|
||||
_address_space(_ep, _alloc, managed_ds_map, _pd, _pd.address_space()),
|
||||
_stack_area (_ep, _alloc, managed_ds_map, _pd, _pd.stack_area()),
|
||||
_linker_area (_ep, _alloc, managed_ds_map, _pd, _pd.linker_area())
|
||||
_address_space(_ep, _alloc, managed_ds_map, _pd.rpc_cap(), _pd.address_space()),
|
||||
_stack_area (_ep, _alloc, managed_ds_map, _pd.rpc_cap(), _pd.stack_area()),
|
||||
_linker_area (_ep, _alloc, managed_ds_map, _pd.rpc_cap(), _pd.linker_area())
|
||||
{
|
||||
_ep.manage(this);
|
||||
}
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* \brief Core-specific instance of the RAM session interface
|
||||
* \author Norman Feske
|
||||
* \date 2006-06-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _RAM_SESSION_COMPONENT_H_
|
||||
#define _RAM_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <ram_session/client.h>
|
||||
|
||||
namespace Gdb_monitor
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
class Ram_session_component;
|
||||
}
|
||||
|
||||
class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
|
||||
{
|
||||
private:
|
||||
|
||||
Env &_env;
|
||||
|
||||
Parent::Client _parent_client;
|
||||
|
||||
Id_space<Parent::Client>::Element const _id_space_element
|
||||
{ _parent_client, _env.id_space() };
|
||||
|
||||
Ram_session_client _parent_ram_session;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Ram_session_component(Env &env, const char *args,
|
||||
Affinity const &affinity);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Ram_session_component();
|
||||
|
||||
|
||||
/***************************
|
||||
** RAM Session interface **
|
||||
***************************/
|
||||
|
||||
Ram_dataspace_capability alloc(size_t, Cache_attribute) override;
|
||||
void free(Ram_dataspace_capability) override;
|
||||
size_t dataspace_size(Ram_dataspace_capability) const override;
|
||||
void ref_account(Ram_session_capability) override;
|
||||
void transfer_quota(Ram_session_capability, Ram_quota) override;
|
||||
Ram_quota ram_quota() const override;
|
||||
Ram_quota used_ram() const override;
|
||||
};
|
||||
|
||||
#endif /* _RAM_SESSION_COMPONENT_H_ */
|
@ -13,7 +13,6 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <util/retry.h>
|
||||
|
||||
@ -59,14 +58,14 @@ Region_map_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||
size_t ds_size = Dataspace_client(ds_cap).size();
|
||||
|
||||
if (offset < 0 || (size_t)offset >= ds_size) {
|
||||
PWRN("offset outside of dataspace");
|
||||
warning("offset outside of dataspace");
|
||||
throw Region_conflict();
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
size = ds_size - offset;
|
||||
else if (size > ds_size - offset) {
|
||||
PWRN("size bigger than remainder of dataspace");
|
||||
warning("size bigger than remainder of dataspace");
|
||||
throw Region_conflict();
|
||||
}
|
||||
|
||||
@ -88,7 +87,7 @@ void Region_map_component::detach(Region_map::Local_addr local_addr)
|
||||
Lock::Guard lock_guard(_region_map_lock);
|
||||
Region *region = _region_map.first()->find_by_addr(local_addr);
|
||||
if (!region) {
|
||||
PERR("address not in region map");
|
||||
warning("address not in region map");
|
||||
return;
|
||||
}
|
||||
_region_map.remove(region);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/allocator.h>
|
||||
#include <pd_session/capability.h>
|
||||
#include <region_map/client.h>
|
||||
|
||||
|
@ -5,56 +5,39 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/sleep.h>
|
||||
#include <base/thread.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* a variable to be modified with GDB */
|
||||
int test_var = 1;
|
||||
|
||||
/* a thread to test GDB thread switching support */
|
||||
class Test_thread : public Genode::Thread_deprecated<2*4096>
|
||||
|
||||
void test_thread_step()
|
||||
{
|
||||
public:
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
Test_thread() : Thread_deprecated("test") { }
|
||||
|
||||
void step_func()
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
void test_thread_sigsegv()
|
||||
{
|
||||
*(int *)0 = 42;
|
||||
}
|
||||
|
||||
void sigsegv_func()
|
||||
{
|
||||
/*
|
||||
* make sure that the main thread is sleeping in
|
||||
* Genode::sleep_forever() when the segfault happens
|
||||
*/
|
||||
static Timer::Connection timer;
|
||||
timer.msleep(500);
|
||||
|
||||
*(int *)0 = 42;
|
||||
}
|
||||
void *test_thread_start(void*)
|
||||
{
|
||||
test_thread_step();
|
||||
test_thread_sigsegv();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void entry() /* set a breakpoint here to test the 'info threads' command */
|
||||
{
|
||||
step_func();
|
||||
|
||||
sigsegv_func();
|
||||
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This function returns the current value of 'test_var' + 1 and can be called from
|
||||
@ -88,16 +71,13 @@ int func1()
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
int main()
|
||||
{
|
||||
Test_thread test_thread;
|
||||
|
||||
func1();
|
||||
|
||||
test_thread.start();
|
||||
|
||||
test_thread.join();
|
||||
pthread_t test_thread;
|
||||
pthread_create(&test_thread, nullptr, test_thread_start, nullptr);
|
||||
pthread_join(test_thread, nullptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = test-gdb_monitor
|
||||
SRC_CC = main.cc
|
||||
LIBS = posix
|
||||
LIBS = base posix
|
||||
|
||||
CC_OLEVEL = -O0
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user