breakpoints.c revision 534e00fcdb63af352414f5bf180ec392157b1a2b
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 11f728123bd75a65a6a1536e198c3c30719e494e71Juan Cespedes#include "common.h" 125b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 135b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes/*****************************************************************************/ 145b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 151dec217e47f998c03c642561d98753c32683985cJuan CespedesBreakpoint * 16a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesaddress2bpstruct(Process *proc, void *addr) { 172662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc != NULL); 182662768efe599f6bb43c4310177e30f56b601bb7Petr Machata assert(proc->breakpoints != NULL); 199a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 20cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); 21cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes return dict_find_entry(proc->breakpoints, addr); 225b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 235b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 249a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienandvoid 25a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesinsert_breakpoint(Process *proc, void *addr, 26c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata struct library_symbol *libsym, int enable) { 271dec217e47f998c03c642561d98753c32683985cJuan Cespedes Breakpoint *sbp; 28cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 299a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata Process * leader = proc->leader; 309a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 319a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata /* Only the group leader should be getting the breakpoints and 329a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata * thus have ->breakpoint initialized. */ 339a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader != NULL); 349a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader->breakpoints != NULL); 359a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 36a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch#ifdef __arm__ 37a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch int thumb_mode = (int)addr & 1; 38a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch if (thumb_mode) 39a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch addr = (void *)((int)addr & ~1); 40a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch#endif 41a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch 42cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", proc->pid, addr, libsym ? libsym->name : "NULL"); 43b3f8fef12fccb0914b7b28725f42192c279d31c9Petr Machata debug(1, "symbol=%s, addr=%p", libsym?libsym->name:"(nil)", addr); 445b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 452d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (!addr) 462d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand return; 479a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 482d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (libsym) 499a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand libsym->needs_init = 0; 509a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 519a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata sbp = dict_find_entry(leader->breakpoints, addr); 52cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes if (!sbp) { 531dec217e47f998c03c642561d98753c32683985cJuan Cespedes sbp = calloc(1, sizeof(Breakpoint)); 54cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes if (!sbp) { 552d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand return; /* TODO FIXME XXX: error_mem */ 56cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes } 579a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata dict_enter(leader->breakpoints, addr, sbp); 58cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes sbp->addr = addr; 592d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand sbp->libsym = libsym; 605b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes } 6163184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes#ifdef __arm__ 62a2ff9d6db878e564caffef8807907aa0faedb7fdZachary T Welch sbp->thumb_mode = thumb_mode | proc->thumb_mode; 6363184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes proc->thumb_mode = 0; 6463184be8c577f5799e44db2a4e312a8240ad7751Juan Cespedes#endif 655b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes sbp->enabled++; 66c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata if (sbp->enabled == 1 && enable) { 67c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata assert(proc->pid != 0); 68f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata enable_breakpoint(proc, sbp); 69c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata } 705b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 715b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 72f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 73a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesdelete_breakpoint(Process *proc, void *addr) { 74cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes Breakpoint *sbp; 75cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 76cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr); 77cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 789a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata Process * leader = proc->leader; 799a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(leader != NULL); 809a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 819a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata sbp = dict_find_entry(leader->breakpoints, addr); 822d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand assert(sbp); /* FIXME: remove after debugging has been done. */ 835b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes /* This should only happen on out-of-memory conditions. */ 842d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (sbp == NULL) 852d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand return; 865b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 875b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes sbp->enabled--; 882d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (sbp->enabled == 0) 89f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata disable_breakpoint(proc, sbp); 905b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes assert(sbp->enabled >= 0); 915b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 925b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 93f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void 94f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesenable_bp_cb(void *addr, void *sbp, void *proc) { 95cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid); 961dec217e47f998c03c642561d98753c32683985cJuan Cespedes if (((Breakpoint *)sbp)->enabled) { 97f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata enable_breakpoint(proc, sbp); 98cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes } 995b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 1005b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 101f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 102a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesenable_all_breakpoints(Process *proc) { 103cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid); 1045e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (proc->breakpoints_enabled <= 0) { 105f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#ifdef __powerpc__ 106f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes unsigned long a; 107f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes 108f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes /* 109f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes * PPC HACK! (XXX FIXME TODO) 110f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes * If the dynamic linker hasn't populated the PLT then 111f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes * dont enable the breakpoints 112f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes */ 113ce377d567ccc0b14693619b69ebe0ac6deb0ba90Juan Cespedes if (options.libcalls) { 1142d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand a = ptrace(PTRACE_PEEKTEXT, proc->pid, 11576c61f15d7989bf7adffed2e46a44c34a80bd927Paul Gilliam sym2addr(proc, proc->list_of_symbols), 1162d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand 0); 117de5a7eb873c05a698e4267b554e25124dc92e7f4Juan Cespedes if (a == 0x0) 118de5a7eb873c05a698e4267b554e25124dc92e7f4Juan Cespedes return; 119de5a7eb873c05a698e4267b554e25124dc92e7f4Juan Cespedes } 120f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes#endif 121f1bfe203f5f1c0e11a614f9d593a68406f5cb47eJuan Cespedes 122cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes debug(1, "Enabling breakpoints for pid %u...", proc->pid); 123a0ccf39a68c0fcdf2165bde0f9b70ed12fc61cd8Juan Cespedes if (proc->breakpoints) { 1242d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand dict_apply_to_all(proc->breakpoints, enable_bp_cb, 1252d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand proc); 126a0ccf39a68c0fcdf2165bde0f9b70ed12fc61cd8Juan Cespedes } 1271228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#ifdef __mips__ 128a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes { 1295c682047d0b03f53dc05d3bd80181e7f82121779Juan Cespedes /* 1305c682047d0b03f53dc05d3bd80181e7f82121779Juan Cespedes * I'm sure there is a nicer way to do this. We need to 1315c682047d0b03f53dc05d3bd80181e7f82121779Juan Cespedes * insert breakpoints _after_ the child has been started. 1325c682047d0b03f53dc05d3bd80181e7f82121779Juan Cespedes */ 133a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes struct library_symbol *sym; 134a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes struct library_symbol *new_sym; 135a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes sym=proc->list_of_symbols; 136a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes while(sym){ 137a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes void *addr= sym2addr(proc,sym); 138a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes if(!addr){ 139a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes sym=sym->next; 140a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes continue; 141a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 142a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes if(dict_find_entry(proc->breakpoints,addr)){ 143a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes sym=sym->next; 144a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes continue; 145a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 146a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes debug(2,"inserting bp %p %s",addr,sym->name); 1474795087c406008f63de933755c87851acd6b9806Arnaud Patard new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1); 1484795087c406008f63de933755c87851acd6b9806Arnaud Patard memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1); 149a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes new_sym->next=proc->list_of_symbols; 150a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes proc->list_of_symbols=new_sym; 151a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes insert_breakpoint(proc, addr, new_sym); 152a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes sym=sym->next; 153a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 154a413e5b8880de643a83ad124d078091c0956fe1dJuan Cespedes } 1551228a91e6560c5e5ac4fdd051adc9b34bf9fc047Eric Vaitl#endif 1565e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 1575e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes proc->breakpoints_enabled = 1; 1585e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 1595e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes 160f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void 161f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesdisable_bp_cb(void *addr, void *sbp, void *proc) { 162cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid); 1631dec217e47f998c03c642561d98753c32683985cJuan Cespedes if (((Breakpoint *)sbp)->enabled) { 164f789c9c0d1f3301afad66e5f0520b9093665f242Petr Machata disable_breakpoint(proc, sbp); 165cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes } 1665b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes} 1675b3ffdf2e696273d38434ff7b3c26349fff5a0eaJuan Cespedes 168f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 169a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesdisable_all_breakpoints(Process *proc) { 170cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); 1719a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 1725e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes if (proc->breakpoints_enabled) { 173cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes debug(1, "Disabling breakpoints for pid %u...", proc->pid); 174cac15c3f170b5ec2cc6304c8c0763a78103e1778Juan Cespedes dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc); 1755e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes } 1765e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes proc->breakpoints_enabled = 0; 1775e01f654d83a95f2acffa86df57a4c2db9b0cae9Juan Cespedes} 1787186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 179f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesstatic void 180f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesfree_bp_cb(void *addr, void *sbp, void *data) { 181cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "free_bp_cb(sbp=%p)", sbp); 1827186e2af704f4458e6383e8a92482594db29b597Juan Cespedes assert(sbp); 1837186e2af704f4458e6383e8a92482594db29b597Juan Cespedes free(sbp); 1847186e2af704f4458e6383e8a92482594db29b597Juan Cespedes} 1857186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 1861974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machataint 187c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machatabreakpoints_init(Process *proc, int enable) 188c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata{ 1892d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand struct library_symbol *sym; 1907186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 191cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); 1922d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (proc->breakpoints) { /* let's remove that struct */ 1937186e2af704f4458e6383e8a92482594db29b597Juan Cespedes dict_apply_to_all(proc->breakpoints, free_bp_cb, NULL); 1947186e2af704f4458e6383e8a92482594db29b597Juan Cespedes dict_clear(proc->breakpoints); 1957186e2af704f4458e6383e8a92482594db29b597Juan Cespedes proc->breakpoints = NULL; 1967186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 1972662768efe599f6bb43c4310177e30f56b601bb7Petr Machata 1989a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata /* Only the thread group leader should hold the breakpoints. 1999a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata * (N.B. PID may be set to 0 temporarily when called by 2009a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata * handle_exec). */ 2019a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata assert(proc->leader == proc); 2029a5420c82a2fd81681572a2e3859ea1671c3bdedPetr Machata 2032662768efe599f6bb43c4310177e30f56b601bb7Petr Machata proc->breakpoints = dict_init(dict_key2hash_int, 2042662768efe599f6bb43c4310177e30f56b601bb7Petr Machata dict_key_cmp_int); 2057186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 206534e00fcdb63af352414f5bf180ec392157b1a2bPetr Machata destroy_library_symbol_chain(proc->list_of_symbols); 2073d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata proc->list_of_symbols = NULL; 2083d7e4b8d6119c1cda159e2665b40b6dcd4052e85Petr Machata 209ce377d567ccc0b14693619b69ebe0ac6deb0ba90Juan Cespedes if (options.libcalls && proc->filename) { 2109a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand proc->list_of_symbols = read_elf(proc); 2111974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata if (proc->list_of_symbols == NULL) { 2121974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata /* XXX leak breakpoints */ 2131974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata return -1; 2141974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata } 2151974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata 2167186e2af704f4458e6383e8a92482594db29b597Juan Cespedes if (opt_e) { 2172662768efe599f6bb43c4310177e30f56b601bb7Petr Machata struct library_symbol **tmp1 = &proc->list_of_symbols; 2182d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand while (*tmp1) { 2192d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand struct opt_e_t *tmp2 = opt_e; 2207186e2af704f4458e6383e8a92482594db29b597Juan Cespedes int keep = !opt_e_enable; 2217186e2af704f4458e6383e8a92482594db29b597Juan Cespedes 2222d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand while (tmp2) { 2232662768efe599f6bb43c4310177e30f56b601bb7Petr Machata if (!strcmp((*tmp1)->name, 2242662768efe599f6bb43c4310177e30f56b601bb7Petr Machata tmp2->name)) { 2257186e2af704f4458e6383e8a92482594db29b597Juan Cespedes keep = opt_e_enable; 2267186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2277186e2af704f4458e6383e8a92482594db29b597Juan Cespedes tmp2 = tmp2->next; 2287186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2297186e2af704f4458e6383e8a92482594db29b597Juan Cespedes if (!keep) { 2307186e2af704f4458e6383e8a92482594db29b597Juan Cespedes *tmp1 = (*tmp1)->next; 2317186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } else { 2327186e2af704f4458e6383e8a92482594db29b597Juan Cespedes tmp1 = &((*tmp1)->next); 2337186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2347186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2357186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 2367186e2af704f4458e6383e8a92482594db29b597Juan Cespedes } 237c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata 238c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata for (sym = proc->list_of_symbols; sym; sym = sym->next) 239c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata insert_breakpoint(proc, sym2addr(proc, sym), sym, enable); 240c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata 2417186e2af704f4458e6383e8a92482594db29b597Juan Cespedes proc->callstack_depth = 0; 2427186e2af704f4458e6383e8a92482594db29b597Juan Cespedes proc->breakpoints_enabled = -1; 2431974dbccbf10a2dd8e06724d2fb4eb61fd91076aPetr Machata return 0; 2447186e2af704f4458e6383e8a92482594db29b597Juan Cespedes} 2459a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand 246f13505251e6402460f6cc7ec84e0d8ca91607b4fJuan Cespedesvoid 247a8909f71e1421949c960f287217be6c42c286c0fJuan Cespedesreinitialize_breakpoints(Process *proc) { 248cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes struct library_symbol *sym; 249cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 250cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes debug(DEBUG_FUNCTION, "reinitialize_breakpoints(pid=%d)", proc->pid); 251cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes 252cd8976dbee947f152c3a322503a1063c6359da76Juan Cespedes sym = proc->list_of_symbols; 2532d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand 2542d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand while (sym) { 2559a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand if (sym->needs_init) { 256c7585b60235268e1f62bd91c5f040ef6df6e0ef3Petr Machata insert_breakpoint(proc, sym2addr(proc, sym), sym, 1); 2572d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand if (sym->needs_init && !sym->is_weak) { 2582d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand fprintf(stderr, 2592d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand "could not re-initialize breakpoint for \"%s\" in file \"%s\"\n", 2602d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand sym->name, proc->filename); 2619a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand exit(1); 2622d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand } 2632d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand } 2649a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand sym = sym->next; 2652d45b1a8e26a36a9f85dc49e721c4390ca93dc40Ian Wienand } 2669a2ad351a1c3215dc596ff3e2e3fd4bc24445a6bIan Wienand} 267