GDB monitor: find out page faulting thread

Fixes #898.
This commit is contained in:
Christian Prochaska 2013-10-24 16:05:31 +02:00 committed by Christian Helmuth
parent 5774a864b1
commit cc04ffcf42
10 changed files with 68 additions and 13 deletions

View File

@ -18,11 +18,11 @@
#include <base/capability.h>
#include <base/lock.h>
#include <cpu/cpu_state.h>
#include <base/thread_state_base.h>
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 */

View File

@ -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 {

View File

@ -16,16 +16,16 @@
#ifndef _INCLUDE__BASE__THREAD_STATE_H_
#define _INCLUDE__BASE__THREAD_STATE_H_
#include <cpu/cpu_state.h>
#include <base/thread_state_base.h>
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) { }

View File

@ -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));

View File

@ -20,11 +20,11 @@ namespace Okl4 { extern "C" {
#include <l4/types.h>
} }
#include <cpu/cpu_state.h>
#include <base/thread_state_base.h>
namespace Genode {
struct Thread_state : public Cpu_state
struct Thread_state : Thread_state_base
{
Okl4::L4_ThreadId_t tid; /* OKL4 specific thread id */
};

View File

@ -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 <cpu/cpu_state.h>
#include <base/thread_state_base.h>
namespace Genode {
struct Thread_state : public Cpu_state { };
struct Thread_state : Thread_state_base { };
}
#endif /* _INCLUDE__BASE__THREAD_STATE_H_ */

View File

@ -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 <cpu/cpu_state.h>
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_ */

View File

@ -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
{

View File

@ -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);

View File

@ -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;
+ }