breakpoints.c revision cac15c3f170b5ec2cc6304c8c0763a78103e1778
1#if HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#include <stdlib.h> 6#include <assert.h> 7 8#ifdef __powerpc__ 9#include <sys/ptrace.h> 10#endif 11 12#include "ltrace.h" 13#include "options.h" 14#include "debug.h" 15#include "dict.h" 16 17/*****************************************************************************/ 18 19struct breakpoint * 20address2bpstruct(struct process * proc, void * addr) { 21 return dict_find_entry(proc->breakpoints, addr); 22} 23 24void 25insert_breakpoint(struct process * proc, void * addr) { 26 struct breakpoint * sbp; 27 28 if (!proc->breakpoints) { 29 proc->breakpoints = dict_init(dict_key2hash_int, dict_key_cmp_int); 30 /* atexit(brk_dict_clear); */ /* why bother to do this on exit? */ 31 } 32 sbp = dict_find_entry(proc->breakpoints, addr); 33 if (!sbp) { 34 sbp = malloc(sizeof(struct breakpoint)); 35 if (!sbp) { 36 return; /* TODO FIXME XXX: error_mem */ 37 } 38 dict_enter(proc->breakpoints, addr, sbp); 39 sbp->addr = addr; 40 sbp->enabled = 0; 41 } 42 sbp->enabled++; 43 if (sbp->enabled==1 && proc->pid) enable_breakpoint(proc->pid, sbp); 44} 45 46void 47delete_breakpoint(struct process * proc, void * addr) { 48 struct breakpoint * sbp = dict_find_entry(proc->breakpoints, addr); 49 assert(sbp); /* FIXME: remove after debugging has been done. */ 50 /* This should only happen on out-of-memory conditions. */ 51 if (sbp == NULL) return; 52 53 sbp->enabled--; 54 if (sbp->enabled == 0) disable_breakpoint(proc->pid, sbp); 55 assert(sbp->enabled >= 0); 56} 57 58static void 59enable_bp_cb(void * addr, void * sbp, void * proc) { 60 if (((struct breakpoint *)sbp)->enabled) { 61 enable_breakpoint(((struct process *)proc)->pid, sbp); 62 } 63} 64 65void 66enable_all_breakpoints(struct process * proc) { 67 if (proc->breakpoints_enabled <= 0) { 68#ifdef __powerpc__ 69 unsigned long a; 70 71 /* 72 * PPC HACK! (XXX FIXME TODO) 73 * If the dynamic linker hasn't populated the PLT then 74 * dont enable the breakpoints 75 */ 76 if (opt_L) { 77 a = ptrace(PTRACE_PEEKTEXT, proc->pid, proc->list_of_symbols->enter_addr, 0); 78 if (a == 0x0) 79 return; 80 } 81#endif 82 83 debug(1, "Enabling breakpoints for pid %u...", proc->pid); 84 dict_apply_to_all(proc->breakpoints, enable_bp_cb, proc); 85 } 86 proc->breakpoints_enabled = 1; 87} 88 89static void 90disable_bp_cb(void * addr, void * sbp, void * proc) { 91 if (((struct breakpoint *)sbp)->enabled) { 92 disable_breakpoint(((struct process *)proc)->pid, sbp); 93 } 94} 95 96void 97disable_all_breakpoints(struct process * proc) { 98 if (proc->breakpoints_enabled) { 99 debug(1, "Disabling breakpoints for pid %u...", proc->pid); 100 dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc); 101 } 102 proc->breakpoints_enabled = 0; 103} 104