breakpoints.c revision bc37326ace5c70e57928c000162cffbcca9afb77
1d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes#include "config.h" 2d44c6b8b090b8b7aa9d971d9e0bfd848732a3071Juan Cespedes 35b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes#include <stdlib.h> 47186e2af704f4458e6383e8a92482594db29b597Juan Cespedes#include <string.h> 55b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes#include <assert.h> 65b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 7f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#ifdef __powerpc__ 8f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#include <sys/ptrace.h> 9f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#endif 10f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes 119294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata#include "breakpoint.h" 12f728123bd75a65a6a1536e198c3c30719e494e71Juan Cespedes#include "common.h" 135b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 14a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatavoid 15a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatabreakpoint_on_hit(struct breakpoint *bp, struct Process *proc) 16a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata{ 17a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata assert(bp != NULL); 18a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata if (bp->cbs != NULL && bp->cbs->on_hit != NULL) 19a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata (bp->cbs->on_hit) (bp, proc); 20a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata} 21a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata 22a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatavoid 23a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machatabreakpoint_on_destroy(struct breakpoint *bp) 24a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata{ 25a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata assert(bp != NULL); 26a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata if (bp->cbs != NULL && bp->cbs->on_destroy != NULL) 27a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata (bp->cbs->on_destroy) (bp); 28a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata} 29a9fd8f45e97edc629bdc218d95ce0d0a9e3de401Petr Machata 305b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes/*****************************************************************************/ 315b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 329294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint * 33fed1e8d33ab050df892a88110e1a316d285ee650Petr Machataaddress2bpstruct(Process *proc, void *addr) 34fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 352662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc != NULL); 362662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc->breakpoints != NULL); 379a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 38cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); 39cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes return dict_find_entry(proc->breakpoints, addr); 405b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 415b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 429294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machatastruct breakpoint * 43a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesinsert_breakpoint(Process *proc, void *addr, 44fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata struct library_symbol *libsym, int enable) 45fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 469294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata struct breakpoint *sbp; 47cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 489a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata Process * leader = proc->leader; 499a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 509a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata /* Only the group leader should be getting the breakpoints and 519a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata * thus have ->breakpoint initialized. */ 529a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader != NULL); 539a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader->breakpoints != NULL); 549a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 55a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch#ifdef __arm__ 56a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch int thumb_mode = (int)addr & 1; 57a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch if (thumb_mode) 58a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch addr = (void *)((int)addr & ~1); 59a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch#endif 60a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch 61cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", proc->pid, addr, libsym ? libsym->name : "NULL"); 62b3f8fef12fccb0914b7b28725f42192c279d31c9Petr Machata debug(1, "symbol=%s, addr=%p", libsym?libsym->name:"(nil)", addr); 635b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 642d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (!addr) 659294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata return NULL; 669a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 672d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (libsym) 689a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand libsym->needs_init = 0; 699a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 709a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata sbp = dict_find_entry(leader->breakpoints, addr); 71fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata if (sbp == NULL) { 72fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata sbp = calloc(1, sizeof(*sbp)); 73fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata if (sbp == NULL) { 749294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata return NULL; /* TODO FIXME XXX: error_mem */ 75cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes } 769a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata dict_enter(leader->breakpoints, addr, sbp); 77cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes sbp->addr = addr; 782d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand sbp->libsym = libsym; 795b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes } 8063184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes#ifdef __arm__ 81a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch sbp->thumb_mode = thumb_mode | proc->thumb_mode; 8263184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes proc->thumb_mode = 0; 8363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes#endif 845b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes sbp->enabled++; 85c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata if (sbp->enabled == 1 && enable) { 86c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata assert(proc->pid != 0); 87f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata enable_breakpoint(proc, sbp); 88c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata } 899294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata 909294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata return sbp; 915b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 925b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 93f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 94fed1e8d33ab050df892a88110e1a316d285ee650Petr Machatadelete_breakpoint(Process *proc, void *addr) 95fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 969294d82f67e20f5f2b61f317ad04f5cb717c7d27Petr Machata struct breakpoint *sbp; 97cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 98cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr); 99cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 1009a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata Process * leader = proc->leader; 1019a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader != NULL); 1029a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 1039a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata sbp = dict_find_entry(leader->breakpoints, addr); 1042d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand assert(sbp); /* FIXME: remove after debugging has been done. */ 1055b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes /* This should only happen on out-of-memory conditions. */ 1062d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (sbp == NULL) 1072d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand return; 1085b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 1095b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes sbp->enabled--; 1102d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (sbp->enabled == 0) 111f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata disable_breakpoint(proc, sbp); 1125b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes assert(sbp->enabled >= 0); 1135b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 1145b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 115f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void 116fed1e8d33ab050df892a88110e1a316d285ee650Petr Machataenable_bp_cb(void *addr, void *sbp, void *proc) 117fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 118cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid); 119bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata if (((struct breakpoint *)sbp)->enabled) 120f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata enable_breakpoint(proc, sbp); 1215b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 1225b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 123f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 124bc37326ace5c70e57928c000162cffbcca9afb77Petr Machataenable_all_breakpoints(Process *proc) 125bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata{ 126cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid); 127f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#ifdef __powerpc__ 12861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata unsigned long a; 12961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata 13061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata /* 13161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata * PPC HACK! (XXX FIXME TODO) 13261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata * If the dynamic linker hasn't populated the PLT then 13361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata * dont enable the breakpoints 13461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata */ 13561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata if (options.libcalls) { 13661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata a = ptrace(PTRACE_PEEKTEXT, proc->pid, 13761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata sym2addr(proc, proc->list_of_symbols), 13861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata 0); 13961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata if (a == 0x0) 14061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata return; 14161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata } 142f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#endif 143f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes 14461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata debug(1, "Enabling breakpoints for pid %u...", proc->pid); 14561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata if (proc->breakpoints) { 14661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata dict_apply_to_all(proc->breakpoints, enable_bp_cb, 14761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata proc); 14861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata } 1491228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#ifdef __mips__ 15061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata { 15161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata /* 15261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata * I'm sure there is a nicer way to do this. We need to 15361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata * insert breakpoints _after_ the child has been started. 15461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata */ 15561196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata struct library_symbol *sym; 15661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata struct library_symbol *new_sym; 15761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata sym=proc->list_of_symbols; 15861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata while(sym){ 15961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata void *addr= sym2addr(proc,sym); 16061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata if(!addr){ 16161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata sym=sym->next; 16261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata continue; 16361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata } 16461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata if(dict_find_entry(proc->breakpoints,addr)){ 165a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes sym=sym->next; 16661196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata continue; 167a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 16861196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata debug(2,"inserting bp %p %s",addr,sym->name); 16961196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1); 17061196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1); 17161196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata new_sym->next=proc->list_of_symbols; 17261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata proc->list_of_symbols=new_sym; 17361196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata insert_breakpoint(proc, addr, new_sym); 17461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata sym=sym->next; 175a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 1765e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 17761196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata#endif 1785e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 1795e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 180f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void 181fed1e8d33ab050df892a88110e1a316d285ee650Petr Machatadisable_bp_cb(void *addr, void *sbp, void *proc) 182fed1e8d33ab050df892a88110e1a316d285ee650Petr Machata{ 183cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid); 184bc37326ace5c70e57928c000162cffbcca9afb77Petr Machata if (((struct breakpoint *)sbp)->enabled) 185f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata disable_breakpoint(proc, sbp); 1865b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 1875b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 188f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 189a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesdisable_all_breakpoints(Process *proc) { 190cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); 1919a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 19261196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc); 1935e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 1947186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 195f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void 196f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesfree_bp_cb(void *addr, void *sbp, void *data) { 197cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "free_bp_cb(sbp=%p)", sbp); 1987186e2af704f4458e6383e8a92482594db29b597Juan Cespedes assert(sbp); 1997186e2af704f4458e6383e8a92482594db29b597Juan Cespedes free(sbp); 2007186e2af704f4458e6383e8a92482594db29b597Juan Cespedes} 2017186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 20202648a119092bb5b64918063521237f257283c72Petr Machatastatic void 20302648a119092bb5b64918063521237f257283c72Petr Machataentry_callback_hit(struct breakpoint *bp, struct Process *proc) 20402648a119092bb5b64918063521237f257283c72Petr Machata{ 20502648a119092bb5b64918063521237f257283c72Petr Machata if (proc == NULL || proc->leader == NULL) 20602648a119092bb5b64918063521237f257283c72Petr Machata return; 20702648a119092bb5b64918063521237f257283c72Petr Machata delete_breakpoint(proc, bp->addr); // xxx 20802648a119092bb5b64918063521237f257283c72Petr Machata reinitialize_breakpoints(proc->leader); 20902648a119092bb5b64918063521237f257283c72Petr Machata} 21002648a119092bb5b64918063521237f257283c72Petr Machata 2111974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machataint 212c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machatabreakpoints_init(Process *proc, int enable) 213c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata{ 214cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); 2152d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (proc->breakpoints) { /* let's remove that struct */ 2167186e2af704f4458e6383e8a92482594db29b597Juan Cespedes dict_apply_to_all(proc->breakpoints, free_bp_cb, NULL); 2177186e2af704f4458e6383e8a92482594db29b597Juan Cespedes dict_clear(proc->breakpoints); 2187186e2af704f4458e6383e8a92482594db29b597Juan Cespedes proc->breakpoints = NULL; 2197186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2202662768efe599f6bb43c4310177e30f56b601bb7Petr Machata 2219a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata /* Only the thread group leader should hold the breakpoints. 2229a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata * (N.B. PID may be set to 0 temporarily when called by 2239a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata * handle_exec). */ 2249a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 2259a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 2262662768efe599f6bb43c4310177e30f56b601bb7Petr Machata proc->breakpoints = dict_init(dict_key2hash_int, 2272662768efe599f6bb43c4310177e30f56b601bb7Petr Machata dict_key_cmp_int); 2287186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 229534e00fcdb63af352414f5bf180ec392157b1a2bPetr Machata destroy_library_symbol_chain(proc->list_of_symbols); 2303d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata proc->list_of_symbols = NULL; 2313d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata 232e84fa00bdabf20f57d1d02d159aa3fcab4e549fePetr Machata GElf_Addr entry; 233ce377d567ccc0b14693619b69ebe0ac6deb0ba90Juan Cespedes if (options.libcalls && proc->filename) { 234e84fa00bdabf20f57d1d02d159aa3fcab4e549fePetr Machata proc->list_of_symbols = read_elf(proc, &entry); 2351974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata if (proc->list_of_symbols == NULL) { 23602648a119092bb5b64918063521237f257283c72Petr Machata fail: 2371974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata /* XXX leak breakpoints */ 2381974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata return -1; 2391974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata } 2401974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata 2417186e2af704f4458e6383e8a92482594db29b597Juan Cespedes if (opt_e) { 2422662768efe599f6bb43c4310177e30f56b601bb7Petr Machata struct library_symbol **tmp1 = &proc->list_of_symbols; 2432d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand while (*tmp1) { 2442d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand struct opt_e_t *tmp2 = opt_e; 2457186e2af704f4458e6383e8a92482594db29b597Juan Cespedes int keep = !opt_e_enable; 2467186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 2472d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand while (tmp2) { 2482662768efe599f6bb43c4310177e30f56b601bb7Petr Machata if (!strcmp((*tmp1)->name, 2492662768efe599f6bb43c4310177e30f56b601bb7Petr Machata tmp2->name)) { 2507186e2af704f4458e6383e8a92482594db29b597Juan Cespedes keep = opt_e_enable; 2517186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2527186e2af704f4458e6383e8a92482594db29b597Juan Cespedes tmp2 = tmp2->next; 2537186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2547186e2af704f4458e6383e8a92482594db29b597Juan Cespedes if (!keep) { 2557186e2af704f4458e6383e8a92482594db29b597Juan Cespedes *tmp1 = (*tmp1)->next; 2567186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } else { 2577186e2af704f4458e6383e8a92482594db29b597Juan Cespedes tmp1 = &((*tmp1)->next); 2587186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2597186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2607186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2617186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 262c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata 26302648a119092bb5b64918063521237f257283c72Petr Machata struct breakpoint *entry_bp 26461196a4a81e77322bf1f3dc609007f5d35a5103aPetr Machata = insert_breakpoint(proc, (void *)(uintptr_t)entry, NULL, 1); 26502648a119092bb5b64918063521237f257283c72Petr Machata if (entry_bp == NULL) { 26602648a119092bb5b64918063521237f257283c72Petr Machata fprintf(stderr, "fail!\n"); 26702648a119092bb5b64918063521237f257283c72Petr Machata goto fail; 26802648a119092bb5b64918063521237f257283c72Petr Machata } 26902648a119092bb5b64918063521237f257283c72Petr Machata 27002648a119092bb5b64918063521237f257283c72Petr Machata static struct bp_callbacks entry_callbacks = { 27102648a119092bb5b64918063521237f257283c72Petr Machata .on_hit = entry_callback_hit, 27202648a119092bb5b64918063521237f257283c72Petr Machata }; 27302648a119092bb5b64918063521237f257283c72Petr Machata entry_bp->cbs = &entry_callbacks; 274c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata 2757186e2af704f4458e6383e8a92482594db29b597Juan Cespedes proc->callstack_depth = 0; 2761974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata return 0; 2777186e2af704f4458e6383e8a92482594db29b597Juan Cespedes} 2789a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 279f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 280a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesreinitialize_breakpoints(Process *proc) { 281cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes struct library_symbol *sym; 282cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 283cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "reinitialize_breakpoints(pid=%d)", proc->pid); 284cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 285cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes sym = proc->list_of_symbols; 2862d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand 2872d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand while (sym) { 2889a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand if (sym->needs_init) { 289c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata insert_breakpoint(proc, sym2addr(proc, sym), sym, 1); 2902d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (sym->needs_init && !sym->is_weak) { 2912d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand fprintf(stderr, 2922d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand "could not re-initialize breakpoint for \"%s\" in file \"%s\"\n", 2932d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand sym->name, proc->filename); 2949a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand exit(1); 2952d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand } 2962d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand } 2979a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand sym = sym->next; 2982d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand } 2999a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand} 300