| Juan Cespedes | d44c6b8 | 1998-09-25 14:48:42 +0200 | [diff] [blame] | 1 | #include "config.h" | 
| Juan Cespedes | d44c6b8 | 1998-09-25 14:48:42 +0200 | [diff] [blame] | 2 |  | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 3 | #include <stdlib.h> | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 4 | #include <string.h> | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 5 | #include <assert.h> | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 6 | #include <error.h> | 
 | 7 | #include <errno.h> | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 8 |  | 
| Juan Cespedes | f1bfe20 | 2002-03-27 00:22:23 +0100 | [diff] [blame] | 9 | #ifdef __powerpc__ | 
 | 10 | #include <sys/ptrace.h> | 
 | 11 | #endif | 
 | 12 |  | 
| Petr Machata | 9294d82 | 2012-02-07 12:35:58 +0100 | [diff] [blame] | 13 | #include "breakpoint.h" | 
| Juan Cespedes | f728123 | 2009-06-25 16:11:21 +0200 | [diff] [blame] | 14 | #include "common.h" | 
| Petr Machata | 366c2f4 | 2012-02-09 19:34:36 +0100 | [diff] [blame] | 15 | #include "proc.h" | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 16 | #include "library.h" | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 17 |  | 
| Petr Machata | a9fd8f4 | 2012-02-07 13:25:56 +0100 | [diff] [blame] | 18 | void | 
 | 19 | breakpoint_on_hit(struct breakpoint *bp, struct Process *proc) | 
 | 20 | { | 
 | 21 | 	assert(bp != NULL); | 
 | 22 | 	if (bp->cbs != NULL && bp->cbs->on_hit != NULL) | 
| Petr Machata | 55ac932 | 2012-03-27 03:07:35 +0200 | [diff] [blame^] | 23 | 		(bp->cbs->on_hit)(bp, proc); | 
 | 24 | } | 
 | 25 |  | 
 | 26 | void | 
 | 27 | breakpoint_on_continue(struct breakpoint *bp, struct Process *proc) | 
 | 28 | { | 
 | 29 | 	assert(bp != NULL); | 
 | 30 | 	if (bp->cbs != NULL && bp->cbs->on_continue != NULL) | 
 | 31 | 		(bp->cbs->on_continue)(bp, proc); | 
 | 32 | 	else | 
 | 33 | 		continue_after_breakpoint(proc, bp); | 
| Petr Machata | a9fd8f4 | 2012-02-07 13:25:56 +0100 | [diff] [blame] | 34 | } | 
 | 35 |  | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 36 | /*****************************************************************************/ | 
 | 37 |  | 
| Petr Machata | 9294d82 | 2012-02-07 12:35:58 +0100 | [diff] [blame] | 38 | struct breakpoint * | 
| Petr Machata | fed1e8d | 2012-02-07 02:06:29 +0100 | [diff] [blame] | 39 | address2bpstruct(Process *proc, void *addr) | 
 | 40 | { | 
| Petr Machata | 2662768 | 2011-07-08 18:15:32 +0200 | [diff] [blame] | 41 | 	assert(proc != NULL); | 
 | 42 | 	assert(proc->breakpoints != NULL); | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame] | 43 | 	assert(proc->leader == proc); | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 44 | 	debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 45 | 	return dict_find_entry(proc->breakpoints, addr); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 46 | } | 
 | 47 |  | 
| Petr Machata | 8cce119 | 2012-03-25 01:37:19 +0100 | [diff] [blame] | 48 | #ifndef ARCH_HAVE_BREAKPOINT_DATA | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 49 | int | 
 | 50 | arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp) | 
 | 51 | { | 
 | 52 | 	return 0; | 
 | 53 | } | 
