~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/arch/um/kernel/trap_user.c

Version: ~ [ 0.6-2.3.46 ] ~
Architecture: ~ [ um ] ~

** Warning: Cannot open xref database.

1 #include <stdio.h> 2 #include <unistd.h> 3 #include <signal.h> 4 #include <errno.h> 5 #include <sched.h> 6 #include <sys/ptrace.h> 7 #include <sys/time.h> 8 #include <sys/wait.h> 9 #include <sys/mman.h> 10 #include <asm/page.h> 11 #include <asm/unistd.h> 12 #include <asm/ptrace.h> 13 #include "user_util.h" 14 #include "kern_util.h" 15 #include "user.h" 16 17 static void signal_segv(int sig) 18 { 19 write(2, "Seg fault in signals\n", strlen("Seg fault in signals\n")); 20 stop(); 21 } 22 23 int detach(int pid) 24 { 25 return(ptrace(PTRACE_DETACH, pid, 0, SIGSTOP)); 26 } 27 28 static int signal_tramp(void *arg) 29 { 30 int (*proc)(void *); 31 32 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) 33 panic("ptrace PTRACE_TRACEME failed"); 34 signal(SIGUSR1, SIG_IGN); 35 set_timers(); 36 set_cmdline("(idle thread)"); 37 proc = arg; 38 return((*proc)(NULL)); 39 } 40 41 static void signal_usr1(int sig) 42 { 43 } 44 45 struct { 46 unsigned long address; 47 int is_write; 48 int pid; 49 } segfault_record[1024]; 50 51 int segfault_index = 0; 52 53 struct { 54 int pid; 55 int signal; 56 unsigned long addr; 57 struct timeval time; 58 } signal_record[1024]; 59 60 int signal_index = 0; 61 int nsignals = 0; 62 63 int signals(void *arg) 64 { 65 struct init_thread *init_info; 66 void *task; 67 int status, pid, sig, cont_type, tracing, want_tracing, op; 68 int last_index, proc_id; 69 70 signal(SIGSEGV, signal_segv); 71 signal(SIGUSR1, signal_usr1); 72 register_pid(getpid(), 0); 73 printk("signal thread pid = %d\n", getpid()); 74 init_info = arg; 75 clone(signal_tramp, init_info->sp, CLONE_FILES | SIGCHLD, init_info->proc); 76 set_cmdline("(tracing thread)"); 77 while(1){ 78 if((pid = linux_wait(-1, &status, WUNTRACED)) <= 0){ 79 if(errno != ECHILD){ 80 printk("wait failed - errno = %d\n", errno); 81 } 82 continue; 83 } 84 nsignals++; 85 if(WIFEXITED(status)) ; 86 #ifdef notdef 87 { 88 printk("Child %d exited with status %d\n", pid, WEXITSTATUS(status)); 89 } 90 #endif 91 else if(WIFSIGNALED(status)){ 92 sig = WTERMSIG(status); 93 if(sig != 9){ 94 printk("Child %d exited with signal %d\n", pid, sig); 95 } 96 } 97 else if(WIFSTOPPED(status)){ 98 sig = WSTOPSIG(status); 99 if(signal_index == 1024){ 100 signal_index = 0; 101 last_index = 1023; 102 } 103 else last_index = signal_index - 1; 104 if((sig == SIGPROF) && (signal_record[last_index].signal == SIGPROF) && 105 (signal_record[last_index].pid == pid)) 106 signal_index = last_index; 107 signal_record[signal_index].pid = pid; 108 gettimeofday(&signal_record[signal_index].time, NULL); 109 signal_record[signal_index].addr = 0; 110 signal_record[signal_index++].signal = sig; 111 #ifdef __SMP__ 112 proc_id = pid_to_processor_id(pid); 113 task = cpu_tasks[proc_id].task; 114 #else 115 task = get_current_task(); 116 #endif 117 tracing = is_tracing(task); 118 want_tracing = get_want_tracing(task); 119 switch(sig){ 120 case SIGUSR1: 121 sig = 0; 122 if((op = do_proc_op(task, proc_id)) != OP_NONE){ 123 if((op == OP_EXEC) || (op == OP_SWITCH)) continue; 124 } 125 else { 126 printk("Detaching pid %d\n", pid); 127 detach(pid); 128 continue; 129 } 130 break; 131 case SIGSTOP: 132 continue; 133 case SIGBUS: 134 case SIGILL: 135 PROC_UNTESTED(); 136 break; 137 case SIGTRAP: 138 sig = 0; 139 if((tracing == want_tracing) && (tracing != 0)){ 140 do_syscall(task, pid); 141 continue; 142 } 143 break; 144 case SIGUSR2: 145 if(is_tracing(task)) panic("tracing in a system call"); 146 break; 147 case SIGVTALRM: 148 /* XXX this causes interrupts to be lost */ 149 if(sigs_blocked(task)){ 150 extern int blocked_timers; 151 blocked_timers++; 152 if(tracing != 0) cont_type = PTRACE_SYSCALL; 153 else cont_type = PTRACE_CONT; 154 if(ptrace(cont_type, pid, 0, 0) < 0){ 155 panic("ptrace after alarm failed"); 156 } 157 continue; 158 } 159 break; 160 default: 161 break; 162 } 163 tracing = want_tracing; 164 set_tracing(task, want_tracing); 165 if(tracing != 0) cont_type = PTRACE_SYSCALL; 166 else cont_type = PTRACE_CONT; 167 if(ptrace(cont_type, pid, 0, sig) != 0){ 168 PROC_UNTESTED(); 169 printk("ptrace failed\n"); 170 } 171 } 172 } 173 return(0); 174 } 175 176 int nsegfaults = 0; 177 178 static void segv_handler(struct sigcontext_struct *sc) 179 { 180 int index; 181 182 lock_trap(); 183 index = segfault_index++; 184 if(segfault_index == 1024) segfault_index = 0; 185 unlock_trap(); 186 nsegfaults++; 187 segfault_record[index].address = sc->cr2; 188 segfault_record[index].pid = getpid(); 189 segfault_record[index].is_write = sc->err & 2; 190 segv(sc->cr2, sc->err & 2); 191 } 192 193 void kern_segv_handler(int sig) 194 { 195 struct sigcontext_struct *sc; 196 197 sc = (struct sigcontext_struct *) (&sig + 1); 198 segv_handler(sc); 199 } 200 201 void user_segv_handler(int sig) 202 { 203 struct sigcontext_struct *sc; 204 unsigned long addr; 205 int is_user; 206 207 sc = (struct sigcontext_struct *) (&sig + 1); 208 if((((unsigned long) &sig) & ~4095) > 0xaf000000) panic("signal on wrong stack"); 209 if((addr = forced_fault()) != 0){ 210 sc->cr2 = addr; 211 sc->err = 2; 212 segv_handler(sc); 213 kill(getpid(), SIGSTOP); 214 } 215 else { 216 block_signals(NULL); 217 is_user = set_user_thread(NULL, 0); 218 segv_handler(sc); 219 set_user_thread(NULL, is_user); 220 unblock_signals(NULL); 221 } 222 } 223

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.