2 * This file is part of ltrace.
3 * Copyright (C) 2006,2007,2011,2012 Petr Machata, Red Hat Inc.
4 * Copyright (C) 2009 Juan Cespedes
5 * Copyright (C) 1998,2001,2002,2003,2007,2008,2009 Juan Cespedes
6 * Copyright (C) 2006 Ian Wienand
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
33 #include <sys/ptrace.h>
37 #include "breakpoint.h"
40 #include "ltrace-elf.h"
43 #ifndef ARCH_HAVE_TRANSLATE_ADDRESS
45 arch_translate_address_dyn(struct Process *proc,
46 arch_addr_t addr, arch_addr_t *ret)
54 arch_translate_address(struct ltelf *lte,
55 arch_addr_t addr, arch_addr_t *ret)
63 breakpoint_on_hit(struct breakpoint *bp, struct Process *proc)
66 if (bp->cbs != NULL && bp->cbs->on_hit != NULL)
67 (bp->cbs->on_hit)(bp, proc);
71 breakpoint_on_continue(struct breakpoint *bp, struct Process *proc)
74 if (bp->cbs != NULL && bp->cbs->on_continue != NULL)
75 (bp->cbs->on_continue)(bp, proc);
77 continue_after_breakpoint(proc, bp);
81 breakpoint_on_retract(struct breakpoint *bp, struct Process *proc)
84 if (bp->cbs != NULL && bp->cbs->on_retract != NULL)
85 (bp->cbs->on_retract)(bp, proc);
88 /*****************************************************************************/
91 address2bpstruct(Process *proc, void *addr)
94 assert(proc->breakpoints != NULL);
95 assert(proc->leader == proc);
96 debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr);
97 return dict_find_entry(proc->breakpoints, addr);
100 #ifndef ARCH_HAVE_BREAKPOINT_DATA
102 arch_breakpoint_init(struct Process *proc, struct breakpoint *sbp)
108 arch_breakpoint_destroy(struct breakpoint *sbp)
113 arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp)
120 breakpoint_init_base(struct breakpoint *bp, struct Process *proc,
121 arch_addr_t addr, struct library_symbol *libsym)
125 memset(bp->orig_value, 0, sizeof(bp->orig_value));
130 /* On second thought, I don't think we need PROC. All the translation
131 * (arch_translate_address in particular) should be doable using
132 * static lookups of various sections in the ELF file. We shouldn't
133 * need process for anything. */
135 breakpoint_init(struct breakpoint *bp, struct Process *proc,
136 arch_addr_t addr, struct library_symbol *libsym)
138 breakpoint_init_base(bp, proc, addr, libsym);
139 return arch_breakpoint_init(proc, bp);
143 breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs)
146 assert(bp->cbs == NULL);
151 breakpoint_destroy(struct breakpoint *bp)
155 arch_breakpoint_destroy(bp);
159 breakpoint_clone(struct breakpoint *retp, struct Process *new_proc,
160 struct breakpoint *bp, struct Process *old_proc)
162 struct library_symbol *libsym = NULL;
163 if (bp->libsym != NULL) {
164 int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym);
168 breakpoint_init_base(retp, new_proc, bp->addr, libsym);
169 memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value));
170 retp->enabled = bp->enabled;
171 if (arch_breakpoint_clone(retp, bp) < 0)
173 breakpoint_set_callbacks(retp, bp->cbs);
178 breakpoint_turn_on(struct breakpoint *bp, struct Process *proc)
181 if (bp->enabled == 1) {
182 assert(proc->pid != 0);
183 enable_breakpoint(proc, bp);
189 breakpoint_turn_off(struct breakpoint *bp, struct Process *proc)
192 if (bp->enabled == 0)
193 disable_breakpoint(proc, bp);
194 assert(bp->enabled >= 0);
199 insert_breakpoint(struct Process *proc, void *addr,
200 struct library_symbol *libsym)
202 Process *leader = proc->leader;
204 /* Only the group leader should be getting the breakpoints and
205 * thus have ->breakpoint initialized. */
206 assert(leader != NULL);
207 assert(leader->breakpoints != NULL);
209 debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)",
210 proc->pid, addr, libsym ? libsym->name : "NULL");
214 /* XXX what we need to do instead is have a list of
215 * breakpoints that are enabled at this address. The
216 * following works if every breakpoint is the same and there's
217 * no extra data, but that doesn't hold anymore. For now it
218 * will suffice, about the only realistic case where we need
219 * to have more than one breakpoint per address is return from
220 * a recursive library call. */
221 struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr);
223 sbp = malloc(sizeof(*sbp));
225 || breakpoint_init(sbp, proc, addr, libsym) < 0) {
229 if (proc_add_breakpoint(leader, sbp) < 0) {
231 breakpoint_destroy(sbp);
237 if (breakpoint_turn_on(sbp, proc) < 0) {
238 proc_remove_breakpoint(leader, sbp);
246 delete_breakpoint(Process *proc, void *addr)
248 debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr);
250 Process * leader = proc->leader;
251 assert(leader != NULL);
253 struct breakpoint *sbp = dict_find_entry(leader->breakpoints, addr);
255 /* This should only happen on out-of-memory conditions. */
259 if (breakpoint_turn_off(sbp, proc) < 0) {
260 fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n",
261 breakpoint_name(sbp), sbp->addr);
264 if (sbp->enabled == 0) {
265 proc_remove_breakpoint(leader, sbp);
266 breakpoint_destroy(sbp);
272 breakpoint_name(const struct breakpoint *bp)
275 return bp->libsym != NULL ? bp->libsym->name : NULL;
279 breakpoint_library(const struct breakpoint *bp)
282 return bp->libsym != NULL ? bp->libsym->lib : NULL;
286 enable_bp_cb(void *addr, void *sbp, void *proc)
288 debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", ((Process *)proc)->pid);
289 if (((struct breakpoint *)sbp)->enabled)
290 enable_breakpoint(proc, sbp);
294 enable_all_breakpoints(Process *proc)
296 debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid);
298 debug(1, "Enabling breakpoints for pid %u...", proc->pid);
299 if (proc->breakpoints) {
300 dict_apply_to_all(proc->breakpoints, enable_bp_cb,
306 disable_bp_cb(void *addr, void *sbp, void *proc)
308 debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", ((Process *)proc)->pid);
309 if (((struct breakpoint *)sbp)->enabled)
310 disable_breakpoint(proc, sbp);
314 disable_all_breakpoints(Process *proc) {
315 debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid);
316 assert(proc->leader == proc);
317 dict_apply_to_all(proc->breakpoints, disable_bp_cb, proc);
320 /* XXX This is not currently properly supported. On clone, this is
321 * just sliced. Hopefully at the point that clone is done, this
322 * breakpoint is not necessary anymore. If this use case ends up
323 * being important, we need to add a clone and destroy callbacks to
324 * breakpoints, and we should also probably drop arch_breakpoint_data
325 * so that we don't end up with two different customization mechanisms
326 * for one structure. */
327 struct entry_breakpoint {
328 struct breakpoint super;
329 arch_addr_t dyn_addr;
333 entry_breakpoint_on_hit(struct breakpoint *a, struct Process *proc)
335 struct entry_breakpoint *bp = (void *)a;
336 if (proc == NULL || proc->leader == NULL)
338 arch_addr_t dyn_addr = bp->dyn_addr;
339 delete_breakpoint(proc, bp->super.addr);
340 linkmap_init(proc, dyn_addr);
341 arch_dynlink_done(proc);
345 entry_breakpoint_init(struct Process *proc,
346 struct entry_breakpoint *bp, arch_addr_t addr,
350 int err = breakpoint_init(&bp->super, proc, addr, NULL);
354 static struct bp_callbacks entry_callbacks = {
355 .on_hit = entry_breakpoint_on_hit,
357 bp->super.cbs = &entry_callbacks;
358 bp->dyn_addr = lib->dyn_addr;
363 breakpoints_init(Process *proc)
365 debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid);
367 /* XXX breakpoint dictionary should be initialized
368 * outside. Here we just put in breakpoints. */
369 assert(proc->breakpoints != NULL);
371 /* Only the thread group leader should hold the breakpoints. */
372 assert(proc->leader == proc);
374 /* N.B. the following used to be conditional on this, and
375 * maybe it still needs to be. */
376 assert(proc->filename != NULL);
378 struct library *lib = ltelf_read_main_binary(proc, proc->filename);
379 struct entry_breakpoint *entry_bp = NULL;
382 switch (lib != NULL) {
386 proc_remove_library(proc, lib);
387 proc_remove_breakpoint(proc, &entry_bp->super);
389 breakpoint_destroy(&entry_bp->super);
391 library_destroy(lib);
397 entry_bp = malloc(sizeof(*entry_bp));
399 || (entry_breakpoint_init(proc, entry_bp,
400 lib->entry, lib)) < 0) {
402 "Couldn't initialize entry breakpoint for PID %d.\n"
403 "Some tracing events may be missed.\n", proc->pid);
409 if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0)
413 if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0)
416 proc_add_library(proc, lib);
418 proc->callstack_depth = 0;