| Petr Machata | 8cce119 | 2012-03-25 01:37:19 +0100 | [diff] [blame] | 54 |  | 
 | 55 | void | 
 | 56 | arch_breakpoint_destroy(struct breakpoint *sbp) | 
 | 57 | { | 
 | 58 | } | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 59 | #endif | 
 | 60 |  | 
 | 61 | int | 
 | 62 | breakpoint_init(struct breakpoint *bp, struct Process *proc, | 
| Petr Machata | 55ac932 | 2012-03-27 03:07:35 +0200 | [diff] [blame^] | 63 | 		target_address_t addr, struct library_symbol *libsym) | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 64 | { | 
| Petr Machata | 55ac932 | 2012-03-27 03:07:35 +0200 | [diff] [blame^] | 65 | 	bp->cbs = NULL; | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 66 | 	bp->addr = addr; | 
 | 67 | 	memset(bp->orig_value, 0, sizeof(bp->orig_value)); | 
 | 68 | 	bp->enabled = 0; | 
 | 69 | 	bp->libsym = libsym; | 
 | 70 | 	return arch_breakpoint_init(proc, bp); | 
 | 71 | } | 
 | 72 |  | 
| Petr Machata | 8cce119 | 2012-03-25 01:37:19 +0100 | [diff] [blame] | 73 | void | 
| Petr Machata | 55ac932 | 2012-03-27 03:07:35 +0200 | [diff] [blame^] | 74 | breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs) | 
 | 75 | { | 
 | 76 | 	if (bp->cbs != NULL) | 
 | 77 | 		assert(bp->cbs == NULL); | 
 | 78 | 	bp->cbs = cbs; | 
 | 79 | } | 
 | 80 |  | 
 | 81 | void | 
| Petr Machata | 8cce119 | 2012-03-25 01:37:19 +0100 | [diff] [blame] | 82 | breakpoint_destroy(struct breakpoint *bp) | 
 | 83 | { | 
 | 84 | 	if (bp == NULL) | 
 | 85 | 		return; | 
 | 86 |  | 
 | 87 | 	/* XXX I'm not convinced that we need on_destroy.  We already | 
 | 88 | 	 * have arch_breakpoint_destroy, which is necessary as a | 
 | 89 | 	 * counterpart of arch_breakpoint_init in any case.  */ | 
 | 90 | 	if (bp->cbs != NULL && bp->cbs->on_destroy != NULL) | 
 | 91 | 		(bp->cbs->on_destroy) (bp); | 
 | 92 |  | 
 | 93 | 	arch_breakpoint_destroy(bp); | 
 | 94 | } | 
 | 95 |  | 
| Petr Machata | 9294d82 | 2012-02-07 12:35:58 +0100 | [diff] [blame] | 96 | struct breakpoint * | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 97 | insert_breakpoint(Process *proc, void *addr, | 
| Petr Machata | fed1e8d | 2012-02-07 02:06:29 +0100 | [diff] [blame] | 98 | 		  struct library_symbol *libsym, int enable) | 
 | 99 | { | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame] | 100 | 	Process * leader = proc->leader; | 
 | 101 |  | 
 | 102 | 	/* Only the group leader should be getting the breakpoints and | 
 | 103 | 	 * thus have ->breakpoint initialized.  */ | 
 | 104 | 	assert(leader != NULL); | 
 | 105 | 	assert(leader->breakpoints != NULL); | 
 | 106 |  | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 107 | 	debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", proc->pid, addr, libsym ? libsym->name : "NULL"); | 
