proc.c revision 3ed2a4227d5f2a8d44f3c6ffd704a9d2e867c591
1#include "config.h" 2 3#if defined(HAVE_LIBUNWIND) 4#include <libunwind.h> 5#include <libunwind-ptrace.h> 6#endif /* defined(HAVE_LIBUNWIND) */ 7 8#include <sys/types.h> 9#include <string.h> 10#include <stdio.h> 11#include <errno.h> 12#include <stdlib.h> 13#include <assert.h> 14#include <error.h> 15 16#include "common.h" 17#include "breakpoint.h" 18#include "proc.h" 19 20static int 21process_bare_init(struct Process *proc, const char *filename, pid_t pid) 22{ 23 memset(proc, 0, sizeof(*proc)); 24 25 proc->filename = strdup(filename); 26 if (proc->filename == NULL) { 27 fail: 28 free(proc->filename); 29 if (proc->breakpoints != NULL) 30 dict_clear(proc->breakpoints); 31 return -1; 32 } 33 34 /* Add process so that we know who the leader is. */ 35 proc->pid = pid; 36 add_process(proc); 37 if (proc->leader == NULL) 38 goto fail; 39 40 if (proc->leader == proc) { 41 proc->breakpoints = dict_init(target_address_hash, 42 target_address_cmp); 43 if (proc->breakpoints == NULL) 44 goto fail; 45 } else { 46 proc->breakpoints = NULL; 47 } 48 49#if defined(HAVE_LIBUNWIND) 50 proc->unwind_priv = _UPT_create(pid); 51 proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0); 52#endif /* defined(HAVE_LIBUNWIND) */ 53 54 return 0; 55} 56 57static void 58process_bare_destroy(struct Process *proc) 59{ 60 free(proc->filename); 61 dict_clear(proc->breakpoints); 62 remove_process(proc); 63} 64 65int 66process_init(struct Process *proc, const char *filename, pid_t pid, int enable) 67{ 68 if (process_bare_init(proc, filename, pid) < 0) { 69 error(0, errno, "init process %d", pid); 70 return -1; 71 } 72 73 if (proc->leader == proc && breakpoints_init(proc, enable) < 0) { 74 fprintf(stderr, "failed to init breakpoints %d\n", 75 proc->pid); 76 process_bare_destroy(proc); 77 return -1; 78 } 79 80 return 0; 81} 82 83struct Process * 84open_program(const char *filename, pid_t pid, int enable) 85{ 86 assert(pid != 0); 87 struct Process *proc = malloc(sizeof(*proc)); 88 if (proc == NULL 89 || process_init(proc, filename, pid, enable) < 0) { 90 free(proc); 91 return NULL; 92 } 93 return proc; 94} 95 96struct clone_single_bp_data { 97 struct Process *old_proc; 98 struct Process *new_proc; 99 int error; 100}; 101 102struct find_symbol_data { 103 struct library_symbol *old_libsym; 104 struct library_symbol *found_libsym; 105}; 106 107static enum callback_status 108find_sym_in_lib(struct Process *proc, struct library *lib, void *u) 109{ 110 struct find_symbol_data *fs = u; 111 fs->found_libsym 112 = library_each_symbol(lib, NULL, library_symbol_equal_cb, 113 fs->old_libsym); 114 return fs->found_libsym != NULL ? CBS_STOP : CBS_CONT; 115} 116 117static void 118clone_single_bp(void *key, void *value, void *u) 119{ 120 target_address_t addr = (target_address_t)key; 121 struct breakpoint *bp = value; 122 struct clone_single_bp_data *data = u; 123 124 /* Find library and symbol that this symbol was linked to. */ 125 struct library_symbol *libsym = bp->libsym; 126 struct library *lib = NULL; 127 if (libsym != NULL) { 128 struct find_symbol_data f_data = { 129 .old_libsym = libsym, 130 }; 131 lib = proc_each_library(data->old_proc, NULL, 132 find_sym_in_lib, &f_data); 133 assert(lib != NULL); 134 libsym = f_data.found_libsym; 135 } 136 137 /* LIB and LIBSYM now hold the new library and symbol that 138 * correspond to the original breakpoint. Now we can do the 139 * clone itself. */ 140 struct breakpoint *clone = malloc(sizeof(*clone)); 141 if (clone == NULL 142 || breakpoint_init(clone, data->new_proc, addr, libsym) < 0) { 143 data->error = -1; 144 return; 145 } 146 breakpoint_set_callbacks(clone, bp->cbs); 147} 148 149int 150process_clone(struct Process *retp, struct Process *proc, pid_t pid) 151{ 152 if (process_bare_init(retp, proc->filename, pid) < 0) { 153 fail: 154 error(0, errno, "clone process %d->%d", proc->pid, pid); 155 return -1; 156 } 157 158 /* For non-leader processes, that's all we need to do. */ 159 if (proc->leader != proc) 160 return 0; 161 162 /* Clone symbols first so that we can clone and relink 163 * breakpoints. */ 164 struct library *lib; 165 struct library **nlibp = &retp->libraries; 166 for (lib = proc->libraries; lib != NULL; lib = lib->next) { 167 *nlibp = malloc(sizeof(**nlibp)); 168 if (*nlibp == NULL 169 || library_clone(*nlibp, lib) < 0) { 170 fail2: 171 process_bare_destroy(retp); 172 173 /* Error when cloning. Unroll what was done. */ 174 for (lib = retp->libraries; lib != NULL; ) { 175 struct library *next = lib->next; 176 library_destroy(lib); 177 free(lib); 178 lib = next; 179 } 180 goto fail; 181 } 182 183 nlibp = &(*nlibp)->next; 184 } 185 186 /* Now clone breakpoints. Symbol relinking is done in 187 * clone_single_bp. */ 188 struct clone_single_bp_data data = { 189 .old_proc = proc, 190 .new_proc = retp, 191 .error = 0, 192 }; 193 dict_apply_to_all(proc->breakpoints, &clone_single_bp, &data); 194 195 if (data.error < 0) 196 goto fail2; 197 198 return 0; 199} 200 201static int 202open_one_pid(pid_t pid) 203{ 204 Process *proc; 205 char *filename; 206 debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid); 207 208 /* Get the filename first. Should the trace_pid fail, we can 209 * easily free it, untracing is more work. */ 210 if ((filename = pid2name(pid)) == NULL 211 || trace_pid(pid) < 0) { 212 free(filename); 213 return -1; 214 } 215 216 proc = open_program(filename, pid, 0); 217 if (proc == NULL) 218 return -1; 219 trace_set_options(proc); 220 221 return 0; 222} 223 224static enum callback_status 225start_one_pid(Process * proc, void * data) 226{ 227 continue_process(proc->pid); 228 return CBS_CONT; 229} 230 231void 232open_pid(pid_t pid) 233{ 234 debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid); 235 /* If we are already tracing this guy, we should be seeing all 236 * his children via normal tracing route. */ 237 if (pid2proc(pid) != NULL) 238 return; 239 240 /* First, see if we can attach the requested PID itself. */ 241 if (open_one_pid(pid)) { 242 fprintf(stderr, "Cannot attach to pid %u: %s\n", 243 pid, strerror(errno)); 244 trace_fail_warning(pid); 245 return; 246 } 247 248 /* Now attach to all tasks that belong to that PID. There's a 249 * race between process_tasks and open_one_pid. So when we 250 * fail in open_one_pid below, we just do another round. 251 * Chances are that by then that PID will have gone away, and 252 * that's why we have seen the failure. The processes that we 253 * manage to open_one_pid are stopped, so we should eventually 254 * reach a point where process_tasks doesn't give any new 255 * processes (because there's nobody left to produce 256 * them). */ 257 size_t old_ntasks = 0; 258 int have_all; 259 while (1) { 260 pid_t *tasks; 261 size_t ntasks; 262 size_t i; 263 264 if (process_tasks(pid, &tasks, &ntasks) < 0) { 265 fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n", 266 pid, strerror(errno)); 267 break; 268 } 269 270 have_all = 1; 271 for (i = 0; i < ntasks; ++i) 272 if (pid2proc(tasks[i]) == NULL 273 && open_one_pid(tasks[i])) 274 have_all = 0; 275 276 free(tasks); 277 278 if (have_all && old_ntasks == ntasks) 279 break; 280 old_ntasks = ntasks; 281 } 282 283 /* Done. Now initialize breakpoints and then continue 284 * everyone. */ 285 Process * leader; 286 leader = pid2proc(pid)->leader; 287 enable_all_breakpoints(leader); 288 289 each_task(pid2proc(pid)->leader, NULL, start_one_pid, NULL); 290} 291 292static enum callback_status 293find_proc(Process * proc, void * data) 294{ 295 pid_t pid = (pid_t)(uintptr_t)data; 296 return proc->pid == pid ? CBS_STOP : CBS_CONT; 297} 298 299Process * 300pid2proc(pid_t pid) { 301 return each_process(NULL, &find_proc, (void *)(uintptr_t)pid); 302} 303 304static Process * list_of_processes = NULL; 305 306static void 307unlist_process(Process * proc) 308{ 309 Process *tmp; 310 311 if (list_of_processes == proc) { 312 list_of_processes = list_of_processes->next; 313 return; 314 } 315 316 for (tmp = list_of_processes; ; tmp = tmp->next) { 317 /* If the following assert fails, the process wasn't 318 * in the list. */ 319 assert(tmp->next != NULL); 320 321 if (tmp->next == proc) { 322 tmp->next = tmp->next->next; 323 return; 324 } 325 } 326} 327 328struct Process * 329each_process(struct Process *start_after, 330 enum callback_status(*cb)(struct Process *proc, void *data), 331 void *data) 332{ 333 struct Process *it = start_after == NULL ? list_of_processes 334 : start_after->next; 335 336 while (it != NULL) { 337 /* Callback might call remove_process. */ 338 struct Process *next = it->next; 339 switch ((*cb)(it, data)) { 340 case CBS_FAIL: 341 /* XXX handle me */ 342 case CBS_STOP: 343 return it; 344 case CBS_CONT: 345 break; 346 } 347 it = next; 348 } 349 return NULL; 350} 351 352Process * 353each_task(struct Process *proc, struct Process *start_after, 354 enum callback_status(*cb)(struct Process *proc, void *data), 355 void *data) 356{ 357 assert(proc != NULL); 358 struct Process *it = start_after == NULL ? proc->leader 359 : start_after->next; 360 361 if (it != NULL) { 362 struct Process *leader = it->leader; 363 while (it != NULL && it->leader == leader) { 364 /* Callback might call remove_process. */ 365 struct Process *next = it->next; 366 switch ((*cb)(it, data)) { 367 case CBS_FAIL: 368 /* XXX handle me */ 369 case CBS_STOP: 370 return it; 371 case CBS_CONT: 372 break; 373 } 374 it = next; 375 } 376 } 377 return NULL; 378} 379 380void 381add_process(Process * proc) 382{ 383 Process ** leaderp = &list_of_processes; 384 if (proc->pid) { 385 pid_t tgid = process_leader(proc->pid); 386 if (tgid == 0) 387 /* Must have been terminated before we managed 388 * to fully attach. */ 389 return; 390 if (tgid == proc->pid) 391 proc->leader = proc; 392 else { 393 Process * leader = pid2proc(tgid); 394 proc->leader = leader; 395 if (leader != NULL) 396 leaderp = &leader->next; 397 } 398 } 399 proc->next = *leaderp; 400 *leaderp = proc; 401} 402 403void 404change_process_leader(Process * proc, Process * leader) 405{ 406 Process ** leaderp = &list_of_processes; 407 if (proc->leader == leader) 408 return; 409 410 assert(leader != NULL); 411 unlist_process(proc); 412 if (proc != leader) 413 leaderp = &leader->next; 414 415 proc->leader = leader; 416 proc->next = *leaderp; 417 *leaderp = proc; 418} 419 420static enum callback_status 421clear_leader(struct Process *proc, void *data) 422{ 423 debug(DEBUG_FUNCTION, "detach_task %d from leader %d", 424 proc->pid, proc->leader->pid); 425 proc->leader = NULL; 426 return CBS_CONT; 427} 428 429static enum ecb_status 430event_for_proc(Event * event, void * data) 431{ 432 if (event->proc == data) 433 return ecb_deque; 434 else 435 return ecb_cont; 436} 437 438static void 439delete_events_for(Process * proc) 440{ 441 Event * event; 442 while ((event = each_qd_event(&event_for_proc, proc)) != NULL) 443 free(event); 444} 445 446void 447remove_process(Process *proc) 448{ 449 debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid); 450 451 if (proc->leader == proc) 452 each_task(proc, NULL, &clear_leader, NULL); 453 454 unlist_process(proc); 455 delete_events_for(proc); 456} 457 458void 459install_event_handler(Process *proc, struct event_handler *handler) 460{ 461 debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler); 462 assert(proc->event_handler == NULL); 463 proc->event_handler = handler; 464} 465 466void 467destroy_event_handler(Process * proc) 468{ 469 struct event_handler *handler = proc->event_handler; 470 debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler); 471 assert(handler != NULL); 472 if (handler->destroy != NULL) 473 handler->destroy(handler); 474 free(handler); 475 proc->event_handler = NULL; 476} 477 478static enum callback_status 479breakpoint_for_symbol(struct library_symbol *libsym, void *data) 480{ 481 struct Process *proc = data; 482 assert(proc->leader == proc); 483 484 /* If there is an artificial breakpoint on the same address, 485 * its libsym will be NULL, and we can smuggle our libsym 486 * there. That artificial breakpoint is there presumably for 487 * the callbacks, which we don't touch. If there is a real 488 * breakpoint, then this is a bug. ltrace-elf.c should filter 489 * symbols and ignore extra symbol aliases. 490 * 491 * The other direction is more complicated and currently not 492 * supported. If a breakpoint has custom callbacks, it might 493 * be also custom-allocated, and we would really need to swap 494 * the two: delete the one now in the dictionary, swap values 495 * around, and put the new breakpoint back in. */ 496 struct breakpoint *bp = dict_find_entry(proc->breakpoints, 497 libsym->enter_addr); 498 if (bp != NULL) { 499 assert(bp->libsym == NULL); 500 bp->libsym = libsym; 501 return CBS_CONT; 502 } 503 504 bp = malloc(sizeof(*bp)); 505 if (bp == NULL 506 || breakpoint_init(bp, proc, libsym->enter_addr, libsym) < 0) { 507 fail: 508 free(bp); 509 return CBS_FAIL; 510 } 511 if (proc_add_breakpoint(proc, bp) < 0) { 512 breakpoint_destroy(bp); 513 goto fail; 514 } 515 516 /* If this is dlopened library, turn on the breakpoint right 517 * away. */ 518 if (proc->fixed_libs != NULL 519 && breakpoint_turn_on(bp) < 0) { 520 proc_remove_breakpoint(proc, bp); 521 breakpoint_destroy(bp); 522 goto fail; 523 } 524 525 return CBS_CONT; 526} 527 528void 529proc_add_library(struct Process *proc, struct library *lib) 530{ 531 assert(lib->next == NULL); 532 lib->next = proc->libraries; 533 proc->libraries = lib; 534 debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d", 535 lib->soname, lib->base, lib->pathname, proc->pid); 536 537 struct library_symbol *libsym = NULL; 538 while ((libsym = library_each_symbol(lib, libsym, breakpoint_for_symbol, 539 proc)) != NULL) 540 error(0, errno, "insert breakpoint for %s", libsym->name); 541} 542 543int 544proc_remove_library(struct Process *proc, struct library *lib) 545{ 546 struct library **libp; 547 for (libp = &proc->libraries; *libp != NULL; libp = &(*libp)->next) 548 if (*libp == lib) { 549 *libp = lib->next; 550 return 0; 551 } 552 return -1; 553} 554 555struct library * 556proc_each_library(struct Process *proc, struct library *it, 557 enum callback_status (*cb)(struct Process *proc, 558 struct library *lib, void *data), 559 void *data) 560{ 561 if (it == NULL) 562 it = proc->libraries; 563 564 while (it != NULL) { 565 struct library *next = it->next; 566 567 switch (cb(proc, it, data)) { 568 case CBS_FAIL: 569 /* XXX handle me */ 570 case CBS_STOP: 571 return it; 572 case CBS_CONT: 573 break; 574 } 575 576 it = next; 577 } 578 579 return NULL; 580} 581 582int 583proc_add_breakpoint(struct Process *proc, struct breakpoint *bp) 584{ 585 struct Process *leader = proc->leader; 586 587 /* Only the group leader should be getting the breakpoints and 588 * thus have ->breakpoint initialized. */ 589 assert(leader != NULL); 590 assert(leader->breakpoints != NULL); 591 592 /* Make sure it wasn't inserted yet. */ 593 assert(bp->proc == NULL); 594 595 debug(DEBUG_FUNCTION, "proc_insert_breakpoint(pid=%d, %s@%p)", 596 proc->pid, breakpoint_name(bp), bp->addr); 597 598 /* XXX We might merge bp->libsym instead of the following 599 * assert, but that's not necessary right now. Look into 600 * breakpoint_for_symbol. */ 601 assert(dict_find_entry(leader->breakpoints, bp->addr) == NULL); 602 603 if (dict_enter(leader->breakpoints, bp->addr, bp) < 0) { 604 error(0, errno, "couldn't enter breakpoint %s@%p to dictionary", 605 breakpoint_name(bp), bp->addr); 606 return -1; 607 } 608 609 bp->proc = proc; 610 return 0; 611} 612 613int 614proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp) 615{ 616 /* XXX We can't, really. We are missing dict_remove. */ 617 assert(!"Not yet implemented!"); 618 abort(); 619} 620