proc.c revision d5199029878221dd7d73e413f71d080b7079d4e6
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 /* Don't bother if there were errors anyway. */ 312 if (data->error != 0) 313 return; 314 315 struct breakpoint *clone = malloc(sizeof(*clone)); 316 if (clone == NULL 317 || breakpoint_clone(clone, data->new_proc, 318 bp, data->old_proc) < 0) { 319 fail: 320 free(clone); 321 data->error = -1; 322 } 323 if (proc_add_breakpoint(data->new_proc->leader, clone) < 0) { 324 breakpoint_destroy(clone); 325 goto fail; 326 } 327} 328 329int 330process_clone(struct Process *retp, struct Process *proc, pid_t pid) 331{ 332 if (process_bare_init(retp, proc->filename, pid, 0) < 0) { 333 fail1: 334 fprintf(stderr, "failed to clone process %d->%d : %s\n", 335 proc->pid, pid, strerror(errno)); 336 return -1; 337 } 338 339 retp->tracesysgood = proc->tracesysgood; 340 retp->e_machine = proc->e_machine; 341 retp->e_class = proc->e_class; 342 343 /* For non-leader processes, that's all we need to do. */ 344 if (retp->leader != retp) 345 return 0; 346 347 /* Clone symbols first so that we can clone and relink 348 * breakpoints. */ 349 struct library *lib; 350 struct library **nlibp = &retp->libraries; 351 for (lib = proc->leader->libraries; lib != NULL; lib = lib->next) { 352 *nlibp = malloc(sizeof(**nlibp)); 353 if (*nlibp == NULL 354 || library_clone(*nlibp, lib) < 0) { 355 fail2: 356 process_bare_destroy(retp, 0); 357 358 /* Error when cloning. Unroll what was done. */ 359 for (lib = retp->libraries; lib != NULL; ) { 360 struct library *next = lib->next; 361 library_destroy(lib); 362 free(lib); 363 lib = next; 364 } 365 goto fail1; 366 } 367 368 nlibp = &(*nlibp)->next; 369 } 370 371 /* Now clone breakpoints. Symbol relinking is done in 372 * clone_single_bp. */ 373 struct clone_single_bp_data data = { 374 .old_proc = proc, 375 .new_proc = retp, 376 .error = 0, 377 }; 378 dict_apply_to_all(proc->leader->breakpoints, &clone_single_bp, &data); 379 if (data.error < 0) 380 goto fail2; 381 382 /* And finally the call stack. */ 383 /* XXX clearly the callstack handling should be moved to a 384 * separate module and this whole business extracted to 385 * callstack_clone, or callstack_element_clone. */ 386 memcpy(retp->callstack, proc->callstack, sizeof(retp->callstack)); 387 retp->callstack_depth = proc->callstack_depth; 388 389 size_t i; 390 for (i = 0; i < retp->callstack_depth; ++i) { 391 struct callstack_element *elem = &retp->callstack[i]; 392 struct fetch_context *ctx = elem->fetch_context; 393 if (ctx != NULL) { 394 struct fetch_context *nctx = fetch_arg_clone(retp, ctx); 395 if (nctx == NULL) { 396 size_t j; 397 fail3: 398 for (j = 0; j < i; ++j) { 399 nctx = elem->fetch_context; 400 fetch_arg_done(nctx); 401 elem->fetch_context = NULL; 402 } 403 goto fail2; 404 } 405 elem->fetch_context = nctx; 406 } 407 408 struct value_dict *args = elem->arguments; 409 if (args != NULL) { 410 struct value_dict *nargs = malloc(sizeof(*nargs)); 411 if (nargs == NULL 412 || val_dict_clone(nargs, args) < 0) { 413 size_t j; 414 for (j = 0; j < i; ++j) { 415 nargs = elem->arguments; 416 val_dict_destroy(nargs); 417 free(nargs); 418 elem->arguments = NULL; 419 } 420 421 /* Pretend that this round went well, 422 * so that fail3 frees I-th 423 * fetch_context. */ 424 ++i; 425 goto fail3; 426 } 427 elem->arguments = nargs; 428 } 429 430 /* If it's not a syscall, we need to find the 431 * corresponding library symbol in the cloned 432 * library. */ 433 if (!elem->is_syscall && elem->c_un.libfunc != NULL) { 434 struct library_symbol *libfunc = elem->c_un.libfunc; 435 int rc = proc_find_symbol(retp, libfunc, 436 NULL, &elem->c_un.libfunc); 437 assert(rc == 0); 438 } 439 } 440 441 /* At this point, retp is fully initialized, except for OS and 442 * arch parts, and we can call private_process_destroy. */ 443 if (os_process_clone(retp, proc) < 0) { 444 private_process_destroy(retp, 0); 445 return -1; 446 } 447 if (arch_process_clone(retp, proc) < 0) { 448 os_process_destroy(retp); 449 private_process_destroy(retp, 0); 450 return -1; 451 } 452 453 return 0; 454} 455 456static int 457open_one_pid(pid_t pid) 458{ 459 Process *proc; 460 char *filename; 461 debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid); 462 463 /* Get the filename first. Should the trace_pid fail, we can 464 * easily free it, untracing is more work. */ 465 if ((filename = pid2name(pid)) == NULL 466 || trace_pid(pid) < 0) { 467 fail: 468 free(filename); 469 return -1; 470 } 471 472 proc = open_program(filename, pid); 473 if (proc == NULL) 474 goto fail; 475 free(filename); 476 trace_set_options(proc); 477 478 return 0; 479} 480 481static enum callback_status 482start_one_pid(Process * proc, void * data) 483{ 484 continue_process(proc->pid); 485 return CBS_CONT; 486} 487 488void 489open_pid(pid_t pid) 490{ 491 debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid); 492 /* If we are already tracing this guy, we should be seeing all 493 * his children via normal tracing route. */ 494 if (pid2proc(pid) != NULL) 495 return; 496 497 /* First, see if we can attach the requested PID itself. */ 498 if (open_one_pid(pid)) { 499 fprintf(stderr, "Cannot attach to pid %u: %s\n", 500 pid, strerror(errno)); 501 trace_fail_warning(pid); 502 return; 503 } 504 505 /* Now attach to all tasks that belong to that PID. There's a 506 * race between process_tasks and open_one_pid. So when we 507 * fail in open_one_pid below, we just do another round. 508 * Chances are that by then that PID will have gone away, and 509 * that's why we have seen the failure. The processes that we 510 * manage to open_one_pid are stopped, so we should eventually 511 * reach a point where process_tasks doesn't give any new 512 * processes (because there's nobody left to produce 513 * them). */ 514 size_t old_ntasks = 0; 515 int have_all; 516 while (1) { 517 pid_t *tasks; 518 size_t ntasks; 519 size_t i; 520 521 if (process_tasks(pid, &tasks, &ntasks) < 0) { 522 fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n", 523 pid, strerror(errno)); 524 break; 525 } 526 527 have_all = 1; 528 for (i = 0; i < ntasks; ++i) 529 if (pid2proc(tasks[i]) == NULL 530 && open_one_pid(tasks[i])) 531 have_all = 0; 532 533 free(tasks); 534 535 if (have_all && old_ntasks == ntasks) 536 break; 537 old_ntasks = ntasks; 538 } 539 540 struct Process *leader = pid2proc(pid)->leader; 541 542 /* XXX Is there a way to figure out whether _start has 543 * actually already been hit? */ 544 arch_dynlink_done(leader); 545 546 /* Done. Continue everyone. */ 547 each_task(leader, NULL, start_one_pid, NULL); 548} 549 550static enum callback_status 551find_proc(Process * proc, void * data) 552{ 553 pid_t pid = (pid_t)(uintptr_t)data; 554 return proc->pid == pid ? CBS_STOP : CBS_CONT; 555} 556 557Process * 558pid2proc(pid_t pid) { 559 return each_process(NULL, &find_proc, (void *)(uintptr_t)pid); 560} 561 562static Process * list_of_processes = NULL; 563 564static void 565unlist_process(Process * proc) 566{ 567 Process *tmp; 568 569 if (list_of_processes == proc) { 570 list_of_processes = list_of_processes->next; 571 return; 572 } 573 574 for (tmp = list_of_processes; ; tmp = tmp->next) { 575 /* If the following assert fails, the process wasn't 576 * in the list. */ 577 assert(tmp->next != NULL); 578 579 if (tmp->next == proc) { 580 tmp->next = tmp->next->next; 581 return; 582 } 583 } 584} 585 586struct Process * 587each_process(struct Process *start_after, 588 enum callback_status(*cb)(struct Process *proc, void *data), 589 void *data) 590{ 591 struct Process *it = start_after == NULL ? list_of_processes 592 : start_after->next; 593 594 while (it != NULL) { 595 /* Callback might call remove_process. */ 596 struct Process *next = it->next; 597 switch ((*cb)(it, data)) { 598 case CBS_FAIL: 599 /* XXX handle me */ 600 case CBS_STOP: 601 return it; 602 case CBS_CONT: 603 break; 604 } 605 it = next; 606 } 607 return NULL; 608} 609 610Process * 611each_task(struct Process *proc, struct Process *start_after, 612 enum callback_status(*cb)(struct Process *proc, void *data), 613 void *data) 614{ 615 assert(proc != NULL); 616 struct Process *it = start_after == NULL ? proc->leader 617 : start_after->next; 618 619 if (it != NULL) { 620 struct Process *leader = it->leader; 621 while (it != NULL && it->leader == leader) { 622 /* Callback might call remove_process. */ 623 struct Process *next = it->next; 624 switch ((*cb)(it, data)) { 625 case CBS_FAIL: 626 /* XXX handle me */ 627 case CBS_STOP: 628 return it; 629 case CBS_CONT: 630 break; 631 } 632 it = next; 633 } 634 } 635 return NULL; 636} 637 638static void 639add_process(struct Process *proc, int was_exec) 640{ 641 Process ** leaderp = &list_of_processes; 642 if (proc->pid) { 643 pid_t tgid = process_leader(proc->pid); 644 if (tgid == 0) 645 /* Must have been terminated before we managed 646 * to fully attach. */ 647 return; 648 if (tgid == proc->pid) 649 proc->leader = proc; 650 else { 651 Process * leader = pid2proc(tgid); 652 proc->leader = leader; 653 if (leader != NULL) 654 leaderp = &leader->next; 655 } 656 } 657 658 if (!was_exec) { 659 proc->next = *leaderp; 660 *leaderp = proc; 661 } 662} 663 664void 665change_process_leader(Process * proc, Process * leader) 666{ 667 Process ** leaderp = &list_of_processes; 668 if (proc->leader == leader) 669 return; 670 671 assert(leader != NULL); 672 unlist_process(proc); 673 if (proc != leader) 674 leaderp = &leader->next; 675 676 proc->leader = leader; 677 proc->next = *leaderp; 678 *leaderp = proc; 679} 680 681static enum callback_status 682clear_leader(struct Process *proc, void *data) 683{ 684 debug(DEBUG_FUNCTION, "detach_task %d from leader %d", 685 proc->pid, proc->leader->pid); 686 proc->leader = NULL; 687 return CBS_CONT; 688} 689 690void 691remove_process(Process *proc) 692{ 693 debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid); 694 695 if (proc->leader == proc) 696 each_task(proc, NULL, &clear_leader, NULL); 697 698 unlist_process(proc); 699 process_removed(proc); 700 process_destroy(proc); 701 free(proc); 702} 703 704void 705install_event_handler(Process *proc, struct event_handler *handler) 706{ 707 debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler); 708 assert(proc->event_handler == NULL); 709 proc->event_handler = handler; 710} 711 712void 713destroy_event_handler(Process * proc) 714{ 715 struct event_handler *handler = proc->event_handler; 716 debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler); 717 assert(handler != NULL); 718 if (handler->destroy != NULL) 719 handler->destroy(handler); 720 free(handler); 721 proc->event_handler = NULL; 722} 723 724static int 725breakpoint_for_symbol(struct library_symbol *libsym, struct Process *proc) 726{ 727 arch_addr_t bp_addr; 728 assert(proc->leader == proc); 729 730 /* Don't enable latent or delayed symbols. */ 731 if (libsym->latent || libsym->delayed) { 732 debug(DEBUG_FUNCTION, 733 "delayed and/or latent breakpoint pid=%d, %s@%p", 734 proc->pid, libsym->name, libsym->enter_addr); 735 return 0; 736 } 737 738 bp_addr = sym2addr(proc, libsym); 739 740 /* If there is an artificial breakpoint on the same address, 741 * its libsym will be NULL, and we can smuggle our libsym 742 * there. That artificial breakpoint is there presumably for 743 * the callbacks, which we don't touch. If there is a real 744 * breakpoint, then this is a bug. ltrace-elf.c should filter 745 * symbols and ignore extra symbol aliases. 746 * 747 * The other direction is more complicated and currently not 748 * supported. If a breakpoint has custom callbacks, it might 749 * be also custom-allocated, and we would really need to swap 750 * the two: delete the one now in the dictionary, swap values 751 * around, and put the new breakpoint back in. */ 752 struct breakpoint *bp = dict_find_entry(proc->breakpoints, 753 bp_addr); 754 if (bp != NULL) { 755 assert(bp->libsym == NULL); 756 bp->libsym = libsym; 757 return 0; 758 } 759 760 bp = malloc(sizeof(*bp)); 761 if (bp == NULL 762 || breakpoint_init(bp, proc, bp_addr, libsym) < 0) { 763 fail: 764 free(bp); 765 return -1; 766 } 767 if (proc_add_breakpoint(proc, bp) < 0) { 768 breakpoint_destroy(bp); 769 goto fail; 770 } 771 772 if (breakpoint_turn_on(bp, proc) < 0) { 773 proc_remove_breakpoint(proc, bp); 774 breakpoint_destroy(bp); 775 goto fail; 776 } 777 778 return 0; 779} 780 781static enum callback_status 782cb_breakpoint_for_symbol(struct library_symbol *libsym, void *data) 783{ 784 return breakpoint_for_symbol(libsym, data) < 0 ? CBS_FAIL : CBS_CONT; 785} 786 787static int 788proc_activate_latent_symbol(struct Process *proc, 789 struct library_symbol *libsym) 790{ 791 assert(libsym->latent); 792 libsym->latent = 0; 793 debug(DEBUG_FUNCTION, "activated latent symbol"); 794 return breakpoint_for_symbol(libsym, proc); 795} 796 797int 798proc_activate_delayed_symbol(struct Process *proc, 799 struct library_symbol *libsym) 800{ 801 assert(libsym->delayed); 802 libsym->delayed = 0; 803 debug(DEBUG_FUNCTION, "activated delayed symbol"); 804 return breakpoint_for_symbol(libsym, proc); 805} 806 807static enum callback_status 808activate_latent_in(struct Process *proc, struct library *lib, void *data) 809{ 810 struct library_exported_name *exported; 811 for (exported = data; exported != NULL; exported = exported->next) { 812 struct library_symbol *libsym = NULL; 813 while ((libsym = library_each_symbol(lib, libsym, 814 library_symbol_named_cb, 815 (void *)exported->name)) 816 != NULL) 817 if (libsym->latent 818 && proc_activate_latent_symbol(proc, libsym) < 0) 819 return CBS_FAIL; 820 } 821 return CBS_CONT; 822} 823 824void 825proc_add_library(struct Process *proc, struct library *lib) 826{ 827 assert(lib->next == NULL); 828 lib->next = proc->libraries; 829 proc->libraries = lib; 830 debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d", 831 lib->soname, lib->base, lib->pathname, proc->pid); 832 833 /* Insert breakpoints for all active (non-latent) symbols. */ 834 struct library_symbol *libsym = NULL; 835 while ((libsym = library_each_symbol(lib, libsym, 836 cb_breakpoint_for_symbol, 837 proc)) != NULL) 838 fprintf(stderr, "Couldn't insert breakpoint for %s to %d: %s.", 839 libsym->name, proc->pid, strerror(errno)); 840 841 /* Look through export list of the new library and compare it 842 * with latent symbols of all libraries (including this 843 * library itself). */ 844 struct library *lib2 = NULL; 845 while ((lib2 = proc_each_library(proc, lib2, activate_latent_in, 846 lib->exported_names)) != NULL) 847 fprintf(stderr, 848 "Couldn't activate latent symbols for %s in %d: %s.", 849 libsym->name, proc->pid, strerror(errno)); 850} 851 852int 853proc_remove_library(struct Process *proc, struct library *lib) 854{ 855 struct library **libp; 856 for (libp = &proc->libraries; *libp != NULL; libp = &(*libp)->next) 857 if (*libp == lib) { 858 *libp = lib->next; 859 return 0; 860 } 861 return -1; 862} 863 864struct library * 865proc_each_library(struct Process *proc, struct library *it, 866 enum callback_status (*cb)(struct Process *proc, 867 struct library *lib, void *data), 868 void *data) 869{ 870 if (it == NULL) 871 it = proc->libraries; 872 873 while (it != NULL) { 874 struct library *next = it->next; 875 876 switch (cb(proc, it, data)) { 877 case CBS_FAIL: 878 /* XXX handle me */ 879 case CBS_STOP: 880 return it; 881 case CBS_CONT: 882 break; 883 } 884 885 it = next; 886 } 887 888 return NULL; 889} 890 891static void 892check_leader(struct Process *proc) 893{ 894 /* Only the group leader should be getting the breakpoints and 895 * thus have ->breakpoint initialized. */ 896 assert(proc->leader != NULL); 897 assert(proc->leader == proc); 898 assert(proc->breakpoints != NULL); 899} 900 901int 902proc_add_breakpoint(struct Process *proc, struct breakpoint *bp) 903{ 904 debug(DEBUG_FUNCTION, "proc_add_breakpoint(pid=%d, %s@%p)", 905 proc->pid, breakpoint_name(bp), bp->addr); 906 check_leader(proc); 907 908 /* XXX We might merge bp->libsym instead of the following 909 * assert, but that's not necessary right now. Read the 910 * comment in breakpoint_for_symbol. */ 911 assert(dict_find_entry(proc->breakpoints, bp->addr) == NULL); 912 913 if (dict_enter(proc->breakpoints, bp->addr, bp) < 0) { 914 fprintf(stderr, 915 "couldn't enter breakpoint %s@%p to dictionary: %s\n", 916 breakpoint_name(bp), bp->addr, strerror(errno)); 917 return -1; 918 } 919 920 return 0; 921} 922 923void 924proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp) 925{ 926 debug(DEBUG_FUNCTION, "proc_remove_breakpoint(pid=%d, %s@%p)", 927 proc->pid, breakpoint_name(bp), bp->addr); 928 check_leader(proc); 929 struct breakpoint *removed = dict_remove(proc->breakpoints, bp->addr); 930 assert(removed == bp); 931} 932 933/* Dict doesn't support iteration restarts, so here's this contraption 934 * for now. XXX add restarts to dict. */ 935struct each_breakpoint_data 936{ 937 void *start; 938 void *end; 939 struct Process *proc; 940 enum callback_status (*cb)(struct Process *proc, 941 struct breakpoint *bp, 942 void *data); 943 void *cb_data; 944}; 945 946static void 947each_breakpoint_cb(void *key, void *value, void *d) 948{ 949 struct each_breakpoint_data *data = d; 950 if (data->end != NULL) 951 return; 952 if (data->start == key) 953 data->start = NULL; 954 955 if (data->start == NULL) { 956 switch (data->cb(data->proc, value, data->cb_data)) { 957 case CBS_FAIL: 958 /* XXX handle me */ 959 case CBS_STOP: 960 data->end = key; 961 case CBS_CONT: 962 return; 963 } 964 } 965} 966 967void * 968proc_each_breakpoint(struct Process *proc, void *start, 969 enum callback_status (*cb)(struct Process *proc, 970 struct breakpoint *bp, 971 void *data), void *data) 972{ 973 struct each_breakpoint_data dd = { 974 .start = start, 975 .proc = proc, 976 .cb = cb, 977 .cb_data = data, 978 }; 979 dict_apply_to_all(proc->breakpoints, &each_breakpoint_cb, &dd); 980 return dd.end; 981} 982 983int 984proc_find_symbol(struct Process *proc, struct library_symbol *sym, 985 struct library **retlib, struct library_symbol **retsym) 986{ 987 struct library *lib = sym->lib; 988 assert(lib != NULL); 989 990 struct library *flib 991 = proc_each_library(proc, NULL, library_with_key_cb, &lib->key); 992 if (flib == NULL) 993 return -1; 994 995 struct library_symbol *fsym 996 = library_each_symbol(flib, NULL, library_symbol_named_cb, 997 (char *)sym->name); 998 if (fsym == NULL) 999 return -1; 1000 1001 if (retlib != NULL) 1002 *retlib = flib; 1003 if (retsym != NULL) 1004 *retsym = fsym; 1005 1006 return 0; 1007} 1008 1009struct library_symbol * 1010proc_each_symbol(struct Process *proc, struct library_symbol *start_after, 1011 enum callback_status (*cb)(struct library_symbol *, void *), 1012 void *data) 1013{ 1014 struct library *lib; 1015 for (lib = start_after != NULL ? start_after->lib : proc->libraries; 1016 lib != NULL; lib = lib->next) { 1017 start_after = library_each_symbol(lib, start_after, cb, data); 1018 if (start_after != NULL) 1019 return start_after; 1020 } 1021 1022 return NULL; 1023} 1024