| Petr Machata | b3f8fef | 2006-11-30 14:45:07 +0100 | [diff] [blame] | 108 | 	debug(1, "symbol=%s, addr=%p", libsym?libsym->name:"(nil)", addr); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 109 |  | 
| Petr Machata | 81c6527 | 2012-03-21 04:57:25 +0100 | [diff] [blame] | 110 | 	if (addr == 0) { | 
 | 111 | 		/* XXX we need a better way to deal with this.  For | 
 | 112 | 		 * now, just abuse errno to carry the error | 
 | 113 | 		 * information.  */ | 
 | 114 | 		errno = EINVAL; | 
| Petr Machata | 9294d82 | 2012-02-07 12:35:58 +0100 | [diff] [blame] | 115 | 		return NULL; | 
| Petr Machata | 81c6527 | 2012-03-21 04:57:25 +0100 | [diff] [blame] | 116 | 	} | 
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 117 |  | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 118 | 	struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr); | 
| Petr Machata | fed1e8d | 2012-02-07 02:06:29 +0100 | [diff] [blame] | 119 | 	if (sbp == NULL) { | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 120 | 		sbp = malloc(sizeof(*sbp)); | 
 | 121 | 		if (sbp == NULL | 
| Petr Machata | 55ac932 | 2012-03-27 03:07:35 +0200 | [diff] [blame^] | 122 | 		    || breakpoint_init(sbp, proc, addr, libsym) < 0 | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 123 | 		    || dict_enter(leader->breakpoints, addr, sbp) < 0) { | 
 | 124 | 			free(sbp); | 
 | 125 | 			return NULL; | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 126 | 		} | 
| Juan Cespedes | cac15c3 | 2003-01-31 18:58:58 +0100 | [diff] [blame] | 127 | 	} | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 128 |  | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 129 | 	sbp->enabled++; | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 130 | 	if (sbp->enabled == 1 && enable) { | 
 | 131 | 		assert(proc->pid != 0); | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 132 | 		enable_breakpoint(proc, sbp); | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 133 | 	} | 
| Petr Machata | 9294d82 | 2012-02-07 12:35:58 +0100 | [diff] [blame] | 134 |  | 
 | 135 | 	return sbp; | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 136 | } | 
 | 137 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 138 | void | 
| Petr Machata | fed1e8d | 2012-02-07 02:06:29 +0100 | [diff] [blame] | 139 | delete_breakpoint(Process *proc, void *addr) | 
 | 140 | { | 
| Petr Machata | 9294d82 | 2012-02-07 12:35:58 +0100 | [diff] [blame] | 141 | 	struct breakpoint *sbp; | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 142 |  | 
 | 143 | 	debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr); | 
 | 144 |  | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame] | 145 | 	Process * leader = proc->leader; | 
 | 146 | 	assert(leader != NULL); | 
 | 147 |  | 
 | 148 | 	sbp = dict_find_entry(leader->breakpoints, addr); | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 149 | 	assert(sbp);		/* FIXME: remove after debugging has been done. */ | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 150 | 	/* This should only happen on out-of-memory conditions. */ | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 151 | 	if (sbp == NULL) | 
 | 152 | 		return; | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 153 |  | 
 | 154 | 	sbp->enabled--; | 
| Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 155 | 	if (sbp->enabled == 0) | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 156 | 		disable_breakpoint(proc, sbp); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 157 | 	assert(sbp->enabled >= 0); | 
 | 158 | } | 
 | 159 |  | 
| Petr Machata | e9aebd6 | 2012-03-25 01:38:53 +0100 | [diff] [blame] | 160 | const char * | 
 | 161 | breakpoint_name(const struct breakpoint *bp) | 
 | 162 | { | 
 | 163 | 	assert(bp != NULL); | 
 | 164 | 	return bp->libsym != NULL ? bp->libsym->name : NULL; | 
 | 165 | } | 
 | 166 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 167 | static void | 
| Petr Machata | fed1e8d | 2012-02-07 02:06:29 +0100 | [diff] [blame] | 168 | enable_bp_cb(void *addr, void *sbp, void *proc) | 
 | 169 | { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 170 | 	debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid); | 
| Petr Machata | bc37326 | 2012-02-07 23:31:15 +0100 | [diff] [blame] | 171 | 	if (((struct breakpoint *)sbp)->enabled) | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 172 | 		enable_breakpoint(proc, sbp); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 173 | } | 
 | 174 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 175 | void | 
| Petr Machata | bc37326 | 2012-02-07 23:31:15 +0100 | [diff] [blame] | 176 | enable_all_breakpoints(Process *proc) | 
 | 177 | { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 178 | 	debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid); | 
