proc.c revision cebb88491e68bdf4d466b03970c9ca77f65615f8
1#include "config.h" 2 3#if defined(HAVE_LIBUNWIND) 4#include <libunwind.h> 5#include <libunwind-ptrace.h> 6#endif /* defined(HAVE_LIBUNWIND) */ 7 8#include <sys/types.h> 9#include <string.h> 10#include <stdio.h> 11#include <errno.h> 12#include <stdlib.h> 13#include <assert.h> 14 15#include "common.h" 16 17Process * 18open_program(char *filename, pid_t pid, int enable) { 19 Process *proc; 20 assert(pid != 0); 21 proc = calloc(sizeof(Process), 1); 22 if (!proc) { 23 perror("malloc"); 24 exit(1); 25 } 26 proc->filename = strdup(filename); 27 proc->breakpoints_enabled = -1; 28 proc->pid = pid; 29#if defined(HAVE_LIBUNWIND) 30 proc->unwind_priv = _UPT_create(pid); 31 proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0); 32#endif /* defined(HAVE_LIBUNWIND) */ 33 34 add_process(proc); 35 36 breakpoints_init(proc, enable); 37 38 return proc; 39} 40 41void 42open_pid(pid_t pid) { 43 Process *proc; 44 char *filename; 45 46 if (trace_pid(pid) < 0) { 47 fprintf(stderr, "Cannot attach to pid %u: %s\n", pid, 48 strerror(errno)); 49 return; 50 } 51 52 filename = pid2name(pid); 53 54 if (!filename) { 55 fprintf(stderr, "Cannot trace pid %u: %s\n", pid, 56 strerror(errno)); 57 return; 58 } 59 60 proc = open_program(filename, pid, 1); 61 continue_process(pid); 62 proc->breakpoints_enabled = 1; 63} 64 65static enum pcb_status 66find_proc(Process * proc, void * data) 67{ 68 pid_t pid = (pid_t)(uintptr_t)data; 69 return proc->pid == pid ? pcb_stop : pcb_cont; 70} 71 72Process * 73pid2proc(pid_t pid) { 74 return each_process(NULL, &find_proc, (void *)(uintptr_t)pid); 75} 76 77 78static Process * list_of_processes = NULL; 79 80Process * 81each_process(Process * proc, 82 enum pcb_status (* cb)(Process * proc, void * data), 83 void * data) 84{ 85 Process * it = proc ?: list_of_processes; 86 for (; it != NULL; ) { 87 /* Callback might call remove_process. */ 88 Process * next = it->next; 89 if ((*cb) (it, data) == pcb_stop) 90 return it; 91 it = next; 92 } 93 return NULL; 94} 95void 96add_process(Process * proc) 97{ 98 proc->next = list_of_processes; 99 list_of_processes = proc; 100} 101 102void 103remove_process(Process *proc) 104{ 105 Process *tmp, *tmp2; 106 107 debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid); 108 109 if (list_of_processes == proc) { 110 tmp = list_of_processes; 111 list_of_processes = list_of_processes->next; 112 free(tmp); 113 return; 114 } 115 tmp = list_of_processes; 116 while (tmp->next) { 117 if (tmp->next == proc) { 118 tmp2 = tmp->next; 119 tmp->next = tmp->next->next; 120 free(tmp2); 121 return; 122 } 123 tmp = tmp->next; 124 } 125} 126