breakpoints.c revision 98ff309cdc98857eb30992f108439cb7d7673598
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2006,2007,2011,2012,2013 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 7 * 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. 12 * 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. 17 * 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 21 * 02110-1301 USA 22 */ 23 24#include "config.h" 25 26#include <assert.h> 27#include <errno.h> 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31 32#ifdef __powerpc__ 33#include <sys/ptrace.h> 34#endif 35 36#include "backend.h" 37#include "breakpoint.h" 38#include "debug.h" 39#include "library.h" 40#include "ltrace-elf.h" 41#include "proc.h" 42 43#ifndef ARCH_HAVE_TRANSLATE_ADDRESS 44int 45arch_translate_address_dyn(struct process *proc, 46 arch_addr_t addr, arch_addr_t *ret) 47{ 48 *ret = addr; 49 return 0; 50} 51 52struct ltelf; 53int 54arch_translate_address(struct ltelf *lte, 55 arch_addr_t addr, arch_addr_t *ret) 56{ 57 *ret = addr; 58 return 0; 59} 60#endif 61 62void 63breakpoint_on_hit(struct breakpoint *bp, struct process *proc) 64{ 65 assert(bp != NULL); 66 if (bp->cbs != NULL && bp->cbs->on_hit != NULL) 67 (bp->cbs->on_hit)(bp, proc); 68} 69 70void 71breakpoint_on_continue(struct breakpoint *bp, struct process *proc) 72{ 73 assert(bp != NULL); 74 if (bp->cbs != NULL && bp->cbs->on_continue != NULL) 75 (bp->cbs->on_continue)(bp, proc); 76 else 77 continue_after_breakpoint(proc, bp); 78} 79 80void 81breakpoint_on_retract(struct breakpoint *bp, struct process *proc) 82{ 83 assert(bp != NULL); 84 if (bp->cbs != NULL && bp->cbs->on_retract != NULL) 85 (bp->cbs->on_retract)(bp, proc); 86} 87 88/*****************************************************************************/ 89 90struct breakpoint * 91address2bpstruct(struct process *proc, arch_addr_t addr) 92{ 93 assert(proc != NULL); 94 assert(proc->breakpoints != NULL); 95 assert(proc->leader == proc); 96 debug(DEBUG_FUNCTION, "address2bpstruct(pid=%d, addr=%p)", proc->pid, addr); 97 98 struct breakpoint *found; 99 if (DICT_FIND_VAL(proc->breakpoints, &addr, &found) < 0) 100 return NULL; 101 return found; 102} 103 104#ifndef ARCH_HAVE_BREAKPOINT_DATA 105int 106arch_breakpoint_init(struct process *proc, struct breakpoint *sbp) 107{ 108 return 0; 109} 110 111void 112arch_breakpoint_destroy(struct breakpoint *sbp) 113{ 114} 115 116int 117arch_breakpoint_clone(struct breakpoint *retp, struct breakpoint *sbp) 118{ 119 return 0; 120} 121#endif 122 123static void 124breakpoint_init_base(struct breakpoint *bp, struct process *proc, 125 arch_addr_t addr, struct library_symbol *libsym) 126{ 127 bp->cbs = NULL; 128 bp->addr = addr; 129 memset(bp->orig_value, 0, sizeof(bp->orig_value)); 130 bp->enabled = 0; 131 bp->libsym = libsym; 132} 133 134/* On second thought, I don't think we need PROC. All the translation 135 * (arch_translate_address in particular) should be doable using 136 * static lookups of various sections in the ELF file. We shouldn't 137 * need process for anything. */ 138int 139breakpoint_init(struct breakpoint *bp, struct process *proc, 140 arch_addr_t addr, struct library_symbol *libsym) 141{ 142 breakpoint_init_base(bp, proc, addr, libsym); 143 return arch_breakpoint_init(proc, bp); 144} 145 146void 147breakpoint_set_callbacks(struct breakpoint *bp, struct bp_callbacks *cbs) 148{ 149 if (bp->cbs != NULL) 150 assert(bp->cbs == NULL); 151 bp->cbs = cbs; 152} 153 154void 155breakpoint_destroy(struct breakpoint *bp) 156{ 157 if (bp == NULL) 158 return; 159 arch_breakpoint_destroy(bp); 160} 161 162int 163breakpoint_clone(struct breakpoint *retp, struct process *new_proc, 164 struct breakpoint *bp, struct process *old_proc) 165{ 166 struct library_symbol *libsym = NULL; 167 if (bp->libsym != NULL) { 168 int rc = proc_find_symbol(new_proc, bp->libsym, NULL, &libsym); 169 assert(rc == 0); 170 } 171 172 breakpoint_init_base(retp, new_proc, bp->addr, libsym); 173 memcpy(retp->orig_value, bp->orig_value, sizeof(bp->orig_value)); 174 retp->enabled = bp->enabled; 175 if (arch_breakpoint_clone(retp, bp) < 0) 176 return -1; 177 breakpoint_set_callbacks(retp, bp->cbs); 178 return 0; 179} 180 181int 182breakpoint_turn_on(struct breakpoint *bp, struct process *proc) 183{ 184 bp->enabled++; 185 if (bp->enabled == 1) { 186 assert(proc->pid != 0); 187 enable_breakpoint(proc, bp); 188 } 189 return 0; 190} 191 192int 193breakpoint_turn_off(struct breakpoint *bp, struct process *proc) 194{ 195 bp->enabled--; 196 if (bp->enabled == 0) 197 disable_breakpoint(proc, bp); 198 assert(bp->enabled >= 0); 199 return 0; 200} 201 202struct breakpoint * 203insert_breakpoint(struct process *proc, arch_addr_t addr, 204 struct library_symbol *libsym) 205{ 206 struct process *leader = proc->leader; 207 208 /* Only the group leader should be getting the breakpoints and 209 * thus have ->breakpoint initialized. */ 210 assert(leader != NULL); 211 assert(leader->breakpoints != NULL); 212 213 debug(DEBUG_FUNCTION, "insert_breakpoint(pid=%d, addr=%p, symbol=%s)", 214 proc->pid, addr, libsym ? libsym->name : "NULL"); 215 216 assert(addr != 0); 217 218 /* XXX what we need to do instead is have a list of 219 * breakpoints that are enabled at this address. The 220 * following works if every breakpoint is the same and there's 221 * no extra data, but that doesn't hold anymore. For now it 222 * will suffice, about the only realistic case where we need 223 * to have more than one breakpoint per address is return from 224 * a recursive library call. */ 225 struct breakpoint *bp; 226 if (DICT_FIND_VAL(leader->breakpoints, &addr, &bp) < 0) { 227 bp = malloc(sizeof(*bp)); 228 if (bp == NULL 229 || breakpoint_init(bp, proc, addr, libsym) < 0) { 230 free(bp); 231 return NULL; 232 } 233 if (proc_add_breakpoint(leader, bp) < 0) { 234 fail: 235 breakpoint_destroy(bp); 236 free(bp); 237 return NULL; 238 } 239 } 240 241 if (breakpoint_turn_on(bp, proc) < 0) { 242 proc_remove_breakpoint(leader, bp); 243 goto fail; 244 } 245 246 return bp; 247} 248 249void 250delete_breakpoint(struct process *proc, arch_addr_t addr) 251{ 252 debug(DEBUG_FUNCTION, "delete_breakpoint(pid=%d, addr=%p)", proc->pid, addr); 253 254 struct process *leader = proc->leader; 255 assert(leader != NULL); 256 257 struct breakpoint *sbp = NULL; 258 DICT_FIND_VAL(leader->breakpoints, &addr, &sbp); 259 assert(sbp != NULL); 260 261 if (breakpoint_turn_off(sbp, proc) < 0) { 262 fprintf(stderr, "Couldn't turn off the breakpoint %s@%p\n", 263 breakpoint_name(sbp), sbp->addr); 264 return; 265 } 266 if (sbp->enabled == 0) { 267 proc_remove_breakpoint(leader, sbp); 268 breakpoint_destroy(sbp); 269 free(sbp); 270 } 271} 272 273const char * 274breakpoint_name(const struct breakpoint *bp) 275{ 276 assert(bp != NULL); 277 return bp->libsym != NULL ? bp->libsym->name : NULL; 278} 279 280struct library * 281breakpoint_library(const struct breakpoint *bp) 282{ 283 assert(bp != NULL); 284 return bp->libsym != NULL ? bp->libsym->lib : NULL; 285} 286 287static enum callback_status 288enable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data) 289{ 290 struct process *proc = data; 291 debug(DEBUG_FUNCTION, "enable_bp_cb(pid=%d)", proc->pid); 292 if ((*bpp)->enabled) 293 enable_breakpoint(proc, *bpp); 294 return CBS_CONT; 295} 296 297void 298enable_all_breakpoints(struct process *proc) 299{ 300 debug(DEBUG_FUNCTION, "enable_all_breakpoints(pid=%d)", proc->pid); 301 302 debug(1, "Enabling breakpoints for pid %u...", proc->pid); 303 if (proc->breakpoints != NULL) 304 DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *, 305 NULL, enable_bp_cb, proc); 306} 307 308static enum callback_status 309disable_bp_cb(arch_addr_t *addr, struct breakpoint **bpp, void *data) 310{ 311 struct process *proc = data; 312 debug(DEBUG_FUNCTION, "disable_bp_cb(pid=%d)", proc->pid); 313 if ((*bpp)->enabled) 314 disable_breakpoint(proc, *bpp); 315 return CBS_CONT; 316} 317 318void 319disable_all_breakpoints(struct process *proc) 320{ 321 debug(DEBUG_FUNCTION, "disable_all_breakpoints(pid=%d)", proc->pid); 322 assert(proc->leader == proc); 323 DICT_EACH(proc->breakpoints, arch_addr_t, struct breakpoint *, 324 NULL, disable_bp_cb, proc); 325} 326 327/* XXX This is not currently properly supported. On clone, this is 328 * just sliced. Hopefully at the point that clone is done, this 329 * breakpoint is not necessary anymore. If this use case ends up 330 * being important, we need to add a clone and destroy callbacks to 331 * breakpoints, and we should also probably drop arch_breakpoint_data 332 * so that we don't end up with two different customization mechanisms 333 * for one structure. */ 334struct entry_breakpoint { 335 struct breakpoint super; 336 arch_addr_t dyn_addr; 337}; 338 339static void 340entry_breakpoint_on_hit(struct breakpoint *a, struct process *proc) 341{ 342 struct entry_breakpoint *bp = (void *)a; 343 if (proc == NULL || proc->leader == NULL) 344 return; 345 arch_addr_t dyn_addr = bp->dyn_addr; 346 delete_breakpoint(proc, bp->super.addr); 347 linkmap_init(proc, dyn_addr); 348 arch_dynlink_done(proc); 349} 350 351int 352entry_breakpoint_init(struct process *proc, 353 struct entry_breakpoint *bp, arch_addr_t addr, 354 struct library *lib) 355{ 356 assert(addr != 0); 357 int err = breakpoint_init(&bp->super, proc, addr, NULL); 358 if (err < 0) 359 return err; 360 361 static struct bp_callbacks entry_callbacks = { 362 .on_hit = entry_breakpoint_on_hit, 363 }; 364 bp->super.cbs = &entry_callbacks; 365 bp->dyn_addr = lib->dyn_addr; 366 return 0; 367} 368 369int 370breakpoints_init(struct process *proc) 371{ 372 debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); 373 374 /* XXX breakpoint dictionary should be initialized 375 * outside. Here we just put in breakpoints. */ 376 assert(proc->breakpoints != NULL); 377 378 /* Only the thread group leader should hold the breakpoints. */ 379 assert(proc->leader == proc); 380 381 /* N.B. the following used to be conditional on this, and 382 * maybe it still needs to be. */ 383 assert(proc->filename != NULL); 384 385 struct library *lib = ltelf_read_main_binary(proc, proc->filename); 386 struct entry_breakpoint *entry_bp = NULL; 387 int bp_state = 0; 388 int result = -1; 389 switch ((int)(lib != NULL)) { 390 fail: 391 switch (bp_state) { 392 case 2: 393 proc_remove_library(proc, lib); 394 proc_remove_breakpoint(proc, &entry_bp->super); 395 case 1: 396 breakpoint_destroy(&entry_bp->super); 397 } 398 library_destroy(lib); 399 free(entry_bp); 400 case 0: 401 return result; 402 } 403 404 entry_bp = malloc(sizeof(*entry_bp)); 405 if (entry_bp == NULL 406 || (entry_breakpoint_init(proc, entry_bp, 407 lib->entry, lib)) < 0) { 408 fprintf(stderr, 409 "Couldn't initialize entry breakpoint for PID %d.\n" 410 "Some tracing events may be missed.\n", proc->pid); 411 free(entry_bp); 412 413 } else { 414 ++bp_state; 415 416 if ((result = proc_add_breakpoint(proc, &entry_bp->super)) < 0) 417 goto fail; 418 ++bp_state; 419 420 if ((result = breakpoint_turn_on(&entry_bp->super, proc)) < 0) 421 goto fail; 422 } 423 proc_add_library(proc, lib); 424 425 proc->callstack_depth = 0; 426 return 0; 427} 428