| Petr Machata | 61196a4 | 2012-02-07 16:41:03 +0100 | [diff] [blame] | 179 |  | 
 | 180 | 	debug(1, "Enabling breakpoints for pid %u...", proc->pid); | 
 | 181 | 	if (proc->breakpoints) { | 
 | 182 | 		dict_apply_to_all(proc->breakpoints, enable_bp_cb, | 
 | 183 | 				  proc); | 
 | 184 | 	} | 
 | 185 | #ifdef __mips__ | 
 | 186 | 	{ | 
 | 187 | 		/* | 
 | 188 | 		 * I'm sure there is a nicer way to do this. We need to | 
 | 189 | 		 * insert breakpoints _after_ the child has been started. | 
 | 190 | 		 */ | 
 | 191 | 		struct library_symbol *sym; | 
 | 192 | 		struct library_symbol *new_sym; | 
 | 193 | 		sym=proc->list_of_symbols; | 
 | 194 | 		while(sym){ | 
 | 195 | 			void *addr= sym2addr(proc,sym); | 
 | 196 | 			if(!addr){ | 
 | 197 | 				sym=sym->next; | 
 | 198 | 				continue; | 
 | 199 | 			} | 
 | 200 | 			if(dict_find_entry(proc->breakpoints,addr)){ | 
 | 201 | 				sym=sym->next; | 
 | 202 | 				continue; | 
 | 203 | 			} | 
 | 204 | 			debug(2,"inserting bp %p %s",addr,sym->name); | 
 | 205 | 			new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1); | 
 | 206 | 			memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1); | 
 | 207 | 			new_sym->next=proc->list_of_symbols; | 
 | 208 | 			proc->list_of_symbols=new_sym; | 
 | 209 | 			insert_breakpoint(proc, addr, new_sym); | 
 | 210 | 			sym=sym->next; | 
 | 211 | 		} | 
 | 212 | 	} | 
 | 213 | #endif | 
| Juan Cespedes | 5e01f65 | 1998-03-08 22:31:44 +0100 | [diff] [blame] | 214 | } | 
 | 215 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 216 | static void | 
| Petr Machata | fed1e8d | 2012-02-07 02:06:29 +0100 | [diff] [blame] | 217 | disable_bp_cb(void *addr, void *sbp, void *proc) | 
 | 218 | { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 219 | 	debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid); | 
| Petr Machata | bc37326 | 2012-02-07 23:31:15 +0100 | [diff] [blame] | 220 | 	if (((struct breakpoint *)sbp)->enabled) | 
| Petr Machata | f789c9c | 2011-07-09 10:54:27 +0200 | [diff] [blame] | 221 | 		disable_breakpoint(proc, sbp); | 
| Juan Cespedes | 5b3ffdf | 2001-07-02 00:52:45 +0200 | [diff] [blame] | 222 | } | 
 | 223 |  | 
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 224 | void | 
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 225 | disable_all_breakpoints(Process *proc) { | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 226 | 	debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame] | 227 | 	assert(proc->leader == proc); | 
| Petr Machata | 61196a4 | 2012-02-07 16:41:03 +0100 | [diff] [blame] | 228 | 	dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc); | 
| Juan Cespedes | 5e01f65 | 1998-03-08 22:31:44 +0100 | [diff] [blame] | 229 | } | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 230 |  | 
| Petr Machata | 02648a1 | 2012-02-07 13:44:54 +0100 | [diff] [blame] | 231 | static void | 
 | 232 | entry_callback_hit(struct breakpoint *bp, struct Process *proc) | 
 | 233 | { | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 234 | 	fprintf(stderr, "entry_callback_hit\n"); | 
| Petr Machata | 02648a1 | 2012-02-07 13:44:54 +0100 | [diff] [blame] | 235 | 	if (proc == NULL || proc->leader == NULL) | 
 | 236 | 		return; | 
 | 237 | 	delete_breakpoint(proc, bp->addr); // xxx | 
| Petr Machata | 4e2073f | 2012-03-21 05:15:44 +0100 | [diff] [blame] | 238 | 	enable_all_breakpoints(proc); | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 239 |  | 
 | 240 | 	linkmap_init(proc); | 
| Petr Machata | 02648a1 | 2012-02-07 13:44:54 +0100 | [diff] [blame] | 241 | } | 
 | 242 |  | 
