performace improvments

This commit is contained in:
Stefani Seibold 2015-05-10 22:42:55 +02:00
parent c711f9e033
commit 037149204d
5 changed files with 61 additions and 38 deletions

View File

@ -34,15 +34,20 @@
#define HW_BP_SCRATCH 2 #define HW_BP_SCRATCH 2
struct breakpoint { struct breakpoint {
int (*on_hit)(struct task *task, struct breakpoint *bp);
struct library_symbol *libsym;
arch_addr_t addr; arch_addr_t addr;
unsigned int enabled:1; unsigned int enabled:1;
unsigned int locked:1; unsigned int locked:1;
unsigned int deleted:1; unsigned int deleted:1;
unsigned int type:2; unsigned int type:2;
unsigned int ext:8; unsigned int ext:8;
unsigned int refcnt; unsigned int refcnt;
int (*on_hit)(struct task *task, struct breakpoint *bp);
struct library_symbol *libsym;
union { union {
unsigned char orig_value[BREAKPOINT_LENGTH]; unsigned char orig_value[BREAKPOINT_LENGTH];
#if HW_BREAKPOINTS > 0 #if HW_BREAKPOINTS > 0

View File

@ -403,7 +403,7 @@ static inline int dwarf_readw(struct dwarf_addr_space *as, arch_addr_t *addr, ar
int ret; int ret;
if (is_64bit) { if (is_64bit) {
uint64_t u64; uint64_t u64 = 0;
ret = dwarf_read64(as, addr, &u64); ret = dwarf_read64(as, addr, &u64);
@ -411,7 +411,7 @@ static inline int dwarf_readw(struct dwarf_addr_space *as, arch_addr_t *addr, ar
*valp = u64; *valp = u64;
} }
else { else {
uint32_t u32; uint32_t u32 = 0;
ret = dwarf_read32(as, addr, &u32); ret = dwarf_read32(as, addr, &u32);

View File

@ -70,6 +70,9 @@ static int set_breakpoint_addr(struct task *task, arch_addr_t addr, unsigned int
addr &= 0xffffffff; addr &= 0xffffffff;
#endif #endif
if (task->arch.hw_bp[n] == addr)
return 0;
ret = ptrace(PTRACE_POKEUSER, task->pid, offsetof(struct user, u_debugreg[n]), addr); ret = ptrace(PTRACE_POKEUSER, task->pid, offsetof(struct user, u_debugreg[n]), addr);
if (ret) { if (ret) {
if (errno != ESRCH) { if (errno != ESRCH) {
@ -77,6 +80,9 @@ static int set_breakpoint_addr(struct task *task, arch_addr_t addr, unsigned int
return -1; return -1;
} }
} }
task->arch.hw_bp[n] = addr;
return 0; return 0;
} }
@ -187,6 +193,11 @@ int is_64bit(struct mt_elf *mte)
int arch_task_init(struct task *task) int arch_task_init(struct task *task)
{ {
unsigned int i;
for(i = 0; i < HW_BREAKPOINTS; ++i)
task->arch.hw_bp[i] = 0;
return _apply_hw_bp(task, 0); return _apply_hw_bp(task, 0);
} }

View File

@ -52,6 +52,7 @@ struct context {
struct arch_task_data { struct arch_task_data {
unsigned long dr7; unsigned long dr7;
unsigned long hw_bp[HW_BREAKPOINTS];
}; };
#endif #endif

74
task.h
View File

@ -38,10 +38,18 @@
#include "report.h" #include "report.h"
struct task { struct task {
struct rb_node pid_node; /* red/black tree node for fast pid -> struct task */ /* red/black tree node for fast pid -> struct task */
struct rb_node pid_node;
/* process id */
pid_t pid; pid_t pid;
/* points to the leader thread of the POSIX.1 task */
struct task *leader;
/* current pendig event */
struct event event;
unsigned int stopped:1; unsigned int stopped:1;
unsigned int traced:1; unsigned int traced:1;
unsigned int was_stopped:1; unsigned int was_stopped:1;
@ -49,42 +57,10 @@ struct task {
unsigned int attached:1; unsigned int attached:1;
unsigned int deleted:1; unsigned int deleted:1;
/* Dictionary of breakpoints */ struct breakpoint *breakpoint;
struct dict *breakpoints;
struct library_symbol *libsym; struct library_symbol *libsym;
struct context context; /* process context (registers, stack) */ struct context context; /* process context (registers, stack) */
struct context saved_context; /* context for fetch_param() */ struct context saved_context; /* context for fetch_param() */
struct breakpoint *breakpoint;
unsigned int threads; /* set in leader: number of threads including the leader */
unsigned int threads_stopped; /* set in leader: number of stopped threads including the leader */
/* linked list of libraries, the first entry is the executable itself */
struct list_head libraries_list;
void *backtrace;
/* struct task chaining. */
struct list_head leader_list;
/* points to the leader thread of the POSIX.1 task */
struct task *leader;
/* Thread chaining to leader */
struct list_head task_list;
/* current pendig event */
struct event event;
/* pointer to a breakpoint which was interrupt by a signal during skip */
struct breakpoint *skip_bp;
/* only used in leader: bit mask for used hw breakpoints */
unsigned long hw_bp_mask;
/* array of addresses of hw breakpoints */
struct breakpoint *hw_bp[HW_BREAKPOINTS];
/* os specific task data */ /* os specific task data */
#ifdef OS_HAVE_PROCESS_DATA #ifdef OS_HAVE_PROCESS_DATA
@ -95,6 +71,36 @@ struct task {
#ifdef TASK_HAVE_PROCESS_DATA #ifdef TASK_HAVE_PROCESS_DATA
struct arch_task_data arch; struct arch_task_data arch;
#endif #endif
/* pointer to a breakpoint which was interrupt by a signal during skip */
struct breakpoint *skip_bp;
/* array of addresses of hw breakpoints */
struct breakpoint *hw_bp[HW_BREAKPOINTS];
/* set in leader: number of stopped threads including the leader */
unsigned int threads_stopped;
/* set in leader: dictionary of breakpoints */
struct dict *breakpoints;
/* set in leader: backtrace pimpl */
void *backtrace;
/* linked list of libraries, the first entry is the executable itself */
struct list_head libraries_list;
/* Thread chaining to leader */
struct list_head task_list;
/* set in leader: number of threads including the leader */
unsigned int threads;
/* only used in leader: bit mask for used hw breakpoints */
unsigned long hw_bp_mask;
/* struct task chaining. */
struct list_head leader_list;
}; };
/* PROC underwent an exec. This is a bit like task_destroy /* PROC underwent an exec. This is a bit like task_destroy