handle_event.c revision 4e6c437e54f8308f12c4b09dd38515a0e9b895c6
1#define _GNU_SOURCE 2#include "config.h" 3 4#include <stdio.h> 5#include <string.h> 6#include <stdlib.h> 7#include <signal.h> 8#include <assert.h> 9#include <sys/time.h> 10#include <errno.h> 11 12#ifdef __powerpc__ 13#include <sys/ptrace.h> 14#endif 15 16#include "common.h" 17#include "breakpoint.h" 18#include "proc.h" 19#include "library.h" 20 21static void handle_signal(Event *event); 22static void handle_exit(Event *event); 23static void handle_exit_signal(Event *event); 24static void handle_syscall(Event *event); 25static void handle_arch_syscall(Event *event); 26static void handle_sysret(Event *event); 27static void handle_arch_sysret(Event *event); 28static void handle_clone(Event *event); 29static void handle_exec(Event *event); 30static void handle_breakpoint(Event *event); 31static void handle_new(Event *event); 32 33static void callstack_push_syscall(Process *proc, int sysnum); 34static void callstack_push_symfunc(Process *proc, 35 struct library_symbol *sym); 36static void callstack_pop(Process *proc); 37 38static char * shortsignal(Process *proc, int signum); 39static char * sysname(Process *proc, int sysnum); 40static char * arch_sysname(Process *proc, int sysnum); 41 42static Event * 43call_handler(Process * proc, Event * event) 44{ 45 assert(proc != NULL); 46 47 struct event_handler *handler = proc->event_handler; 48 if (handler == NULL) 49 return event; 50 51 return (*handler->on_event) (handler, event); 52} 53 54void 55handle_event(Event *event) 56{ 57 if (exiting == 1) { 58 debug(1, "ltrace about to exit"); 59 os_ltrace_exiting(); 60 exiting = 2; 61 } 62 debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)", 63 event->proc ? event->proc->pid : -1, event->type); 64 65 /* If the thread group or an individual task define an 66 overriding event handler, give them a chance to kick in. 67 We will end up calling both handlers, if the first one 68 doesn't sink the event. */ 69 if (event->proc != NULL) { 70 event = call_handler(event->proc, event); 71 if (event == NULL) 72 /* It was handled. */ 73 return; 74 75 /* Note: the previous handler has a chance to alter 76 * the event. */ 77 if (event->proc != NULL 78 && event->proc->leader != NULL 79 && event->proc != event->proc->leader) { 80 event = call_handler(event->proc->leader, event); 81 if (event == NULL) 82 return; 83 } 84 } 85 86 switch (event->type) { 87 case EVENT_NONE: 88 debug(1, "event: none"); 89 return; 90 case EVENT_SIGNAL: 91 debug(1, "[%d] event: signal (%s [%d])", 92 event->proc->pid, 93 shortsignal(event->proc, event->e_un.signum), 94 event->e_un.signum); 95 handle_signal(event); 96 return; 97 case EVENT_EXIT: 98 debug(1, "[%d] event: exit (%d)", 99 event->proc->pid, 100 event->e_un.ret_val); 101 handle_exit(event); 102 return; 103 case EVENT_EXIT_SIGNAL: 104 debug(1, "[%d] event: exit signal (%s [%d])", 105 event->proc->pid, 106 shortsignal(event->proc, event->e_un.signum), 107 event->e_un.signum); 108 handle_exit_signal(event); 109 return; 110 case EVENT_SYSCALL: 111 debug(1, "[%d] event: syscall (%s [%d])", 112 event->proc->pid, 113 sysname(event->proc, event->e_un.sysnum), 114 event->e_un.sysnum); 115 handle_syscall(event); 116 return; 117 case EVENT_SYSRET: 118 debug(1, "[%d] event: sysret (%s [%d])", 119 event->proc->pid, 120 sysname(event->proc, event->e_un.sysnum), 121 event->e_un.sysnum); 122 handle_sysret(event); 123 return; 124 case EVENT_ARCH_SYSCALL: 125 debug(1, "[%d] event: arch_syscall (%s [%d])", 126 event->proc->pid, 127 arch_sysname(event->proc, event->e_un.sysnum), 128 event->e_un.sysnum); 129 handle_arch_syscall(event); 130 return; 131 case EVENT_ARCH_SYSRET: 132 debug(1, "[%d] event: arch_sysret (%s [%d])", 133 event->proc->pid, 134 arch_sysname(event->proc, event->e_un.sysnum), 135 event->e_un.sysnum); 136 handle_arch_sysret(event); 137 return; 138 case EVENT_CLONE: 139 case EVENT_VFORK: 140 debug(1, "[%d] event: clone (%u)", 141 event->proc->pid, event->e_un.newpid); 142 handle_clone(event); 143 return; 144 case EVENT_EXEC: 145 debug(1, "[%d] event: exec()", 146 event->proc->pid); 147 handle_exec(event); 148 return; 149 case EVENT_BREAKPOINT: 150 debug(1, "[%d] event: breakpoint %p", 151 event->proc->pid, event->e_un.brk_addr); 152 handle_breakpoint(event); 153 return; 154 case EVENT_NEW: 155 debug(1, "[%d] event: new process", 156 event->e_un.newpid); 157 handle_new(event); 158 return; 159 default: 160 fprintf(stderr, "Error! unknown event?\n"); 161 exit(1); 162 } 163} 164 165typedef struct Pending_New Pending_New; 166struct Pending_New { 167 pid_t pid; 168 Pending_New * next; 169}; 170static Pending_New * pending_news = NULL; 171 172static int 173pending_new(pid_t pid) { 174 Pending_New * p; 175 176 debug(DEBUG_FUNCTION, "pending_new(%d)", pid); 177 178 p = pending_news; 179 while (p) { 180 if (p->pid == pid) { 181 return 1; 182 } 183 p = p->next; 184 } 185 return 0; 186} 187 188static void 189pending_new_insert(pid_t pid) { 190 Pending_New * p; 191 192 debug(DEBUG_FUNCTION, "pending_new_insert(%d)", pid); 193 194 p = malloc(sizeof(Pending_New)); 195 if (!p) { 196 perror("malloc()"); 197 exit(1); 198 } 199 p->pid = pid; 200 p->next = pending_news; 201 pending_news = p; 202} 203 204static void 205pending_new_remove(pid_t pid) { 206 Pending_New *p, *pred; 207 208 debug(DEBUG_FUNCTION, "pending_new_remove(%d)", pid); 209 210 p = pending_news; 211 if (p->pid == pid) { 212 pending_news = p->next; 213 free(p); 214 } else { 215 while (p) { 216 if (p->pid == pid) { 217 pred->next = p->next; 218 free(p); 219 } 220 pred = p; 221 p = p->next; 222 } 223 } 224} 225 226static void 227handle_clone(Event *event) 228{ 229 debug(DEBUG_FUNCTION, "handle_clone(pid=%d)", event->proc->pid); 230 231 struct Process *proc = malloc(sizeof(*proc)); 232 if (proc == NULL) { 233 fail: 234 free(proc); 235 /* XXX proper error handling here, please. */ 236 perror("malloc()"); 237 exit(1); 238 } 239 240 if (process_clone(proc, event->proc, event->e_un.newpid) < 0) 241 goto fail; 242 proc->parent = event->proc; 243 244 /* We save register values to the arch pointer, and these need 245 to be per-thread. */ 246 proc->arch_ptr = NULL; 247 248 if (pending_new(proc->pid)) { 249 pending_new_remove(proc->pid); 250 /* XXX this used to be destroy_event_handler call, but 251 * I don't think we want to call that on a shared 252 * state. */ 253 proc->event_handler = NULL; 254 if (event->proc->state == STATE_ATTACHED && options.follow) 255 proc->state = STATE_ATTACHED; 256 else 257 proc->state = STATE_IGNORED; 258 continue_process(proc->pid); 259 } else { 260 proc->state = STATE_BEING_CREATED; 261 } 262 263 if (event->type == EVENT_VFORK) 264 continue_after_vfork(proc); 265 else 266 continue_process(event->proc->pid); 267} 268 269static void 270handle_new(Event * event) { 271 Process * proc; 272 273 debug(DEBUG_FUNCTION, "handle_new(pid=%d)", event->e_un.newpid); 274 275 proc = pid2proc(event->e_un.newpid); 276 if (!proc) { 277 pending_new_insert(event->e_un.newpid); 278 } else { 279 assert(proc->state == STATE_BEING_CREATED); 280 if (options.follow) { 281 proc->state = STATE_ATTACHED; 282 } else { 283 proc->state = STATE_IGNORED; 284 } 285 continue_process(proc->pid); 286 } 287} 288 289static char * 290shortsignal(Process *proc, int signum) { 291 static char *signalent0[] = { 292#include "signalent.h" 293 }; 294 static char *signalent1[] = { 295#include "signalent1.h" 296 }; 297 static char **signalents[] = { signalent0, signalent1 }; 298 int nsignals[] = { sizeof signalent0 / sizeof signalent0[0], 299 sizeof signalent1 / sizeof signalent1[0] 300 }; 301 302 debug(DEBUG_FUNCTION, "shortsignal(pid=%d, signum=%d)", proc->pid, signum); 303 304 if (proc->personality > sizeof signalents / sizeof signalents[0]) 305 abort(); 306 if (signum < 0 || signum >= nsignals[proc->personality]) { 307 return "UNKNOWN_SIGNAL"; 308 } else { 309 return signalents[proc->personality][signum]; 310 } 311} 312 313static char * 314sysname(Process *proc, int sysnum) { 315 static char result[128]; 316 static char *syscalent0[] = { 317#include "syscallent.h" 318 }; 319 static char *syscalent1[] = { 320#include "syscallent1.h" 321 }; 322 static char **syscalents[] = { syscalent0, syscalent1 }; 323 int nsyscals[] = { sizeof syscalent0 / sizeof syscalent0[0], 324 sizeof syscalent1 / sizeof syscalent1[0] 325 }; 326 327 debug(DEBUG_FUNCTION, "sysname(pid=%d, sysnum=%d)", proc->pid, sysnum); 328 329 if (proc->personality > sizeof syscalents / sizeof syscalents[0]) 330 abort(); 331 if (sysnum < 0 || sysnum >= nsyscals[proc->personality]) { 332 sprintf(result, "SYS_%d", sysnum); 333 return result; 334 } else { 335 sprintf(result, "SYS_%s", 336 syscalents[proc->personality][sysnum]); 337 return result; 338 } 339} 340 341static char * 342arch_sysname(Process *proc, int sysnum) { 343 static char result[128]; 344 static char *arch_syscalent[] = { 345#include "arch_syscallent.h" 346 }; 347 int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0]; 348 349 debug(DEBUG_FUNCTION, "arch_sysname(pid=%d, sysnum=%d)", proc->pid, sysnum); 350 351 if (sysnum < 0 || sysnum >= nsyscals) { 352 sprintf(result, "ARCH_%d", sysnum); 353 return result; 354 } else { 355 sprintf(result, "ARCH_%s", 356 arch_syscalent[sysnum]); 357 return result; 358 } 359} 360 361static void 362handle_signal(Event *event) { 363 debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum); 364 if (event->proc->state != STATE_IGNORED && !options.no_signals) { 365 output_line(event->proc, "--- %s (%s) ---", 366 shortsignal(event->proc, event->e_un.signum), 367 strsignal(event->e_un.signum)); 368 } 369 continue_after_signal(event->proc->pid, event->e_un.signum); 370} 371 372static void 373handle_exit(Event *event) { 374 debug(DEBUG_FUNCTION, "handle_exit(pid=%d, status=%d)", event->proc->pid, event->e_un.ret_val); 375 if (event->proc->state != STATE_IGNORED) { 376 output_line(event->proc, "+++ exited (status %d) +++", 377 event->e_un.ret_val); 378 } 379 remove_process(event->proc); 380 free(event->proc); 381} 382 383static void 384handle_exit_signal(Event *event) { 385 debug(DEBUG_FUNCTION, "handle_exit_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum); 386 if (event->proc->state != STATE_IGNORED) { 387 output_line(event->proc, "+++ killed by %s +++", 388 shortsignal(event->proc, event->e_un.signum)); 389 } 390 remove_process(event->proc); 391 free(event->proc); 392} 393 394static struct library_symbol * 395temporary_syscall_symbol(const char *name) 396{ 397 struct library *syscalls = malloc(sizeof(*syscalls)); 398 struct library_symbol *syscall = malloc(sizeof(*syscall)); 399 if (syscalls == NULL || syscall == NULL) { 400 free(syscalls); 401 free(syscall); 402 return NULL; 403 } 404 library_init(syscalls, (enum library_type)-1); 405 library_set_soname(syscalls, "SYS", 0); 406 library_symbol_init(syscall, 0, name, 0, LS_TOPLT_NONE); 407 library_add_symbol(syscalls, syscall); 408 return syscall; 409} 410 411static void 412output_syscall_left(struct Process *proc, const char *name) 413{ 414 struct library_symbol *syscall = temporary_syscall_symbol(name); 415 output_left(LT_TOF_SYSCALL, proc, syscall); 416 struct library *lib = syscall->lib; 417 library_destroy(lib); 418 free(lib); 419} 420 421static void 422output_syscall_right(struct Process *proc, const char *name) 423{ 424 struct library_symbol *syscall = temporary_syscall_symbol(name); 425 output_right(LT_TOF_SYSCALLR, proc, syscall); 426 struct library *lib = syscall->lib; 427 library_destroy(lib); 428 free(lib); 429} 430 431static void 432handle_syscall(Event *event) { 433 debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); 434 if (event->proc->state != STATE_IGNORED) { 435 callstack_push_syscall(event->proc, event->e_un.sysnum); 436 if (options.syscalls) 437 output_syscall_left(event->proc, 438 sysname(event->proc, 439 event->e_un.sysnum)); 440 } 441 continue_after_syscall(event->proc, event->e_un.sysnum, 0); 442} 443 444static void 445handle_exec(Event * event) { 446 Process * proc = event->proc; 447 448 debug(DEBUG_FUNCTION, "handle_exec(pid=%d)", proc->pid); 449 if (proc->state == STATE_IGNORED) { 450 untrace_pid(proc->pid); 451 remove_process(proc); 452 free(proc); 453 return; 454 } 455 output_line(proc, "--- Called exec() ---"); 456 proc->mask_32bit = 0; 457 proc->personality = 0; 458 proc->arch_ptr = NULL; 459 free(proc->filename); 460 proc->filename = pid2name(proc->pid); 461 breakpoints_init(proc, 0); 462 proc->callstack_depth = 0; 463 continue_process(proc->pid); 464 465 /* After the exec, we expect to hit the first executable 466 * instruction. It would be nice to have this removed, but 467 * then we need to do that also for initial call to 468 * wait_for_proc in execute_program. XXX todo. */ 469 wait_for_proc(proc->pid); 470 continue_process(proc->pid); 471} 472 473static void 474handle_arch_syscall(Event *event) { 475 debug(DEBUG_FUNCTION, "handle_arch_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); 476 if (event->proc->state != STATE_IGNORED) { 477 callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum); 478 if (options.syscalls) { 479 output_syscall_left(event->proc, 480 arch_sysname(event->proc, 481 event->e_un.sysnum)); 482 } 483 } 484 continue_process(event->proc->pid); 485} 486 487struct timeval current_time_spent; 488 489static void 490calc_time_spent(Process *proc) { 491 struct timeval tv; 492 struct timezone tz; 493 struct timeval diff; 494 struct callstack_element *elem; 495 496 debug(DEBUG_FUNCTION, "calc_time_spent(pid=%d)", proc->pid); 497 elem = &proc->callstack[proc->callstack_depth - 1]; 498 499 gettimeofday(&tv, &tz); 500 501 diff.tv_sec = tv.tv_sec - elem->time_spent.tv_sec; 502 if (tv.tv_usec >= elem->time_spent.tv_usec) { 503 diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec; 504 } else { 505 diff.tv_sec++; 506 diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec; 507 } 508 current_time_spent = diff; 509} 510 511static void 512handle_sysret(Event *event) { 513 debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); 514 if (event->proc->state != STATE_IGNORED) { 515 if (opt_T || options.summary) { 516 calc_time_spent(event->proc); 517 } 518 if (options.syscalls) 519 output_syscall_right(event->proc, 520 sysname(event->proc, 521 event->e_un.sysnum)); 522 523 assert(event->proc->callstack_depth > 0); 524 unsigned d = event->proc->callstack_depth - 1; 525 assert(event->proc->callstack[d].is_syscall); 526 callstack_pop(event->proc); 527 } 528 continue_after_syscall(event->proc, event->e_un.sysnum, 1); 529} 530 531static void 532handle_arch_sysret(Event *event) { 533 debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); 534 if (event->proc->state != STATE_IGNORED) { 535 if (opt_T || options.summary) { 536 calc_time_spent(event->proc); 537 } 538 if (options.syscalls) 539 output_syscall_right(event->proc, 540 arch_sysname(event->proc, 541 event->e_un.sysnum)); 542 callstack_pop(event->proc); 543 } 544 continue_process(event->proc->pid); 545} 546 547static void 548output_right_tos(struct Process *proc) 549{ 550 size_t d = proc->callstack_depth; 551 struct callstack_element *elem = &proc->callstack[d - 1]; 552 if (proc->state != STATE_IGNORED) 553 output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc->name); 554} 555 556static void 557handle_breakpoint(Event *event) 558{ 559 int i, j; 560 struct breakpoint *sbp; 561 Process *leader = event->proc->leader; 562 void *brk_addr = event->e_un.brk_addr; 563 564 /* The leader has terminated. */ 565 if (leader == NULL) { 566 continue_process(event->proc->pid); 567 return; 568 } 569 570 debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)", 571 event->proc->pid, brk_addr); 572 debug(2, "event: breakpoint (%p)", brk_addr); 573 574 for (i = event->proc->callstack_depth - 1; i >= 0; i--) { 575 if (brk_addr == event->proc->callstack[i].return_addr) { 576#if defined(__mips__) 577 void *addr = NULL; 578 struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc; 579 struct library_symbol *new_sym; 580 assert(sym); 581 addr = sym2addr(event->proc, sym); 582 sbp = dict_find_entry(leader->breakpoints, addr); 583 if (sbp) { 584 if (addr != sbp->addr) { 585 insert_breakpoint(event->proc, addr, sym); 586 } 587 } else { 588 new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1); 589 memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1); 590 new_sym->next = leader->list_of_symbols; 591 leader->list_of_symbols = new_sym; 592 insert_breakpoint(event->proc, addr, new_sym); 593 } 594#endif 595 for (j = event->proc->callstack_depth - 1; j > i; j--) { 596 callstack_pop(event->proc); 597 } 598 if (event->proc->state != STATE_IGNORED) { 599 if (opt_T || options.summary) { 600 calc_time_spent(event->proc); 601 } 602 } 603 event->proc->return_addr = brk_addr; 604 605 output_right_tos(event->proc); 606 callstack_pop(event->proc); 607 608 /* Pop also any other entries that seem like 609 * they are linked to the current one: they 610 * have the same return address, but were made 611 * for different symbols. This should only 612 * happen for entry point tracing, i.e. for -x 613 * everywhere, or -x and -e on PPC64. */ 614 while (event->proc->callstack_depth > 0) { 615 struct callstack_element *prev; 616 size_t d = event->proc->callstack_depth; 617 prev = &event->proc->callstack[d - 1]; 618 619 if (prev->c_un.libfunc == libsym 620 || prev->return_addr != brk_addr) 621 break; 622 623 output_right_tos(event->proc); 624 callstack_pop(event->proc); 625 } 626 627 sbp = address2bpstruct(leader, brk_addr); 628 continue_after_breakpoint(event->proc, sbp); 629 return; 630 } 631 } 632 633 if ((sbp = address2bpstruct(leader, brk_addr))) { 634 breakpoint_on_hit(sbp, event->proc); 635 636 if (event->proc->state != STATE_IGNORED 637 && sbp->libsym != NULL) { 638 event->proc->stack_pointer = get_stack_pointer(event->proc); 639 event->proc->return_addr = 640 get_return_addr(event->proc, event->proc->stack_pointer); 641 callstack_push_symfunc(event->proc, sbp->libsym); 642 output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym); 643 } 644 645 breakpoint_on_continue(sbp, event->proc); 646 return; 647 } 648 649 if (event->proc->state != STATE_IGNORED) 650 output_line(event->proc, "unexpected breakpoint at %p", 651 brk_addr); 652 653 continue_process(event->proc->pid); 654} 655 656static void 657callstack_push_syscall(Process *proc, int sysnum) { 658 struct callstack_element *elem; 659 660 debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum); 661 /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */ 662 if (proc->callstack_depth == MAX_CALLDEPTH - 1) { 663 fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__); 664 abort(); 665 return; 666 } 667 668 elem = &proc->callstack[proc->callstack_depth]; 669 elem->is_syscall = 1; 670 elem->c_un.syscall = sysnum; 671 elem->return_addr = NULL; 672 673 proc->callstack_depth++; 674 if (opt_T || options.summary) { 675 struct timezone tz; 676 gettimeofday(&elem->time_spent, &tz); 677 } 678} 679 680static void 681callstack_push_symfunc(Process *proc, struct library_symbol *sym) { 682 struct callstack_element *elem; 683 684 debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name); 685 /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */ 686 if (proc->callstack_depth == MAX_CALLDEPTH - 1) { 687 fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__); 688 abort(); 689 return; 690 } 691 692 elem = &proc->callstack[proc->callstack_depth++]; 693 elem->is_syscall = 0; 694 elem->c_un.libfunc = sym; 695 696 elem->return_addr = proc->return_addr; 697 if (elem->return_addr) 698 insert_breakpoint(proc, elem->return_addr, NULL); 699 700 /* handle functions like atexit() on mips which have no return */ 701 if (opt_T || options.summary) { 702 struct timezone tz; 703 gettimeofday(&elem->time_spent, &tz); 704 } 705} 706 707static void 708callstack_pop(Process *proc) { 709 struct callstack_element *elem; 710 assert(proc->callstack_depth > 0); 711 712 debug(DEBUG_FUNCTION, "callstack_pop(pid=%d)", proc->pid); 713 elem = &proc->callstack[proc->callstack_depth - 1]; 714 if (!elem->is_syscall && elem->return_addr) { 715 assert(proc->leader != NULL); 716 delete_breakpoint(proc, elem->return_addr); 717 } 718 if (elem->arch_ptr != NULL) { 719 free(elem->arch_ptr); 720 elem->arch_ptr = NULL; 721 } 722 proc->callstack_depth--; 723} 724