* New locking strategy for the team debug info. It's no longer protected
by the team lock, but by a lock in the structure. This is necessary since we can't acquire the team lock while thread switching, for then the thread lock is already held. * Added support for single stepping and break-/watchpoints. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11503 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,16 +9,39 @@
|
||||
|
||||
#include <debugger.h>
|
||||
|
||||
#include <arch/user_debugger.h>
|
||||
|
||||
// Team related debugging data.
|
||||
//
|
||||
// Locking policy:
|
||||
// 1) When accessing the structure it must be made sure, that the structure,
|
||||
// (i.e. the struct team it lives in) isn't deleted. Thus one either needs to
|
||||
// acquire the global team lock, or one accesses the structure from a thread
|
||||
// of that team.
|
||||
// 2) Access to the `flags' field is atomically. Reading via atomic_get()
|
||||
// requires no further locks (in addition to 1) that is). Writing requires
|
||||
// `lock' being held and must be done atomically, too
|
||||
// (atomic_{set,and,or}()). Reading with `lock' being held doesn't need to
|
||||
// be done atomically.
|
||||
// 3) Access to all other fields (read or write) requires `lock' being held.
|
||||
//
|
||||
struct team_debug_info {
|
||||
spinlock lock;
|
||||
// Guards the remaining fields. Should always be the innermost lock
|
||||
// to be acquired/released.
|
||||
|
||||
int32 flags;
|
||||
// Set atomically. So reading atomically is OK, even when the team
|
||||
// lock is not held (at least if it is certain, that the team struct
|
||||
// won't go).
|
||||
|
||||
team_id debugger_team;
|
||||
port_id debugger_port;
|
||||
thread_id nub_thread;
|
||||
port_id nub_port;
|
||||
// the port the nub thread is waiting on for commands from the debugger
|
||||
|
||||
struct arch_team_debug_info arch_info;
|
||||
};
|
||||
|
||||
struct thread_debug_info {
|
||||
@@ -30,6 +53,9 @@ struct thread_debug_info {
|
||||
// the port the thread is waiting on for commands from the nub thread
|
||||
};
|
||||
|
||||
#define GRAB_TEAM_DEBUG_INFO_LOCK(info) acquire_spinlock(&(info).lock)
|
||||
#define RELEASE_TEAM_DEBUG_INFO_LOCK(info) release_spinlock(&(info).lock)
|
||||
|
||||
// team debugging flags (user-specifiable flags are in <debugger.h>)
|
||||
enum {
|
||||
B_TEAM_DEBUG_DEBUGGER_INSTALLED = 0x0001,
|
||||
@@ -47,6 +73,7 @@ enum {
|
||||
B_THREAD_DEBUG_DYING = 0x0002,
|
||||
B_THREAD_DEBUG_STOP = 0x0004,
|
||||
B_THREAD_DEBUG_STOPPED = 0x0008,
|
||||
B_THREAD_DEBUG_SINGLE_STEP = 0x0010,
|
||||
|
||||
B_THREAD_DEBUG_KERNEL_FLAG_MASK = 0xffff,
|
||||
|
||||
@@ -57,14 +84,21 @@ enum {
|
||||
typedef enum {
|
||||
B_DEBUGGED_THREAD_MESSAGE_CONTINUE = 0,
|
||||
B_DEBUGGED_THREAD_GET_WHY_STOPPED,
|
||||
B_DEBUGGED_THREAD_SET_CPU_STATE,
|
||||
} debugged_thread_message;
|
||||
|
||||
typedef struct {
|
||||
uint32 handle_event;
|
||||
} debugged_thread_run;
|
||||
bool single_step;
|
||||
} debugged_thread_continue;
|
||||
|
||||
typedef struct {
|
||||
debug_cpu_state cpu_state;
|
||||
} debugged_thread_set_cpu_state;
|
||||
|
||||
typedef union {
|
||||
debugged_thread_run run;
|
||||
debugged_thread_continue continue_thread;
|
||||
debugged_thread_set_cpu_state set_cpu_state;
|
||||
} debugged_thread_message_data;
|
||||
|
||||
|
||||
@@ -74,7 +108,7 @@ extern "C" {
|
||||
|
||||
// service calls
|
||||
|
||||
void clear_team_debug_info(struct team_debug_info *info);
|
||||
void clear_team_debug_info(struct team_debug_info *info, bool initLock);
|
||||
void destroy_team_debug_info(struct team_debug_info *info);
|
||||
|
||||
void clear_thread_debug_info(struct thread_debug_info *info,
|
||||
|
||||
Reference in New Issue
Block a user