trace.c revision 590c80862c009608fd70e976a282473234d92265
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <errno.h> 5#include <unistd.h> 6#include <sys/types.h> 7#include <sys/wait.h> 8#include "ptrace.h" 9#include <asm/unistd.h> 10#include <assert.h> 11 12#include "common.h" 13 14/* If the system headers did not provide the constants, hard-code the normal 15 values. */ 16#ifndef PTRACE_EVENT_FORK 17 18#define PTRACE_OLDSETOPTIONS 21 19#define PTRACE_SETOPTIONS 0x4200 20#define PTRACE_GETEVENTMSG 0x4201 21 22/* options set using PTRACE_SETOPTIONS */ 23#define PTRACE_O_TRACESYSGOOD 0x00000001 24#define PTRACE_O_TRACEFORK 0x00000002 25#define PTRACE_O_TRACEVFORK 0x00000004 26#define PTRACE_O_TRACECLONE 0x00000008 27#define PTRACE_O_TRACEEXEC 0x00000010 28#define PTRACE_O_TRACEVFORKDONE 0x00000020 29#define PTRACE_O_TRACEEXIT 0x00000040 30 31/* Wait extended result codes for the above trace options. */ 32#define PTRACE_EVENT_FORK 1 33#define PTRACE_EVENT_VFORK 2 34#define PTRACE_EVENT_CLONE 3 35#define PTRACE_EVENT_EXEC 4 36#define PTRACE_EVENT_VFORK_DONE 5 37#define PTRACE_EVENT_EXIT 6 38 39#endif /* PTRACE_EVENT_FORK */ 40 41#ifdef ARCH_HAVE_UMOVELONG 42extern int arch_umovelong (Process *, void *, long *, arg_type_info *); 43int 44umovelong (Process *proc, void *addr, long *result, arg_type_info *info) { 45 return arch_umovelong (proc, addr, result, info); 46} 47#else 48/* Read a single long from the process's memory address 'addr' */ 49int 50umovelong (Process *proc, void *addr, long *result, arg_type_info *info) { 51 long pointed_to; 52 53 errno = 0; 54 pointed_to = ptrace (PTRACE_PEEKTEXT, proc->pid, addr, 0); 55 if (pointed_to == -1 && errno) 56 return -errno; 57 58 *result = pointed_to; 59 if (info) { 60 switch(info->type) { 61 case ARGTYPE_INT: 62 *result &= 0x00000000ffffffffUL; 63 default: 64 break; 65 }; 66 } 67 return 0; 68} 69#endif 70 71void 72trace_me(void) { 73 debug(DEBUG_PROCESS, "trace_me: pid=%d", getpid()); 74 if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) { 75 perror("PTRACE_TRACEME"); 76 exit(1); 77 } 78} 79 80int 81trace_pid(pid_t pid) { 82 debug(DEBUG_PROCESS, "trace_pid: pid=%d", pid); 83 if (ptrace(PTRACE_ATTACH, pid, 1, 0) < 0) { 84 return -1; 85 } 86 87 /* man ptrace: PTRACE_ATTACH attaches to the process specified 88 in pid. The child is sent a SIGSTOP, but will not 89 necessarily have stopped by the completion of this call; 90 use wait() to wait for the child to stop. */ 91 if (waitpid (pid, NULL, __WALL) != pid) { 92 perror ("trace_pid: waitpid"); 93 return -1; 94 } 95 96 return 0; 97} 98 99void 100trace_set_options(Process *proc, pid_t pid) { 101 if (proc->tracesysgood & 0x80) 102 return; 103 104 debug(DEBUG_PROCESS, "trace_set_options: pid=%d", pid); 105 106 long options = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK | 107 PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE | 108 PTRACE_O_TRACEEXEC; 109 if (ptrace(PTRACE_SETOPTIONS, pid, 0, options) < 0 && 110 ptrace(PTRACE_OLDSETOPTIONS, pid, 0, options) < 0) { 111 perror("PTRACE_SETOPTIONS"); 112 return; 113 } 114 proc->tracesysgood |= 0x80; 115} 116 117void 118untrace_pid(pid_t pid) { 119 debug(DEBUG_PROCESS, "untrace_pid: pid=%d", pid); 120 ptrace(PTRACE_DETACH, pid, 1, 0); 121} 122 123void 124continue_after_signal(pid_t pid, int signum) { 125 Process *proc; 126 127 debug(DEBUG_PROCESS, "continue_after_signal: pid=%d, signum=%d", pid, signum); 128 129 proc = pid2proc(pid); 130 ptrace(PTRACE_SYSCALL, pid, 0, signum); 131} 132 133static enum ecb_status 134event_for_pid(Event * event, void * data) 135{ 136 if (event->proc != NULL && event->proc->pid == (pid_t)(uintptr_t)data) 137 return ecb_yield; 138 return ecb_cont; 139} 140 141static int 142have_events_for(pid_t pid) 143{ 144 return each_qd_event(event_for_pid, (void *)(uintptr_t)pid) != NULL; 145} 146 147void 148continue_process(pid_t pid) 149{ 150 debug(DEBUG_PROCESS, "continue_process: pid=%d", pid); 151 152 /* Only really continue the process if there are no events in 153 the queue for this process. Otherwise just for the other 154 events to arrive. */ 155 if (!have_events_for(pid)) 156 /* We always trace syscalls to control fork(), 157 * clone(), execve()... */ 158 ptrace(PTRACE_SYSCALL, pid, 0, 0); 159 else 160 debug(DEBUG_PROCESS, 161 "putting off the continue, events in que."); 162} 163 164/** 165 * This is used for bookkeeping related to PIDs that the event 166 * handlers work with. 167 */ 168struct pid_task { 169 pid_t pid; /* This may be 0 for tasks that exited 170 * mid-handling. */ 171 int sigstopped; 172 int got_event; 173 int delivered; 174} * pids; 175 176struct pid_set { 177 struct pid_task * tasks; 178 size_t count; 179 size_t alloc; 180}; 181 182/** 183 * Breakpoint re-enablement. When we hit a breakpoint, we must 184 * disable it, single-step, and re-enable it. That single-step can be 185 * done only by one task in a task group, while others are stopped, 186 * otherwise the processes would race for who sees the breakpoint 187 * disabled and who doesn't. The following is to keep track of it 188 * all. 189 */ 190struct process_stopping_handler 191{ 192 Event_Handler super; 193 194 /* The task that is doing the re-enablement. */ 195 Process * task_enabling_breakpoint; 196 197 /* The pointer being re-enabled. */ 198 Breakpoint * breakpoint_being_enabled; 199 200 enum { 201 /* We are waiting for everyone to land in t/T. */ 202 psh_stopping = 0, 203 204 /* We are doing the PTRACE_SINGLESTEP. */ 205 psh_singlestep, 206 207 /* We are waiting for all the SIGSTOPs to arrive so 208 * that we can sink them. */ 209 psh_sinking, 210 211 /* This is for tracking the ugly workaround. */ 212 psh_ugly_workaround, 213 } state; 214 215 int exiting; 216 217 struct pid_set pids; 218}; 219 220static enum pcb_status 221task_stopped(Process * task, void * data) 222{ 223 /* If the task is already stopped, don't worry about it. 224 * Likewise if it managed to become a zombie or terminate in 225 * the meantime. This can happen when the whole thread group 226 * is terminating. */ 227 switch (process_status(task->pid)) { 228 case ps_invalid: 229 case ps_tracing_stop: 230 case ps_zombie: 231 return pcb_cont; 232 default: 233 return pcb_stop; 234 } 235} 236 237static struct pid_task * 238get_task_info(struct pid_set * pids, pid_t pid) 239{ 240 assert(pid != 0); 241 size_t i; 242 for (i = 0; i < pids->count; ++i) 243 if (pids->tasks[i].pid == pid) 244 return &pids->tasks[i]; 245 246 return NULL; 247} 248 249static struct pid_task * 250add_task_info(struct pid_set * pids, pid_t pid) 251{ 252 if (pids->count == pids->alloc) { 253 size_t ns = (2 * pids->alloc) ?: 4; 254 struct pid_task * n = realloc(pids->tasks, 255 sizeof(*pids->tasks) * ns); 256 if (n == NULL) 257 return NULL; 258 pids->tasks = n; 259 pids->alloc = ns; 260 } 261 struct pid_task * task_info = &pids->tasks[pids->count++]; 262 memset(task_info, 0, sizeof(*task_info)); 263 task_info->pid = pid; 264 return task_info; 265} 266 267static enum pcb_status 268send_sigstop(Process * task, void * data) 269{ 270 Process * leader = task->leader; 271 struct pid_set * pids = data; 272 273 /* Look for pre-existing task record, or add new. */ 274 struct pid_task * task_info = get_task_info(pids, task->pid); 275 if (task_info == NULL) 276 task_info = add_task_info(pids, task->pid); 277 if (task_info == NULL) { 278 perror("send_sigstop: add_task_info"); 279 destroy_event_handler(leader); 280 /* Signal failure upwards. */ 281 return pcb_stop; 282 } 283 284 /* This task still has not been attached to. It should be 285 stopped by the kernel. */ 286 if (task->state == STATE_BEING_CREATED) 287 return pcb_cont; 288 289 /* Don't bother sending SIGSTOP if we are already stopped, or 290 * if we sent the SIGSTOP already, which happens when we 291 * inherit the handler from breakpoint re-enablement. */ 292 if (task_stopped(task, NULL) == pcb_cont) 293 return pcb_cont; 294 if (task_info->sigstopped) { 295 if (!task_info->delivered) 296 return pcb_cont; 297 task_info->delivered = 0; 298 } 299 300 if (task_kill(task->pid, SIGSTOP) >= 0) { 301 debug(DEBUG_PROCESS, "send SIGSTOP to %d", task->pid); 302 task_info->sigstopped = 1; 303 } else 304 fprintf(stderr, 305 "Warning: couldn't send SIGSTOP to %d\n", task->pid); 306 307 return pcb_cont; 308} 309 310static void 311ugly_workaround(Process * proc, int cont) 312{ 313 void * ip = get_instruction_pointer(proc); 314 Breakpoint * sbp = dict_find_entry(proc->leader->breakpoints, ip); 315 if (sbp != NULL) 316 enable_breakpoint(proc, sbp); 317 else 318 insert_breakpoint(proc, ip, NULL, 1); 319 if (cont) 320 ptrace(PTRACE_CONT, proc->pid, 0, 0); 321} 322 323static void 324process_stopping_done(struct process_stopping_handler * self, Process * leader) 325{ 326 debug(DEBUG_PROCESS, "process stopping done %d", 327 self->task_enabling_breakpoint->pid); 328 size_t i; 329 if (!self->exiting) { 330 for (i = 0; i < self->pids.count; ++i) 331 if (self->pids.tasks[i].pid != 0 332 && self->pids.tasks[i].delivered) 333 continue_process(self->pids.tasks[i].pid); 334 continue_process(self->task_enabling_breakpoint->pid); 335 destroy_event_handler(leader); 336 } else { 337 self->state = psh_ugly_workaround; 338 ugly_workaround(self->task_enabling_breakpoint, 1); 339 } 340} 341 342/* Before we detach, we need to make sure that task's IP is on the 343 * edge of an instruction. So for tasks that have a breakpoint event 344 * in the queue, we adjust the instruction pointer, just like 345 * continue_after_breakpoint does. */ 346static enum ecb_status 347undo_breakpoint(Event * event, void * data) 348{ 349 if (event != NULL 350 && event->proc->leader == data 351 && event->type == EVENT_BREAKPOINT) 352 set_instruction_pointer(event->proc, event->e_un.brk_addr); 353 return ecb_cont; 354} 355 356static enum pcb_status 357untrace_task(Process * task, void * data) 358{ 359 if (task != data) 360 untrace_pid(task->pid); 361 return pcb_cont; 362} 363 364static enum pcb_status 365remove_task(Process * task, void * data) 366{ 367 /* Don't untrace leader just yet. */ 368 if (task != data) 369 remove_process(task); 370 return pcb_cont; 371} 372 373static void 374detach_process(Process * leader) 375{ 376 each_qd_event(&undo_breakpoint, leader); 377 disable_all_breakpoints(leader); 378 379 /* Now untrace the process, if it was attached to by -p. */ 380 struct opt_p_t * it; 381 for (it = opt_p; it != NULL; it = it->next) { 382 Process * proc = pid2proc(it->pid); 383 if (proc == NULL) 384 continue; 385 if (proc->leader == leader) { 386 each_task(leader, &untrace_task, NULL); 387 break; 388 } 389 } 390 each_task(leader, &remove_task, leader); 391 destroy_event_handler(leader); 392 remove_task(leader, NULL); 393} 394 395static void 396handle_stopping_event(struct pid_task * task_info, Event ** eventp) 397{ 398 /* Mark all events, so that we know whom to SIGCONT later. */ 399 if (task_info != NULL) 400 task_info->got_event = 1; 401 402 Event * event = *eventp; 403 404 /* In every state, sink SIGSTOP events for tasks that it was 405 * sent to. */ 406 if (task_info != NULL 407 && event->type == EVENT_SIGNAL 408 && event->e_un.signum == SIGSTOP) { 409 debug(DEBUG_PROCESS, "SIGSTOP delivered to %d", task_info->pid); 410 if (task_info->sigstopped 411 && !task_info->delivered) { 412 task_info->delivered = 1; 413 *eventp = NULL; // sink the event 414 } else 415 fprintf(stderr, "suspicious: %d got SIGSTOP, but " 416 "sigstopped=%d and delivered=%d\n", 417 task_info->pid, task_info->sigstopped, 418 task_info->delivered); 419 } 420} 421 422/* Some SIGSTOPs may have not been delivered to their respective tasks 423 * yet. They are still in the queue. If we have seen an event for 424 * that process, continue it, so that the SIGSTOP can be delivered and 425 * caught by ltrace. */ 426static void 427continue_for_sigstop_delivery(struct pid_set * pids) 428{ 429 size_t i; 430 for (i = 0; i < pids->count; ++i) { 431 if (pids->tasks[i].pid != 0 432 && pids->tasks[i].sigstopped 433 && !pids->tasks[i].delivered 434 && pids->tasks[i].got_event) { 435 debug(DEBUG_PROCESS, "continue %d for SIGSTOP delivery", 436 pids->tasks[i].pid); 437 ptrace(PTRACE_SYSCALL, pids->tasks[i].pid, 0, 0); 438 } 439 } 440} 441 442static int 443event_exit_p(Event * event) 444{ 445 return event != NULL && (event->type == EVENT_EXIT 446 || event->type == EVENT_EXIT_SIGNAL); 447} 448 449static int 450event_exit_or_none_p(Event * event) 451{ 452 return event == NULL || event_exit_p(event) 453 || event->type == EVENT_NONE; 454} 455 456static int 457await_sigstop_delivery(struct pid_set * pids, struct pid_task * task_info, 458 Event * event) 459{ 460 /* If we still didn't get our SIGSTOP, continue the process 461 * and carry on. */ 462 if (event != NULL && !event_exit_or_none_p(event) 463 && task_info != NULL && task_info->sigstopped) { 464 debug(DEBUG_PROCESS, "continue %d for SIGSTOP delivery", 465 task_info->pid); 466 /* We should get the signal the first thing 467 * after this, so it should be OK to continue 468 * even if we are over a breakpoint. */ 469 ptrace(PTRACE_SYSCALL, task_info->pid, 0, 0); 470 471 } else { 472 /* If all SIGSTOPs were delivered, uninstall the 473 * handler and continue everyone. */ 474 /* XXX I suspect that we should check tasks that are 475 * still around. Is things are now, there should be a 476 * race between waiting for everyone to stop and one 477 * of the tasks exiting. */ 478 int all_clear = 1; 479 size_t i; 480 for (i = 0; i < pids->count; ++i) 481 if (pids->tasks[i].pid != 0 482 && pids->tasks[i].sigstopped 483 && !pids->tasks[i].delivered) { 484 all_clear = 0; 485 break; 486 } 487 return all_clear; 488 } 489 490 return 0; 491} 492 493static int 494all_stops_accountable(struct pid_set * pids) 495{ 496 size_t i; 497 for (i = 0; i < pids->count; ++i) 498 if (pids->tasks[i].pid != 0 499 && !pids->tasks[i].got_event 500 && !have_events_for(pids->tasks[i].pid)) 501 return 0; 502 return 1; 503} 504 505/* This event handler is installed when we are in the process of 506 * stopping the whole thread group to do the pointer re-enablement for 507 * one of the threads. We pump all events to the queue for later 508 * processing while we wait for all the threads to stop. When this 509 * happens, we let the re-enablement thread to PTRACE_SINGLESTEP, 510 * re-enable, and continue everyone. */ 511static Event * 512process_stopping_on_event(Event_Handler * super, Event * event) 513{ 514 struct process_stopping_handler * self = (void *)super; 515 Process * task = event->proc; 516 Process * leader = task->leader; 517 Breakpoint * sbp = self->breakpoint_being_enabled; 518 Process * teb = self->task_enabling_breakpoint; 519 520 debug(DEBUG_PROCESS, 521 "pid %d; event type %d; state %d", 522 task->pid, event->type, self->state); 523 524 struct pid_task * task_info = get_task_info(&self->pids, task->pid); 525 if (task_info == NULL) 526 fprintf(stderr, "new task??? %d\n", task->pid); 527 handle_stopping_event(task_info, &event); 528 529 int state = self->state; 530 int event_to_queue = !event_exit_or_none_p(event); 531 532 /* Deactivate the entry if the task exits. */ 533 if (event_exit_p(event) && task_info != NULL) 534 task_info->pid = 0; 535 536 switch (state) { 537 case psh_stopping: 538 /* If everyone is stopped, singlestep. */ 539 if (each_task(leader, &task_stopped, NULL) == NULL) { 540 debug(DEBUG_PROCESS, "all stopped, now SINGLESTEP %d", 541 teb->pid); 542 if (sbp->enabled) 543 disable_breakpoint(teb, sbp); 544 if (ptrace(PTRACE_SINGLESTEP, teb->pid, 0, 0)) 545 perror("PTRACE_SINGLESTEP"); 546 self->state = state = psh_singlestep; 547 } 548 break; 549 550 case psh_singlestep: { 551 /* In singlestep state, breakpoint signifies that we 552 * have now stepped, and can re-enable the breakpoint. */ 553 if (event != NULL && task == teb) { 554 /* Essentially we don't care what event caused 555 * the thread to stop. We can do the 556 * re-enablement now. */ 557 if (sbp->enabled) 558 enable_breakpoint(teb, sbp); 559 560 continue_for_sigstop_delivery(&self->pids); 561 562 self->breakpoint_being_enabled = NULL; 563 self->state = state = psh_sinking; 564 565 if (event->type == EVENT_BREAKPOINT) 566 event = NULL; // handled 567 } else 568 break; 569 } 570 571 /* fall-through */ 572 573 case psh_sinking: 574 if (await_sigstop_delivery(&self->pids, task_info, event)) 575 process_stopping_done(self, leader); 576 break; 577 578 case psh_ugly_workaround: 579 if (event == NULL) 580 break; 581 if (event->type == EVENT_BREAKPOINT) { 582 undo_breakpoint(event, leader); 583 if (task == teb) 584 self->task_enabling_breakpoint = NULL; 585 } 586 if (self->task_enabling_breakpoint == NULL 587 && all_stops_accountable(&self->pids)) { 588 undo_breakpoint(event, leader); 589 detach_process(leader); 590 event = NULL; // handled 591 } 592 } 593 594 if (event != NULL && event_to_queue) { 595 enque_event(event); 596 event = NULL; // sink the event 597 } 598 599 return event; 600} 601 602static void 603process_stopping_destroy(Event_Handler * super) 604{ 605 struct process_stopping_handler * self = (void *)super; 606 free(self->pids.tasks); 607} 608 609void 610continue_after_breakpoint(Process *proc, Breakpoint *sbp) 611{ 612 set_instruction_pointer(proc, sbp->addr); 613 if (sbp->enabled == 0) { 614 continue_process(proc->pid); 615 } else { 616 debug(DEBUG_PROCESS, 617 "continue_after_breakpoint: pid=%d, addr=%p", 618 proc->pid, sbp->addr); 619#if defined __sparc__ || defined __ia64___ || defined __mips__ 620 /* we don't want to singlestep here */ 621 continue_process(proc->pid); 622#else 623 struct process_stopping_handler * handler 624 = calloc(sizeof(*handler), 1); 625 if (handler == NULL) { 626 perror("malloc breakpoint disable handler"); 627 fatal: 628 /* Carry on not bothering to re-enable. */ 629 continue_process(proc->pid); 630 return; 631 } 632 633 handler->super.on_event = process_stopping_on_event; 634 handler->super.destroy = process_stopping_destroy; 635 handler->task_enabling_breakpoint = proc; 636 handler->breakpoint_being_enabled = sbp; 637 install_event_handler(proc->leader, &handler->super); 638 639 if (each_task(proc->leader, &send_sigstop, 640 &handler->pids) != NULL) 641 goto fatal; 642 643 /* And deliver the first fake event, in case all the 644 * conditions are already fulfilled. */ 645 Event ev; 646 ev.type = EVENT_NONE; 647 ev.proc = proc; 648 process_stopping_on_event(&handler->super, &ev); 649#endif 650 } 651} 652 653/** 654 * Ltrace exit. When we are about to exit, we have to go through all 655 * the processes, stop them all, remove all the breakpoints, and then 656 * detach the processes that we attached to using -p. If we left the 657 * other tasks running, they might hit stray return breakpoints and 658 * produce artifacts, so we better stop everyone, even if it's a bit 659 * of extra work. 660 */ 661struct ltrace_exiting_handler 662{ 663 Event_Handler super; 664 struct pid_set pids; 665}; 666 667static Event * 668ltrace_exiting_on_event(Event_Handler * super, Event * event) 669{ 670 struct ltrace_exiting_handler * self = (void *)super; 671 Process * task = event->proc; 672 Process * leader = task->leader; 673 674 debug(DEBUG_PROCESS, "pid %d; event type %d", task->pid, event->type); 675 676 struct pid_task * task_info = get_task_info(&self->pids, task->pid); 677 handle_stopping_event(task_info, &event); 678 679 if (event != NULL && event->type == EVENT_BREAKPOINT) 680 undo_breakpoint(event, leader); 681 682 if (await_sigstop_delivery(&self->pids, task_info, event) 683 && all_stops_accountable(&self->pids)) 684 detach_process(leader); 685 686 /* Sink all non-exit events. We are about to exit, so we 687 * don't bother with queuing them. */ 688 if (event_exit_or_none_p(event)) 689 return event; 690 691 return NULL; 692} 693 694static void 695ltrace_exiting_destroy(Event_Handler * super) 696{ 697 struct ltrace_exiting_handler * self = (void *)super; 698 free(self->pids.tasks); 699} 700 701static int 702ltrace_exiting_install_handler(Process * proc) 703{ 704 /* Only install to leader. */ 705 if (proc->leader != proc) 706 return 0; 707 708 /* Perhaps we are already installed, if the user passed 709 * several -p options that are tasks of one process. */ 710 if (proc->event_handler != NULL 711 && proc->event_handler->on_event == <race_exiting_on_event) 712 return 0; 713 714 /* If stopping handler is already present, let it do the 715 * work. */ 716 if (proc->event_handler != NULL) { 717 assert(proc->event_handler->on_event 718 == &process_stopping_on_event); 719 struct process_stopping_handler * other 720 = (void *)proc->event_handler; 721 other->exiting = 1; 722 return 0; 723 } 724 725 struct ltrace_exiting_handler * handler 726 = calloc(sizeof(*handler), 1); 727 if (handler == NULL) { 728 perror("malloc exiting handler"); 729 fatal: 730 /* XXXXXXXXXXXXXXXXXXX fixme */ 731 return -1; 732 } 733 734 handler->super.on_event = ltrace_exiting_on_event; 735 handler->super.destroy = ltrace_exiting_destroy; 736 install_event_handler(proc->leader, &handler->super); 737 738 if (each_task(proc->leader, &send_sigstop, 739 &handler->pids) != NULL) 740 goto fatal; 741 742 return 0; 743} 744 745/* If ltrace gets SIGINT, the processes directly or indirectly run by 746 * ltrace get it too. We just have to wait long enough for the signal 747 * to be delivered and the process terminated, which we notice and 748 * exit ltrace, too. So there's not much we need to do there. We 749 * want to keep tracing those processes as usual, in case they just 750 * SIG_IGN the SIGINT to do their shutdown etc. 751 * 752 * For processes ran on the background, we want to install an exit 753 * handler that stops all the threads, removes all breakpoints, and 754 * detaches. 755 */ 756void 757ltrace_exiting(void) 758{ 759 struct opt_p_t * it; 760 for (it = opt_p; it != NULL; it = it->next) { 761 Process * proc = pid2proc(it->pid); 762 if (proc == NULL || proc->leader == NULL) 763 continue; 764 if (ltrace_exiting_install_handler(proc->leader) < 0) 765 fprintf(stderr, 766 "Couldn't install exiting handler for %d.\n", 767 proc->pid); 768 } 769} 770 771size_t 772umovebytes(Process *proc, void *addr, void *laddr, size_t len) { 773 774 union { 775 long a; 776 char c[sizeof(long)]; 777 } a; 778 int started = 0; 779 size_t offset = 0, bytes_read = 0; 780 781 while (offset < len) { 782 a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr + offset, 0); 783 if (a.a == -1 && errno) { 784 if (started && errno == EIO) 785 return bytes_read; 786 else 787 return -1; 788 } 789 started = 1; 790 791 if (len - offset >= sizeof(long)) { 792 memcpy(laddr + offset, &a.c[0], sizeof(long)); 793 bytes_read += sizeof(long); 794 } 795 else { 796 memcpy(laddr + offset, &a.c[0], len - offset); 797 bytes_read += (len - offset); 798 } 799 offset += sizeof(long); 800 } 801 802 return bytes_read; 803} 804 805/* Read a series of bytes starting at the process's memory address 806 'addr' and continuing until a NUL ('\0') is seen or 'len' bytes 807 have been read. 808*/ 809int 810umovestr(Process *proc, void *addr, int len, void *laddr) { 811 union { 812 long a; 813 char c[sizeof(long)]; 814 } a; 815 unsigned i; 816 int offset = 0; 817 818 while (offset < len) { 819 a.a = ptrace(PTRACE_PEEKTEXT, proc->pid, addr + offset, 0); 820 for (i = 0; i < sizeof(long); i++) { 821 if (a.c[i] && offset + (signed)i < len) { 822 *(char *)(laddr + offset + i) = a.c[i]; 823 } else { 824 *(char *)(laddr + offset + i) = '\0'; 825 return 0; 826 } 827 } 828 offset += sizeof(long); 829 } 830 *(char *)(laddr + offset) = '\0'; 831 return 0; 832} 833