* 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:
Ingo Weinhold
2005-02-28 00:34:06 +00:00
parent a67d62f1db
commit a7ad39fe09
2 changed files with 294 additions and 50 deletions
+37 -3
View File
@@ -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,