libltrace.c revision 75934ad3b30790f6a892069576d0790a351ef101
1#include "config.h" 2 3#include <sys/param.h> 4#include <sys/wait.h> 5#include <errno.h> 6#include <error.h> 7#include <signal.h> 8#include <stdio.h> 9#include <stdlib.h> 10#include <string.h> 11#include <unistd.h> 12 13#include "common.h" 14#include "proc.h" 15 16char *command = NULL; 17 18int exiting = 0; /* =1 if a SIGINT or SIGTERM has been received */ 19 20static enum callback_status 21stop_non_p_processes(Process *proc, void *data) 22{ 23 int stop = 1; 24 25 struct opt_p_t *it; 26 for (it = opt_p; it != NULL; it = it->next) { 27 Process * p_proc = pid2proc(it->pid); 28 if (p_proc == NULL) { 29 printf("stop_non_p_processes: %d terminated?\n", it->pid); 30 continue; 31 } 32 if (p_proc == proc || p_proc->leader == proc->leader) { 33 stop = 0; 34 break; 35 } 36 } 37 38 if (stop) { 39 debug(2, "Sending SIGSTOP to process %u", proc->pid); 40 kill(proc->pid, SIGSTOP); 41 } 42 43 return CBS_CONT; 44} 45 46static void 47signal_alarm(int sig) { 48 signal(SIGALRM, SIG_DFL); 49 each_process(NULL, &stop_non_p_processes, NULL); 50} 51 52static void 53signal_exit(int sig) 54{ 55 debug(1, "Received interrupt signal; exiting..."); 56 if (exiting != 0) 57 return; 58 59 exiting = 1 + !!os_ltrace_exiting_sighandler(); 60 61 signal(SIGINT, SIG_IGN); 62 signal(SIGTERM, SIG_IGN); 63 signal(SIGALRM, signal_alarm); 64 //alarm(1); 65} 66 67static void 68normal_exit(void) { 69 output_line(0, 0); 70 if (options.summary) { 71 show_summary(); 72 } 73 if (options.output) { 74 fclose(options.output); 75 options.output = NULL; 76 } 77} 78 79void 80ltrace_init(int argc, char **argv) { 81 struct opt_p_t *opt_p_tmp; 82 83 atexit(normal_exit); 84 signal(SIGINT, signal_exit); /* Detach processes when interrupted */ 85 signal(SIGTERM, signal_exit); /* ... or killed */ 86 87 argv = process_options(argc, argv); 88 while (opt_F) { 89 /* If filename begins with ~, expand it to the user's home */ 90 /* directory. This does not correctly handle ~yoda, but that */ 91 /* isn't as bad as it seems because the shell will normally */ 92 /* be doing the expansion for us; only the hardcoded */ 93 /* ~/.ltrace.conf should ever use this code. */ 94 if (opt_F->filename[0] == '~') { 95 char path[PATH_MAX]; 96 char *home_dir = getenv("HOME"); 97 if (home_dir) { 98 strncpy(path, home_dir, PATH_MAX - 1); 99 path[PATH_MAX - 1] = '\0'; 100 strncat(path, opt_F->filename + 1, 101 PATH_MAX - strlen(path) - 1); 102 read_config_file(path); 103 } 104 } else { 105 read_config_file(opt_F->filename); 106 } 107 opt_F = opt_F->next; 108 } 109 if (command) { 110 /* Check that the binary ABI is supported before 111 * calling execute_program. */ 112 struct ltelf lte = {}; 113 open_elf(<e, command); 114 115 pid_t pid = execute_program(command, argv); 116 struct Process *proc = open_program(command, pid); 117 if (proc == NULL) 118 error(EXIT_FAILURE, errno, 119 "couldn't open program '%s'", command); 120 121 trace_set_options(proc); 122 continue_process(pid); 123 } 124 opt_p_tmp = opt_p; 125 while (opt_p_tmp) { 126 open_pid(opt_p_tmp->pid); 127 opt_p_tmp = opt_p_tmp->next; 128 } 129} 130 131static int num_ltrace_callbacks[EVENT_MAX]; 132static callback_func * ltrace_callbacks[EVENT_MAX]; 133 134void 135ltrace_add_callback(callback_func func, Event_type type) { 136 ltrace_callbacks[type] = realloc(ltrace_callbacks[type], (num_ltrace_callbacks[type]+1)*sizeof(callback_func)); 137 ltrace_callbacks[type][num_ltrace_callbacks[type]++] = func; 138} 139 140static void 141dispatch_callbacks(Event * ev) { 142 int i; 143 /* Ignoring case 1: signal into a dying tracer */ 144 if (ev->type==EVENT_SIGNAL && 145 exiting && ev->e_un.signum == SIGSTOP) { 146 return; 147 } 148 /* Ignoring case 2: process being born before a clone event */ 149 if (ev->proc && ev->proc->state == STATE_IGNORED) { 150 return; 151 } 152 for (i=0; i<num_ltrace_callbacks[ev->type]; i++) { 153 ltrace_callbacks[ev->type][i](ev); 154 } 155} 156 157void 158ltrace_main(void) { 159 Event * ev; 160 while (1) { 161 ev = next_event(); 162 dispatch_callbacks(ev); 163 handle_event(ev); 164 } 165} 166