From 037149204dd3c9537b251f027dfb86f6e3bac318 Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Sun, 10 May 2015 22:42:55 +0200 Subject: [PATCH] performace improvments --- breakpoint.h | 9 ++++- dwarf.c | 4 +- sysdeps/linux-gnu/x86/arch.c | 11 ++++++ sysdeps/linux-gnu/x86/arch.h | 1 + task.h | 74 +++++++++++++++++++----------------- 5 files changed, 61 insertions(+), 38 deletions(-) diff --git a/breakpoint.h b/breakpoint.h index fa89aa1..2acd3e8 100644 --- a/breakpoint.h +++ b/breakpoint.h @@ -34,15 +34,20 @@ #define HW_BP_SCRATCH 2 struct breakpoint { - int (*on_hit)(struct task *task, struct breakpoint *bp); - struct library_symbol *libsym; arch_addr_t addr; + unsigned int enabled:1; unsigned int locked:1; unsigned int deleted:1; unsigned int type:2; unsigned int ext:8; + unsigned int refcnt; + + int (*on_hit)(struct task *task, struct breakpoint *bp); + + struct library_symbol *libsym; + union { unsigned char orig_value[BREAKPOINT_LENGTH]; #if HW_BREAKPOINTS > 0 diff --git a/dwarf.c b/dwarf.c index 35a9a0b..5960ed3 100644 --- a/dwarf.c +++ b/dwarf.c @@ -403,7 +403,7 @@ static inline int dwarf_readw(struct dwarf_addr_space *as, arch_addr_t *addr, ar int ret; if (is_64bit) { - uint64_t u64; + uint64_t u64 = 0; 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; } else { - uint32_t u32; + uint32_t u32 = 0; ret = dwarf_read32(as, addr, &u32); diff --git a/sysdeps/linux-gnu/x86/arch.c b/sysdeps/linux-gnu/x86/arch.c index 4034a5e..a119fbd 100644 --- a/sysdeps/linux-gnu/x86/arch.c +++ b/sysdeps/linux-gnu/x86/arch.c @@ -70,6 +70,9 @@ static int set_breakpoint_addr(struct task *task, arch_addr_t addr, unsigned int addr &= 0xffffffff; #endif + if (task->arch.hw_bp[n] == addr) + return 0; + ret = ptrace(PTRACE_POKEUSER, task->pid, offsetof(struct user, u_debugreg[n]), addr); if (ret) { if (errno != ESRCH) { @@ -77,6 +80,9 @@ static int set_breakpoint_addr(struct task *task, arch_addr_t addr, unsigned int return -1; } } + + task->arch.hw_bp[n] = addr; + return 0; } @@ -187,6 +193,11 @@ int is_64bit(struct mt_elf *mte) 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); } diff --git a/sysdeps/linux-gnu/x86/arch.h b/sysdeps/linux-gnu/x86/arch.h index a7e0034..e84b45d 100644 --- a/sysdeps/linux-gnu/x86/arch.h +++ b/sysdeps/linux-gnu/x86/arch.h @@ -52,6 +52,7 @@ struct context { struct arch_task_data { unsigned long dr7; + unsigned long hw_bp[HW_BREAKPOINTS]; }; #endif diff --git a/task.h b/task.h index f03d253..218b366 100644 --- a/task.h +++ b/task.h @@ -38,53 +38,29 @@ #include "report.h" 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; + /* 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 traced:1; unsigned int was_stopped:1; unsigned int is_64bit:1; unsigned int attached:1; unsigned int deleted:1; - - /* Dictionary of breakpoints */ - struct dict *breakpoints; + struct breakpoint *breakpoint; struct library_symbol *libsym; struct context context; /* process context (registers, stack) */ 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 */ #ifdef OS_HAVE_PROCESS_DATA @@ -95,6 +71,36 @@ struct task { #ifdef TASK_HAVE_PROCESS_DATA struct arch_task_data arch; #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