| Petr Machata | 1974dbc | 2011-08-19 18:58:01 +0200 | [diff] [blame] | 243 | int | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 244 | breakpoints_init(Process *proc, int enable) | 
 | 245 | { | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 246 | 	fprintf(stderr, "breakpoints_init %d enable=%d\n", proc->pid, enable); | 
| Juan Cespedes | cd8976d | 2009-05-14 13:47:58 +0200 | [diff] [blame] | 247 | 	debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); | 
| Petr Machata | 2662768 | 2011-07-08 18:15:32 +0200 | [diff] [blame] | 248 |  | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 249 | 	/* XXX breakpoint dictionary should be initialized | 
 | 250 | 	 * outside.  Here we just put in breakpoints.  */ | 
 | 251 | 	assert(proc->breakpoints != NULL); | 
 | 252 |  | 
 | 253 | 	/* Only the thread group leader should hold the breakpoints.  */ | 
| Petr Machata | 9a5420c | 2011-07-09 11:21:23 +0200 | [diff] [blame] | 254 | 	assert(proc->leader == proc); | 
 | 255 |  | 
| Juan Cespedes | ce377d5 | 2008-12-16 19:38:10 +0100 | [diff] [blame] | 256 | 	if (options.libcalls && proc->filename) { | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 257 | 		struct library *lib = ltelf_read_main_binary(proc, proc->filename); | 
 | 258 | 		switch (lib != NULL) { | 
| Petr Machata | 02648a1 | 2012-02-07 13:44:54 +0100 | [diff] [blame] | 259 | 		fail: | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 260 | 			proc_remove_library(proc, lib); | 
 | 261 | 			library_destroy(lib); | 
 | 262 | 		case 0: | 
| Petr Machata | 1974dbc | 2011-08-19 18:58:01 +0200 | [diff] [blame] | 263 | 			return -1; | 
 | 264 | 		} | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 265 | 		proc_add_library(proc, lib); | 
 | 266 | 		fprintf(stderr, "note: symbols in %s were not filtered.\n", | 
 | 267 | 			lib->name); | 
| Petr Machata | 1974dbc | 2011-08-19 18:58:01 +0200 | [diff] [blame] | 268 |  | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 269 | 		struct breakpoint *entry_bp | 
 | 270 | 			= insert_breakpoint(proc, lib->entry, NULL, 1); | 
 | 271 | 		if (entry_bp == NULL) { | 
 | 272 | 			error(0, errno, "couldn't insert entry breakpoint"); | 
 | 273 | 			goto fail; | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 274 | 		} | 
| Petr Machata | c7585b6 | 2011-07-08 22:58:12 +0200 | [diff] [blame] | 275 |  | 
| Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 276 | 		fprintf(stderr, "setting entry_callbacks by hand, fix it\n"); | 
 | 277 | 		static struct bp_callbacks entry_callbacks = { | 
 | 278 | 			.on_hit = entry_callback_hit, | 
 | 279 | 		}; | 
 | 280 | 		entry_bp->cbs = &entry_callbacks; | 
| Petr Machata | 02648a1 | 2012-02-07 13:44:54 +0100 | [diff] [blame] | 281 | 	} | 
 | 282 |  | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 283 | 	proc->callstack_depth = 0; | 
| Petr Machata | 1974dbc | 2011-08-19 18:58:01 +0200 | [diff] [blame] | 284 | 	return 0; | 
| Juan Cespedes | 7186e2a | 2003-01-31 19:56:34 +0100 | [diff] [blame] | 285 | } |