handle_event.c revision 9847abed1f8a4d01466e9c2a6011b59ea11f6d2f
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. 467 * 468 * XXX TODO It would be nice to have this removed, but then we 469 * need to do that also for initial call to wait_for_proc in 470 * execute_program. In that case we could generate a 471 * EVENT_FIRST event or something, or maybe this could somehow 472 * be rolled into EVENT_NEW. */ 473 wait_for_proc(proc->pid); 474 continue_process(proc->pid); 475} 476 477static void 478handle_arch_syscall(Event *event) { 479 debug(DEBUG_FUNCTION, "handle_arch_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); 480 if (event->proc->state != STATE_IGNORED) { 481 callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum); 482 if (options.syscalls) { 483 output_syscall_left(event->proc, 484 arch_sysname(event->proc, 485 event->e_un.sysnum)); 486 } 487 } 488 continue_process(event->proc->pid); 489} 490 491struct timeval current_time_spent; 492 493static void 494calc_time_spent(Process *proc) { 495 struct timeval tv; 496 struct timezone tz; 497 struct timeval diff; 498 struct callstack_element *elem; 499 500 debug(DEBUG_FUNCTION, "calc_time_spent(pid=%d)", proc->pid); 501 elem = &proc->callstack[proc->callstack_depth - 1]; 502 503 gettimeofday(&tv, &tz); 504 505 diff.tv_sec = tv.tv_sec - elem->time_spent.tv_sec; 506 if (tv.tv_usec >= elem->time_spent.tv_usec) { 507 diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec; 508 } else { 509 diff.tv_sec++; 510 diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec; 511 } 512 current_time_spent = diff; 513} 514 515static void 516handle_sysret(Event *event) { 517 debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); 518 if (event->proc->state != STATE_IGNORED) { 519 if (opt_T || options.summary) { 520 calc_time_spent(event->proc); 521 } 522 if (options.syscalls) 523 output_syscall_right(event->proc, 524 sysname(event->proc, 525 event->e_un.sysnum)); 526 527 assert(event->proc->callstack_depth > 0); 528 unsigned d = event->proc->callstack_depth - 1; 529 assert(event->proc->callstack[d].is_syscall); 530 callstack_pop(event->proc); 531 } 532 continue_after_syscall(event->proc, event->e_un.sysnum, 1); 533} 534 535static void 536handle_arch_sysret(Event *event) { 537 debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum); 538 if (event->proc->state != STATE_IGNORED) { 539 if (opt_T || options.summary) { 540 calc_time_spent(event->proc); 541 } 542 if (options.syscalls) 543 output_syscall_right(event->proc, 544 arch_sysname(event->proc, 545 event->e_un.sysnum)); 546 callstack_pop(event->proc); 547 } 548 continue_process(event->proc->pid); 549} 550 551static void 552output_right_tos(struct Process *proc) 553{ 554 size_t d = proc->callstack_depth; 555 struct callstack_element *elem = &proc->callstack[d - 1]; 556 if (proc->state != STATE_IGNORED) 557 output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc->name); 558} 559 560static void 561handle_breakpoint(Event *event) 562{ 563 int i, j; 564 struct breakpoint *sbp; 565 Process *leader = event->proc->leader; 566 void *brk_addr = event->e_un.brk_addr; 567 568 /* The leader has terminated. */ 569 if (leader == NULL) { 570 continue_process(event->proc->pid); 571 return; 572 } 573 574 debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)", 575 event->proc->pid, brk_addr); 576 debug(2, "event: breakpoint (%p)", brk_addr); 577 578 for (i = event->proc->callstack_depth - 1; i >= 0; i--) { 579 if (brk_addr == event->proc->callstack[i].return_addr) { 580#if defined(__mips__) 581 void *addr = NULL; 582 struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc; 583 struct library_symbol *new_sym; 584 assert(sym); 585 addr = sym2addr(event->proc, sym); 586 sbp = dict_find_entry(leader->breakpoints, addr); 587 if (sbp) { 588 if (addr != sbp->addr) { 589 insert_breakpoint(event->proc, addr, sym); 590 } 591 } else { 592 new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1); 593 memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1); 594 new_sym->next = leader->list_of_symbols; 595 leader->list_of_symbols = new_sym; 596 insert_breakpoint(event->proc, addr, new_sym); 597 } 598#endif 599 for (j = event->proc->callstack_depth - 1; j > i; j--) { 600 callstack_pop(event->proc); 601 } 602 if (event->proc->state != STATE_IGNORED) { 603 if (opt_T || options.summary) { 604 calc_time_spent(event->proc); 605 } 606 } 607 event->proc->return_addr = brk_addr; 608 609 output_right_tos(event->proc); 610 callstack_pop(event->proc); 611 612 /* Pop also any other entries that seem like 613 * they are linked to the current one: they 614 * have the same return address, but were made 615 * for different symbols. This should only 616 * happen for entry point tracing, i.e. for -x 617 * everywhere, or -x and -e on PPC64. */ 618 while (event->proc->callstack_depth > 0) { 619 struct callstack_element *prev; 620 size_t d = event->proc->callstack_depth; 621 prev = &event->proc->callstack[d - 1]; 622 623 if (prev->c_un.libfunc == libsym 624 || prev->return_addr != brk_addr) 625 break; 626 627 output_right_tos(event->proc); 628 callstack_pop(event->proc); 629 } 630 631 sbp = address2bpstruct(leader, brk_addr); 632 continue_after_breakpoint(event->proc, sbp); 633 return; 634 } 635 } 636 637 if ((sbp = address2bpstruct(leader, brk_addr))) { 638 breakpoint_on_hit(sbp, event->proc); 639 640 if (event->proc->state != STATE_IGNORED 641 && sbp->libsym != NULL) { 642 event->proc->stack_pointer = get_stack_pointer(event->proc); 643 event->proc->return_addr = 644 get_return_addr(event->proc, event->proc->stack_pointer); 645 callstack_push_symfunc(event->proc, sbp->libsym); 646 output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym); 647 } 648 649 breakpoint_on_continue(sbp, event->proc); 650 return; 651 } 652 653 if (event->proc->state != STATE_IGNORED) 654 output_line(event->proc, "unexpected breakpoint at %p", 655 brk_addr); 656 657 continue_process(event->proc->pid); 658} 659 660static void 661callstack_push_syscall(Process *proc, int sysnum) { 662 struct callstack_element *elem; 663 664 debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum); 665 /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */ 666 if (proc->callstack_depth == MAX_CALLDEPTH - 1) { 667 fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__); 668 abort(); 669 return; 670 } 671 672 elem = &proc->callstack[proc->callstack_depth]; 673 elem->is_syscall = 1; 674 elem->c_un.syscall = sysnum; 675 elem->return_addr = NULL; 676 677 proc->callstack_depth++; 678 if (opt_T || options.summary) { 679 struct timezone tz; 680 gettimeofday(&elem->time_spent, &tz); 681 } 682} 683 684static void 685callstack_push_symfunc(Process *proc, struct library_symbol *sym) { 686 struct callstack_element *elem; 687 688 debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name); 689 /* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */ 690 if (proc->callstack_depth == MAX_CALLDEPTH - 1) { 691 fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__); 692 abort(); 693 return; 694 } 695 696 elem = &proc->callstack[proc->callstack_depth++]; 697 elem->is_syscall = 0; 698 elem->c_un.libfunc = sym; 699 700 elem->return_addr = proc->return_addr; 701 if (elem->return_addr) 702 insert_breakpoint(proc, elem->return_addr, NULL); 703 704 /* handle functions like atexit() on mips which have no return */ 705 if (opt_T || options.summary) { 706 struct timezone tz; 707 gettimeofday(&elem->time_spent, &tz); 708 } 709} 710 711static void 712callstack_pop(Process *proc) { 713 struct callstack_element *elem; 714 assert(proc->callstack_depth > 0); 715 716 debug(DEBUG_FUNCTION, "callstack_pop(pid=%d)", proc->pid); 717 elem = &proc->callstack[proc->callstack_depth - 1]; 718 if (!elem->is_syscall && elem->return_addr) { 719 assert(proc->leader != NULL); 720 delete_breakpoint(proc, elem->return_addr); 721 } 722 if (elem->arch_ptr != NULL) { 723 free(elem->arch_ptr); 724 elem->arch_ptr = NULL; 725 } 726 proc->callstack_depth--; 727} 728