diff --git a/base-foc/include/base/thread_state.h b/base-foc/include/base/thread_state.h
index d5ebd4ddcc..31e6c3167e 100644
--- a/base-foc/include/base/thread_state.h
+++ b/base-foc/include/base/thread_state.h
@@ -18,11 +18,11 @@
#include
#include
-#include
+#include
namespace Genode {
- struct Thread_state : public Cpu_state
+ struct Thread_state : Thread_state_base
{
Native_thread kcap; /* thread's gate cap in its pd */
int id; /* id of gate capability */
diff --git a/base-foc/src/base/pager/pager.cc b/base-foc/src/base/pager/pager.cc
index 5121f2738a..075619d7c7 100644
--- a/base-foc/src/base/pager/pager.cc
+++ b/base-foc/src/base/pager/pager.cc
@@ -81,6 +81,8 @@ void Pager_activation_base::entry()
/* handle request */
if (obj->pager(pager)) {
/* could not resolv - leave thread in pagefault */
+ Lock::Guard guard(obj->state.lock);
+ obj->state.unresolved_page_fault = true;
PDBG("Could not resolve pf=%p ip=%p",
(void*)pager.fault_addr(), (void*)pager.fault_ip());
} else {
diff --git a/base-nova/include/base/thread_state.h b/base-nova/include/base/thread_state.h
index bcfdb3f688..8228199227 100644
--- a/base-nova/include/base/thread_state.h
+++ b/base-nova/include/base/thread_state.h
@@ -16,16 +16,16 @@
#ifndef _INCLUDE__BASE__THREAD_STATE_H_
#define _INCLUDE__BASE__THREAD_STATE_H_
-#include
+#include
namespace Genode {
- struct Thread_state : public Cpu_state
+ struct Thread_state : Thread_state_base
{
bool is_vcpu;
addr_t sel_exc_base;
- Thread_state() : Cpu_state(), is_vcpu(false), sel_exc_base(~0UL) { }
+ Thread_state() : is_vcpu(false), sel_exc_base(~0UL) { }
Thread_state(bool is_vcpu, addr_t sel_exc_base)
: is_vcpu(is_vcpu), sel_exc_base(sel_exc_base) { }
diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc
index 261f7d016c..fcdd93158d 100644
--- a/base-nova/src/base/pager/pager.cc
+++ b/base-nova/src/base/pager/pager.cc
@@ -80,6 +80,8 @@ void Pager_object::_page_fault_handler()
}
if (ret == 1) {
+ obj->_state.thread.unresolved_page_fault = true;
+
char client_name[Context::NAME_LEN];
myself->name(client_name, sizeof(client_name));
diff --git a/base-okl4/include/base/thread_state.h b/base-okl4/include/base/thread_state.h
index 7148a8f083..ecbe2c0e56 100644
--- a/base-okl4/include/base/thread_state.h
+++ b/base-okl4/include/base/thread_state.h
@@ -20,11 +20,11 @@ namespace Okl4 { extern "C" {
#include
} }
-#include
+#include
namespace Genode {
- struct Thread_state : public Cpu_state
+ struct Thread_state : Thread_state_base
{
Okl4::L4_ThreadId_t tid; /* OKL4 specific thread id */
};
diff --git a/base/include/base/thread_state.h b/base/include/base/thread_state.h
index e03b1f000e..37a02a9e61 100644
--- a/base/include/base/thread_state.h
+++ b/base/include/base/thread_state.h
@@ -3,7 +3,8 @@
* \author Norman Feske
* \date 2007-07-30
*
- * This file contains the generic part of the thread state.
+ * This file provides a generic implementation of the 'Thread state' class.
+ * Base platforms can provide their own version of this file.
*/
/*
@@ -16,11 +17,11 @@
#ifndef _INCLUDE__BASE__THREAD_STATE_H_
#define _INCLUDE__BASE__THREAD_STATE_H_
-#include
+#include
namespace Genode {
- struct Thread_state : public Cpu_state { };
+ struct Thread_state : Thread_state_base { };
}
#endif /* _INCLUDE__BASE__THREAD_STATE_H_ */
diff --git a/base/include/base/thread_state_base.h b/base/include/base/thread_state_base.h
new file mode 100644
index 0000000000..b72b1f3388
--- /dev/null
+++ b/base/include/base/thread_state_base.h
@@ -0,0 +1,31 @@
+/*
+ * \brief Thread state base class
+ * \author Norman Feske
+ * \date 2007-07-30
+ *
+ * This file contains the generic part of the thread state.
+ */
+
+/*
+ * Copyright (C) 2007-2013 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.
+ */
+
+#ifndef _INCLUDE__BASE__THREAD_STATE_BASE_H_
+#define _INCLUDE__BASE__THREAD_STATE_BASE_H_
+
+#include
+
+namespace Genode {
+
+ struct Thread_state_base : Cpu_state
+ {
+ bool unresolved_page_fault;
+
+ Thread_state_base() : unresolved_page_fault(false) { };
+ };
+}
+
+#endif /* _INCLUDE__BASE__THREAD_STATE_BASE_H_ */
diff --git a/ports/src/app/gdb_monitor/gdbserver/genode-low.cc b/ports/src/app/gdb_monitor/gdbserver/genode-low.cc
index 5df427c3ef..74f598dc07 100644
--- a/ports/src/app/gdb_monitor/gdbserver/genode-low.cc
+++ b/ports/src/app/gdb_monitor/gdbserver/genode-low.cc
@@ -181,6 +181,23 @@ void genode_continue_thread(unsigned long lwpid, int single_step)
}
+unsigned long genode_find_segfault_lwpid()
+{
+ Cpu_session_component *csc = gdb_stub_thread()->cpu_session_component();
+
+ Thread_capability thread_cap = csc->first();
+
+ while (thread_cap.valid()) {
+ Thread_state thread_state = csc->state(thread_cap);
+ if (thread_state.unresolved_page_fault)
+ return csc->lwpid(thread_cap);
+ thread_cap = csc->next(thread_cap);
+ }
+
+ PDBG("could not determine thread which caused the page fault");
+ return 1;
+}
+
class Memory_model
{
diff --git a/ports/src/app/gdb_monitor/gdbserver/genode-low.h b/ports/src/app/gdb_monitor/gdbserver/genode-low.h
index 4ef0f7c840..19fb10b37f 100644
--- a/ports/src/app/gdb_monitor/gdbserver/genode-low.h
+++ b/ports/src/app/gdb_monitor/gdbserver/genode-low.h
@@ -31,6 +31,8 @@ void genode_resume_all_threads();
ptid_t genode_wait_for_signal_or_gdb_interrupt(struct target_waitstatus *status);
void genode_continue_thread(unsigned long lwpid, int single_step);
+unsigned long genode_find_segfault_lwpid();
+
int genode_fetch_register(int regno, unsigned long *reg_content);
void genode_store_register(int regno, unsigned long reg_content);
unsigned char genode_read_memory_byte(void *addr);
diff --git a/ports/src/app/gdb_monitor/gdbserver_genode.patch b/ports/src/app/gdb_monitor/gdbserver_genode.patch
index 9f02b4844b..30793a88c3 100644
--- a/ports/src/app/gdb_monitor/gdbserver_genode.patch
+++ b/ports/src/app/gdb_monitor/gdbserver_genode.patch
@@ -651,7 +651,7 @@ index 69c6b57..cffa803 100644
x86_supports_tracepoints,
x86_get_thread_area,
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
-index 650ddf8..046dd2e 100644
+index 650ddf8..728da30 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -18,11 +18,14 @@
@@ -756,11 +756,11 @@ index 650ddf8..046dd2e 100644
+ genode_stop_all_threads();
+
+ if (sig > 0) {
-+ event_ptid.lwp = sig;
++ event_ptid.lwp = sig;
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ } else {
-+ event_ptid.lwp = 1;
++ event_ptid.lwp = genode_find_segfault_lwpid();
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_SEGV;
+ }