proc.c revision 165b566a50b2bd560af3bd9649e456915397066b
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. 4 * Copyright (C) 2010 Joe Damato 5 * Copyright (C) 1998,2009 Juan Cespedes 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 */ 22 23#include "config.h" 24 25#include <sys/types.h> 26#include <assert.h> 27#include <errno.h> 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31 32#if defined(HAVE_LIBUNWIND) 33#include <libunwind.h> 34#include <libunwind-ptrace.h> 35#endif /* defined(HAVE_LIBUNWIND) */ 36 37#include "backend.h" 38#include "breakpoint.h" 39#include "debug.h" 40#include "fetch.h" 41#include "proc.h" 42#include "value_dict.h" 43 44#ifndef ARCH_HAVE_PROCESS_DATA 45int 46arch_process_init(struct Process *proc) 47{ 48 return 0; 49} 50 51void 52arch_process_destroy(struct Process *proc) 53{ 54} 55 56int 57arch_process_clone(struct Process *retp, struct Process *proc) 58{ 59 return 0; 60} 61 62int 63arch_process_exec(struct Process *proc) 64{ 65 return 0; 66} 67#endif 68 69#ifndef OS_HAVE_PROCESS_DATA 70int 71os_process_init(struct Process *proc) 72{ 73 return 0; 74} 75 76void 77os_process_destroy(struct Process *proc) 78{ 79} 80 81int 82os_process_clone(struct Process *retp, struct Process *proc) 83{ 84 return 0; 85} 86 87int 88os_process_exec(struct Process *proc) 89{ 90 return 0; 91} 92#endif 93 94#ifndef ARCH_HAVE_DYNLINK_DONE 95void 96arch_dynlink_done(struct Process *proc) 97{ 98} 99#endif 100 101static void add_process(struct Process *proc, int was_exec); 102static void unlist_process(struct Process *proc); 103 104static void 105destroy_unwind(struct Process *proc) 106{ 107#if defined(HAVE_LIBUNWIND) 108 _UPT_destroy(proc->unwind_priv); 109 unw_destroy_addr_space(proc->unwind_as); 110#endif /* defined(HAVE_LIBUNWIND) */ 111} 112 113static int 114process_bare_init(struct Process *proc, const char *filename, 115 pid_t pid, int was_exec) 116{ 117 if (!was_exec) { 118 memset(proc, 0, sizeof(*proc)); 119 120 proc->filename = strdup(filename); 121 if (proc->filename == NULL) { 122 fail: 123 free(proc->filename); 124 if (proc->breakpoints != NULL) 125 dict_clear(proc->breakpoints); 126 return -1; 127 } 128 } 129 130 /* Add process so that we know who the leader is. */ 131 proc->pid = pid; 132 add_process(proc, was_exec); 133 if (proc->leader == NULL) 134 goto fail; 135 136 if (proc->leader == proc) { 137 proc->breakpoints = dict_init(target_address_hash, 138 target_address_cmp); 139 if (proc->breakpoints == NULL) 140 goto fail; 141 } else { 142 proc->breakpoints = NULL; 143 } 144 145#if defined(HAVE_LIBUNWIND) 146 proc->unwind_priv = _UPT_create(pid); 147 proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0); 148#endif /* defined(HAVE_LIBUNWIND) */ 149 150 return 0; 151} 152 153static void 154process_bare_destroy(struct Process *proc, int was_exec) 155{ 156 dict_clear(proc->breakpoints); 157 if (!was_exec) { 158 free(proc->filename); 159 unlist_process(proc); 160 destroy_unwind(proc); 161 } 162} 163 164static int 165process_init_main(struct Process *proc) 166{ 167 if (breakpoints_init(proc) < 0) { 168 fprintf(stderr, "failed to init breakpoints %d\n", 169 proc->pid); 170 return -1; 171 } 172 173 return 0; 174} 175 176int 177process_init(struct Process *proc, const char *filename, pid_t pid) 178{ 179 if (process_bare_init(proc, filename, pid, 0) < 0) { 180 fail: 181 fprintf(stderr, "failed to initialize process %d: %s\n", 182 pid, strerror(errno)); 183 return -1; 184 } 185 186 if (os_process_init(proc) < 0) { 187 process_bare_destroy(proc, 0); 188 goto fail; 189 } 190 191 if (arch_process_init(proc) < 0) { 192 os_process_destroy(proc); 193 process_bare_destroy(proc, 0); 194 goto fail; 195 } 196 197 if (proc->leader != proc) 198 return 0; 199 if (process_init_main(proc) < 0) { 200 process_bare_destroy(proc, 0); 201 goto fail; 202 } 203 return 0; 204} 205 206static enum callback_status 207destroy_breakpoint_cb(struct Process *proc, struct breakpoint *bp, void *data) 208{ 209 breakpoint_destroy(bp); 210 free(bp); 211 return CBS_CONT; 212} 213 214// XXX see comment in handle_event.c 215void callstack_pop(struct Process *proc); 216 217static void 218private_process_destroy(struct Process *proc, int was_exec) 219{ 220 /* Pop remaining stack elements. */ 221 while (proc->callstack_depth > 0) { 222 /* When this is called just before a process is 223 * destroyed, the breakpoints should either have been 224 * retracted by now, or were killed by exec. In any 225 * case, it's safe to pretend that there are no 226 * breakpoints associated with the stack elements, so 227 * that stack_pop doesn't attempt to destroy them. */ 228 size_t i = proc->callstack_depth - 1; 229 if (!proc->callstack[i].is_syscall) 230 proc->callstack[i].return_addr = 0; 231 232 callstack_pop(proc); 233 } 234 235 if (!was_exec) 236 free(proc->filename); 237 238 /* Libraries and symbols. This is only relevant in 239 * leader. */ 240 struct library *lib; 241 for (lib = proc->libraries; lib != NULL; ) { 242 struct library *next = lib->next; 243 library_destroy(lib); 244 free(lib); 245 lib = next; 246 } 247 proc->libraries = NULL; 248 249 /* Breakpoints. */ 250 if (proc->breakpoints != NULL) { 251 proc_each_breakpoint(proc, NULL, destroy_breakpoint_cb, NULL); 252 dict_clear(proc->breakpoints); 253 proc->breakpoints = NULL; 254 } 255 256 destroy_unwind(proc); 257} 258 259void 260process_destroy(struct Process *proc) 261{ 262 arch_process_destroy(proc); 263 os_process_destroy(proc); 264 private_process_destroy(proc, 0); 265} 266 267int 268process_exec(struct Process *proc) 269{ 270 /* Call exec handlers first, before we destroy the main 271 * state. */ 272 if (arch_process_exec(proc) < 0 273 || os_process_exec(proc) < 0) 274 return -1; 275 276 private_process_destroy(proc, 1); 277 278 if (process_bare_init(proc, NULL, proc->pid, 1) < 0) 279 return -1; 280 if (process_init_main(proc) < 0) { 281 process_bare_destroy(proc, 1); 282 return -1; 283 } 284 return 0; 285} 286 287struct Process * 288open_program(const char *filename, pid_t pid) 289{ 290 assert(pid != 0); 291 struct Process *proc = malloc(sizeof(*proc)); 292 if (proc == NULL || process_init(proc, filename, pid) < 0) { 293 free(proc); 294 return NULL; 295 } 296 return proc; 297} 298 299struct clone_single_bp_data { 300 struct Process *old_proc; 301 struct Process *new_proc; 302 int error; 303}; 304 305static void 306clone_single_bp(void *key, void *value, void *u) 307{ 308 struct breakpoint *bp = value; 309 struct clone_single_bp_data *data = u; 310 311 data->error = 0; 312 struct breakpoint *clone = malloc(sizeof(*clone)); 313 if (clone == NULL 314 || breakpoint_clone(clone, data->new_proc, 315 bp, data->old_proc) < 0) { 316 fail: 317 free(clone); 318 data->error = -1; 319 } 320 if (proc_add_breakpoint(data->new_proc->leader, clone) < 0) { 321 breakpoint_destroy(clone); 322 goto fail; 323 } 324} 325 326int 327process_clone(struct Process *retp, struct Process *proc, pid_t pid) 328{ 329 if (process_bare_init(retp, proc->filename, pid, 0) < 0) { 330 fail1: 331 fprintf(stderr, "failed to clone process %d->%d : %s\n", 332 proc->pid, pid, strerror(errno)); 333 return -1; 334 } 335 336 retp->tracesysgood = proc->tracesysgood; 337 retp->e_machine = proc->e_machine; 338 retp->e_class = proc->e_class; 339 340 /* For non-leader processes, that's all we need to do. */ 341 if (retp->leader != retp) 342 return 0; 343 344 /* Clone symbols first so that we can clone and relink 345 * breakpoints. */ 346 struct library *lib; 347 struct library **nlibp = &retp->libraries; 348 for (lib = proc->libraries; lib != NULL; lib = lib->next) { 349 *nlibp = malloc(sizeof(**nlibp)); 350 if (*nlibp == NULL 351 || library_clone(*nlibp, lib) < 0) { 352 fail2: 353 process_bare_destroy(retp, 0); 354 355 /* Error when cloning. Unroll what was done. */ 356 for (lib = retp->libraries; lib != NULL; ) { 357 struct library *next = lib->next; 358 library_destroy(lib); 359 free(lib); 360 lib = next; 361 } 362 goto fail1; 363 } 364 365 nlibp = &(*nlibp)->next; 366 } 367 368 /* Now clone breakpoints. Symbol relinking is done in 369 * clone_single_bp. */ 370 struct clone_single_bp_data data = { 371 .old_proc = proc, 372 .new_proc = retp, 373 .error = 0, 374 }; 375 dict_apply_to_all(proc->breakpoints, &clone_single_bp, &data); 376 if (data.error < 0) 377 goto fail2; 378 379 /* And finally the call stack. */ 380 memcpy(retp->callstack, proc->callstack, sizeof(retp->callstack)); 381 retp->callstack_depth = proc->callstack_depth; 382 383 size_t i; 384 for (i = 0; i < retp->callstack_depth; ++i) { 385 struct fetch_context *ctx = retp->callstack[i].fetch_context; 386 if (ctx != NULL) { 387 struct fetch_context *nctx = fetch_arg_clone(retp, ctx); 388 if (nctx == NULL) { 389 size_t j; 390 fail3: 391 for (j = 0; j < i; ++j) { 392 nctx = retp->callstack[i].fetch_context; 393 fetch_arg_done(nctx); 394 retp->callstack[i].fetch_context = NULL; 395 } 396 goto fail2; 397 } 398 retp->callstack[i].fetch_context = nctx; 399 } 400 401 struct value_dict *args = retp->callstack[i].arguments; 402 if (args != NULL) { 403 struct value_dict *nargs = malloc(sizeof(*nargs)); 404 if (nargs == NULL 405 || val_dict_clone(nargs, args) < 0) { 406 size_t j; 407 fail4: 408 for (j = 0; j < i; ++j) { 409 nargs = retp->callstack[i].arguments; 410 val_dict_destroy(nargs); 411 free(nargs); 412 retp->callstack[i].arguments = NULL; 413 } 414 415 /* Pretend that this round went well, 416 * so that fail3 frees I-th 417 * fetch_context. */ 418 ++i; 419 goto fail3; 420 } 421 retp->callstack[i].arguments = nargs; 422 } 423 424 /* If it's not a syscall, we need to find the 425 * corresponding library symbol in the cloned 426 * library. */ 427 if (!elem->is_syscall && elem->c_un.libfunc != NULL) { 428 struct library_symbol *libfunc = elem->c_un.libfunc; 429 int rc = proc_find_symbol(retp, libfunc, 430 NULL, &elem->c_un.libfunc); 431 assert(rc == 0); 432 } 433 } 434 435 if (os_process_clone(retp, proc) < 0 436 || arch_process_clone(retp, proc) < 0) 437 goto fail4; 438 439 return 0; 440} 441 442static int 443open_one_pid(pid_t pid) 444{ 445 Process *proc; 446 char *filename; 447 debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid); 448 449 /* Get the filename first. Should the trace_pid fail, we can 450 * easily free it, untracing is more work. */ 451 if ((filename = pid2name(pid)) == NULL 452 || trace_pid(pid) < 0) { 453 fail: 454 free(filename); 455 return -1; 456 } 457 458 proc = open_program(filename, pid); 459 if (proc == NULL) 460 goto fail; 461 free(filename); 462 trace_set_options(proc); 463 464 return 0; 465} 466 467static enum callback_status 468start_one_pid(Process * proc, void * data) 469{ 470 continue_process(proc->pid); 471 return CBS_CONT; 472} 473 474void 475open_pid(pid_t pid) 476{ 477 debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid); 478 /* If we are already tracing this guy, we should be seeing all 479 * his children via normal tracing route. */ 480 if (pid2proc(pid) != NULL) 481 return; 482 483 /* First, see if we can attach the requested PID itself. */ 484 if (open_one_pid(pid)) { 485 fprintf(stderr, "Cannot attach to pid %u: %s\n", 486 pid, strerror(errno)); 487 trace_fail_warning(pid); 488 return; 489 } 490 491 /* Now attach to all tasks that belong to that PID. There's a 492 * race between process_tasks and open_one_pid. So when we 493 * fail in open_one_pid below, we just do another round. 494 * Chances are that by then that PID will have gone away, and 495 * that's why we have seen the failure. The processes that we 496 * manage to open_one_pid are stopped, so we should eventually 497 * reach a point where process_tasks doesn't give any new 498 * processes (because there's nobody left to produce 499 * them). */ 500 size_t old_ntasks = 0; 501 int have_all; 502 while (1) { 503 pid_t *tasks; 504 size_t ntasks; 505 size_t i; 506 507 if (process_tasks(pid, &tasks, &ntasks) < 0) { 508 fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n", 509 pid, strerror(errno)); 510 break; 511 } 512 513 have_all = 1; 514 for (i = 0; i < ntasks; ++i) 515 if (pid2proc(tasks[i]) == NULL 516 && open_one_pid(tasks[i])) 517 have_all = 0; 518 519 free(tasks); 520 521 if (have_all && old_ntasks == ntasks) 522 break; 523 old_ntasks = ntasks; 524 } 525 526 struct Process *leader = pid2proc(pid)->leader; 527 528 /* XXX Is there a way to figure out whether _start has 529 * actually already been hit? */ 530 arch_dynlink_done(leader); 531 532 /* Done. Continue everyone. */ 533 each_task(leader, NULL, start_one_pid, NULL); 534} 535 536static enum callback_status 537find_proc(Process * proc, void * data) 538{ 539 pid_t pid = (pid_t)(uintptr_t)data; 540 return proc->pid == pid ? CBS_STOP : CBS_CONT; 541} 542 543Process * 544pid2proc(pid_t pid) { 545 return each_process(NULL, &find_proc, (void *)(uintptr_t)pid); 546} 547 548static Process * list_of_processes = NULL; 549 550static void 551unlist_process(Process * proc) 552{ 553 Process *tmp; 554 555 if (list_of_processes == proc) { 556 list_of_processes = list_of_processes->next; 557 return; 558 } 559 560 for (tmp = list_of_processes; ; tmp = tmp->next) { 561 /* If the following assert fails, the process wasn't 562 * in the list. */ 563 assert(tmp->next != NULL); 564 565 if (tmp->next == proc) { 566 tmp->next = tmp->next->next; 567 return; 568 } 569 } 570} 571 572struct Process * 573each_process(struct Process *start_after, 574 enum callback_status(*cb)(struct Process *proc, void *data), 575 void *data) 576{ 577 struct Process *it = start_after == NULL ? list_of_processes 578 : start_after->next; 579 580 while (it != NULL) { 581 /* Callback might call remove_process. */ 582 struct Process *next = it->next; 583 switch ((*cb)(it, data)) { 584 case CBS_FAIL: 585 /* XXX handle me */ 586 case CBS_STOP: 587 return it; 588 case CBS_CONT: 589 break; 590 } 591 it = next; 592 } 593 return NULL; 594} 595 596Process * 597each_task(struct Process *proc, struct Process *start_after, 598 enum callback_status(*cb)(struct Process *proc, void *data), 599 void *data) 600{ 601 assert(proc != NULL); 602 struct Process *it = start_after == NULL ? proc->leader 603 : start_after->next; 604 605 if (it != NULL) { 606 struct Process *leader = it->leader; 607 while (it != NULL && it->leader == leader) { 608 /* Callback might call remove_process. */ 609 struct Process *next = it->next; 610 switch ((*cb)(it, data)) { 611 case CBS_FAIL: 612 /* XXX handle me */ 613 case CBS_STOP: 614 return it; 615 case CBS_CONT: 616 break; 617 } 618 it = next; 619 } 620 } 621 return NULL; 622} 623 624static void 625add_process(struct Process *proc, int was_exec) 626{ 627 Process ** leaderp = &list_of_processes; 628 if (proc->pid) { 629 pid_t tgid = process_leader(proc->pid); 630 if (tgid == 0) 631 /* Must have been terminated before we managed 632 * to fully attach. */ 633 return; 634 if (tgid == proc->pid) 635 proc->leader = proc; 636 else { 637 Process * leader = pid2proc(tgid); 638 proc->leader = leader; 639 if (leader != NULL) 640 leaderp = &leader->next; 641 } 642 } 643 644 if (!was_exec) { 645 proc->next = *leaderp; 646 *leaderp = proc; 647 } 648} 649 650void 651change_process_leader(Process * proc, Process * leader) 652{ 653 Process ** leaderp = &list_of_processes; 654 if (proc->leader == leader) 655 return; 656 657 assert(leader != NULL); 658 unlist_process(proc); 659 if (proc != leader) 660 leaderp = &leader->next; 661 662 proc->leader = leader; 663 proc->next = *leaderp; 664 *leaderp = proc; 665} 666 667static enum callback_status 668clear_leader(struct Process *proc, void *data) 669{ 670 debug(DEBUG_FUNCTION, "detach_task %d from leader %d", 671 proc->pid, proc->leader->pid); 672 proc->leader = NULL; 673 return CBS_CONT; 674} 675 676void 677remove_process(Process *proc) 678{ 679 debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid); 680 681 if (proc->leader == proc) 682 each_task(proc, NULL, &clear_leader, NULL); 683 684 unlist_process(proc); 685 process_removed(proc); 686 process_destroy(proc); 687 free(proc); 688} 689 690void 691install_event_handler(Process *proc, struct event_handler *handler) 692{ 693 debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler); 694 assert(proc->event_handler == NULL); 695 proc->event_handler = handler; 696} 697 698void 699destroy_event_handler(Process * proc) 700{ 701 struct event_handler *handler = proc->event_handler; 702 debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler); 703 assert(handler != NULL); 704 if (handler->destroy != NULL) 705 handler->destroy(handler); 706 free(handler); 707 proc->event_handler = NULL; 708} 709 710static int 711breakpoint_for_symbol(struct library_symbol *libsym, struct Process *proc) 712{ 713 arch_addr_t bp_addr; 714 assert(proc->leader == proc); 715 716 /* Don't enable latent or delayed symbols. */ 717 if (libsym->latent || libsym->delayed) 718 return 0; 719 720 bp_addr = sym2addr(proc, libsym); 721 722 /* If there is an artificial breakpoint on the same address, 723 * its libsym will be NULL, and we can smuggle our libsym 724 * there. That artificial breakpoint is there presumably for 725 * the callbacks, which we don't touch. If there is a real 726 * breakpoint, then this is a bug. ltrace-elf.c should filter 727 * symbols and ignore extra symbol aliases. 728 * 729 * The other direction is more complicated and currently not 730 * supported. If a breakpoint has custom callbacks, it might 731 * be also custom-allocated, and we would really need to swap 732 * the two: delete the one now in the dictionary, swap values 733 * around, and put the new breakpoint back in. */ 734 struct breakpoint *bp = dict_find_entry(proc->breakpoints, 735 bp_addr); 736 if (bp != NULL) { 737 assert(bp->libsym == NULL); 738 bp->libsym = libsym; 739 return 0; 740 } 741 742 bp = malloc(sizeof(*bp)); 743 if (bp == NULL 744 || breakpoint_init(bp, proc, bp_addr, libsym) < 0) { 745 fail: 746 free(bp); 747 return -1; 748 } 749 if (proc_add_breakpoint(proc, bp) < 0) { 750 breakpoint_destroy(bp); 751 goto fail; 752 } 753 754 if (breakpoint_turn_on(bp, proc) < 0) { 755 proc_remove_breakpoint(proc, bp); 756 breakpoint_destroy(bp); 757 goto fail; 758 } 759 760 return 0; 761} 762 763static enum callback_status 764cb_breakpoint_for_symbol(struct library_symbol *libsym, void *data) 765{ 766 return breakpoint_for_symbol(libsym, data) < 0 ? CBS_FAIL : CBS_CONT; 767} 768 769static int 770proc_activate_latent_symbol(struct Process *proc, 771 struct library_symbol *libsym) 772{ 773 assert(libsym->latent); 774 libsym->latent = 0; 775 return breakpoint_for_symbol(libsym, proc); 776} 777 778int 779proc_activate_delayed_symbol(struct Process *proc, 780 struct library_symbol *libsym) 781{ 782 assert(libsym->delayed); 783 libsym->delayed = 0; 784 return breakpoint_for_symbol(libsym, proc); 785} 786 787static enum callback_status 788activate_latent_in(struct Process *proc, struct library *lib, void *data) 789{ 790 struct library_exported_name *exported; 791 for (exported = data; exported != NULL; exported = exported->next) { 792 struct library_symbol *libsym = NULL; 793 while ((libsym = library_each_symbol(lib, libsym, 794 library_symbol_named_cb, 795 (void *)exported->name)) 796 != NULL) 797 if (libsym->latent 798 && proc_activate_latent_symbol(proc, libsym) < 0) 799 return CBS_FAIL; 800 } 801 return CBS_CONT; 802} 803 804void 805proc_add_library(struct Process *proc, struct library *lib) 806{ 807 assert(lib->next == NULL); 808 lib->next = proc->libraries; 809 proc->libraries = lib; 810 debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d", 811 lib->soname, lib->base, lib->pathname, proc->pid); 812 813 /* Insert breakpoints for all active (non-latent) symbols. */ 814 struct library_symbol *libsym = NULL; 815 while ((libsym = library_each_symbol(lib, libsym, 816 cb_breakpoint_for_symbol, 817 proc)) != NULL) 818 fprintf(stderr, "Couldn't insert breakpoint for %s to %d: %s.", 819 libsym->name, proc->pid, strerror(errno)); 820 821 /* Look through export list of the new library and compare it 822 * with latent symbols of all libraries (including this 823 * library itself). */ 824 struct library *lib2 = NULL; 825 while ((lib2 = proc_each_library(proc, lib2, activate_latent_in, 826 lib->exported_names)) != NULL) 827 fprintf(stderr, 828 "Couldn't activate latent symbols for %s in %d: %s.", 829 libsym->name, proc->pid, strerror(errno)); 830} 831 832int 833proc_remove_library(struct Process *proc, struct library *lib) 834{ 835 struct library **libp; 836 for (libp = &proc->libraries; *libp != NULL; libp = &(*libp)->next) 837 if (*libp == lib) { 838 *libp = lib->next; 839 return 0; 840 } 841 return -1; 842} 843 844struct library * 845proc_each_library(struct Process *proc, struct library *it, 846 enum callback_status (*cb)(struct Process *proc, 847 struct library *lib, void *data), 848 void *data) 849{ 850 if (it == NULL) 851 it = proc->libraries; 852 853 while (it != NULL) { 854 struct library *next = it->next; 855 856 switch (cb(proc, it, data)) { 857 case CBS_FAIL: 858 /* XXX handle me */ 859 case CBS_STOP: 860 return it; 861 case CBS_CONT: 862 break; 863 } 864 865 it = next; 866 } 867 868 return NULL; 869} 870 871static void 872check_leader(struct Process *proc) 873{ 874 /* Only the group leader should be getting the breakpoints and 875 * thus have ->breakpoint initialized. */ 876 assert(proc->leader != NULL); 877 assert(proc->leader == proc); 878 assert(proc->breakpoints != NULL); 879} 880 881int 882proc_add_breakpoint(struct Process *proc, struct breakpoint *bp) 883{ 884 debug(DEBUG_FUNCTION, "proc_add_breakpoint(pid=%d, %s@%p)", 885 proc->pid, breakpoint_name(bp), bp->addr); 886 check_leader(proc); 887 888 /* XXX We might merge bp->libsym instead of the following 889 * assert, but that's not necessary right now. Read the 890 * comment in breakpoint_for_symbol. */ 891 assert(dict_find_entry(proc->breakpoints, bp->addr) == NULL); 892 893 if (dict_enter(proc->breakpoints, bp->addr, bp) < 0) { 894 fprintf(stderr, 895 "couldn't enter breakpoint %s@%p to dictionary: %s\n", 896 breakpoint_name(bp), bp->addr, strerror(errno)); 897 return -1; 898 } 899 900 return 0; 901} 902 903void 904proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp) 905{ 906 debug(DEBUG_FUNCTION, "proc_remove_breakpoint(pid=%d, %s@%p)", 907 proc->pid, breakpoint_name(bp), bp->addr); 908 check_leader(proc); 909 struct breakpoint *removed = dict_remove(proc->breakpoints, bp->addr); 910 assert(removed == bp); 911} 912 913/* Dict doesn't support iteration restarts, so here's this contraption 914 * for now. XXX add restarts to dict. */ 915struct each_breakpoint_data 916{ 917 void *start; 918 void *end; 919 struct Process *proc; 920 enum callback_status (*cb)(struct Process *proc, 921 struct breakpoint *bp, 922 void *data); 923 void *cb_data; 924}; 925 926static void 927each_breakpoint_cb(void *key, void *value, void *d) 928{ 929 struct each_breakpoint_data *data = d; 930 if (data->end != NULL) 931 return; 932 if (data->start == key) 933 data->start = NULL; 934 935 if (data->start == NULL) { 936 switch (data->cb(data->proc, value, data->cb_data)) { 937 case CBS_FAIL: 938 /* XXX handle me */ 939 case CBS_STOP: 940 data->end = key; 941 case CBS_CONT: 942 return; 943 } 944 } 945} 946 947void * 948proc_each_breakpoint(struct Process *proc, void *start, 949 enum callback_status (*cb)(struct Process *proc, 950 struct breakpoint *bp, 951 void *data), void *data) 952{ 953 struct each_breakpoint_data dd = { 954 .start = start, 955 .proc = proc, 956 .cb = cb, 957 .cb_data = data, 958 }; 959 dict_apply_to_all(proc->breakpoints, &each_breakpoint_cb, &dd); 960 return dd.end; 961} 962 963int 964proc_find_symbol(struct Process *proc, struct library_symbol *sym, 965 struct library **retlib, struct library_symbol **retsym) 966{ 967 struct library *lib = sym->lib; 968 assert(lib != NULL); 969 970 struct library *flib 971 = proc_each_library(proc, NULL, library_with_key_cb, &lib->key); 972 if (flib == NULL) 973 return -1; 974 975 struct library_symbol *fsym 976 = library_each_symbol(flib, NULL, library_symbol_named_cb, 977 (char *)sym->name); 978 if (fsym == NULL) 979 return -1; 980 981 if (retlib != NULL) 982 *retlib = flib; 983 if (retsym != NULL) 984 *retsym = fsym; 985 986 return 0; 987} 988