blob: 5360b0b38480d26a7ace95eb4ee86efce6e20f4e [file] [log] [blame]
Joe Damatoab3b72c2010-10-31 00:21:53 -07001#include "config.h"
2
3#if defined(HAVE_LIBUNWIND)
4#include <libunwind.h>
5#include <libunwind-ptrace.h>
6#endif /* defined(HAVE_LIBUNWIND) */
7
Juan Cespedes273ea6d1998-03-14 23:02:40 +01008#include <sys/types.h>
9#include <string.h>
10#include <stdio.h>
11#include <errno.h>
12#include <stdlib.h>
Petr Machata1b17dbf2011-07-08 19:22:52 +020013#include <assert.h>
Petr Machata1974dbc2011-08-19 18:58:01 +020014#include <error.h>
Juan Cespedes273ea6d1998-03-14 23:02:40 +010015
Juan Cespedesf7281232009-06-25 16:11:21 +020016#include "common.h"
Petr Machata9294d822012-02-07 12:35:58 +010017#include "breakpoint.h"
Petr Machata366c2f42012-02-09 19:34:36 +010018#include "proc.h"
Juan Cespedes273ea6d1998-03-14 23:02:40 +010019
Juan Cespedesa8909f72009-04-28 20:02:41 +020020Process *
Petr Machatac7585b62011-07-08 22:58:12 +020021open_program(char *filename, pid_t pid, int enable) {
Juan Cespedesa8909f72009-04-28 20:02:41 +020022 Process *proc;
Petr Machata1b17dbf2011-07-08 19:22:52 +020023 assert(pid != 0);
Juan Cespedesa8909f72009-04-28 20:02:41 +020024 proc = calloc(sizeof(Process), 1);
Juan Cespedes273ea6d1998-03-14 23:02:40 +010025 if (!proc) {
26 perror("malloc");
27 exit(1);
28 }
Petr Machata1974dbc2011-08-19 18:58:01 +020029
Juan Cespedese0660df2009-05-21 18:14:39 +020030 proc->filename = strdup(filename);
Petr Machata1b17dbf2011-07-08 19:22:52 +020031 proc->pid = pid;
Joe Damatoab3b72c2010-10-31 00:21:53 -070032#if defined(HAVE_LIBUNWIND)
Petr Machata1b17dbf2011-07-08 19:22:52 +020033 proc->unwind_priv = _UPT_create(pid);
34 proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0);
Joe Damatoab3b72c2010-10-31 00:21:53 -070035#endif /* defined(HAVE_LIBUNWIND) */
Joe Damatoab3b72c2010-10-31 00:21:53 -070036
Petr Machatacebb8842011-07-09 11:14:11 +020037 add_process(proc);
Petr Machata1974dbc2011-08-19 18:58:01 +020038 if (proc->leader == NULL) {
39 free(proc);
40 return NULL;
41 }
Juan Cespedes273ea6d1998-03-14 23:02:40 +010042
Petr Machata61196a42012-02-07 16:41:03 +010043 if (proc->leader == proc) {
44 trace_set_options(proc, proc->pid);
Petr Machata1974dbc2011-08-19 18:58:01 +020045 if (breakpoints_init(proc, enable)) {
46 fprintf(stderr, "failed to init breakpoints %d\n",
47 proc->pid);
48 remove_process(proc);
49 return NULL;
50 }
Petr Machata61196a42012-02-07 16:41:03 +010051 }
Joe Damatoab3b72c2010-10-31 00:21:53 -070052
Juan Cespedes273ea6d1998-03-14 23:02:40 +010053 return proc;
54}
55
Petr Machata3c516d52011-08-18 03:53:18 +020056static int
Petr Machata9a5420c2011-07-09 11:21:23 +020057open_one_pid(pid_t pid)
58{
Juan Cespedesa8909f72009-04-28 20:02:41 +020059 Process *proc;
Ian Wienand2d45b1a2006-02-20 22:48:07 +010060 char *filename;
Petr Machata9a5420c2011-07-09 11:21:23 +020061 debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid);
62
Petr Machata1974dbc2011-08-19 18:58:01 +020063 /* Get the filename first. Should the trace_pid fail, we can
64 * easily free it, untracing is more work. */
65 if ((filename = pid2name(pid)) == NULL
66 || trace_pid(pid) < 0) {
67 free(filename);
68 return -1;
69 }
Juan Cespedes35d70631998-03-15 14:05:40 +010070
Petr Machata1974dbc2011-08-19 18:58:01 +020071 proc = open_program(filename, pid, 0);
72 if (proc == NULL)
73 return -1;
Petr Machata602330f2011-07-09 11:15:34 +020074 trace_set_options(proc, pid);
Petr Machata3c516d52011-08-18 03:53:18 +020075
Petr Machata1974dbc2011-08-19 18:58:01 +020076 return 0;
77}
78
Petr Machata61196a42012-02-07 16:41:03 +010079static enum pcb_status
Petr Machata1974dbc2011-08-19 18:58:01 +020080start_one_pid(Process * proc, void * data)
81{
82 continue_process(proc->pid);
Petr Machata1974dbc2011-08-19 18:58:01 +020083 return pcb_cont;
Juan Cespedes273ea6d1998-03-14 23:02:40 +010084}
Juan Cespedese74c80d2009-02-11 11:32:31 +010085
Petr Machata9a5420c2011-07-09 11:21:23 +020086void
87open_pid(pid_t pid)
88{
89 debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid);
Petr Machata3c516d52011-08-18 03:53:18 +020090 /* If we are already tracing this guy, we should be seeing all
91 * his children via normal tracing route. */
92 if (pid2proc(pid) != NULL)
93 return;
Petr Machata9a5420c2011-07-09 11:21:23 +020094
Petr Machata3c516d52011-08-18 03:53:18 +020095 /* First, see if we can attach the requested PID itself. */
Petr Machata1974dbc2011-08-19 18:58:01 +020096 if (open_one_pid(pid)) {
Petr Machata3c516d52011-08-18 03:53:18 +020097 fprintf(stderr, "Cannot attach to pid %u: %s\n",
98 pid, strerror(errno));
Petr Machatacec06ec2012-04-10 13:31:55 +020099 trace_fail_warning(pid);
Petr Machata3c516d52011-08-18 03:53:18 +0200100 return;
Petr Machata9a5420c2011-07-09 11:21:23 +0200101 }
102
Petr Machata3c516d52011-08-18 03:53:18 +0200103 /* Now attach to all tasks that belong to that PID. There's a
104 * race between process_tasks and open_one_pid. So when we
105 * fail in open_one_pid below, we just do another round.
106 * Chances are that by then that PID will have gone away, and
107 * that's why we have seen the failure. The processes that we
108 * manage to open_one_pid are stopped, so we should eventually
109 * reach a point where process_tasks doesn't give any new
110 * processes (because there's nobody left to produce
111 * them). */
Petr Machata1974dbc2011-08-19 18:58:01 +0200112 size_t old_ntasks = 0;
Petr Machata3c516d52011-08-18 03:53:18 +0200113 int have_all;
Petr Machata1974dbc2011-08-19 18:58:01 +0200114 while (1) {
Petr Machata3c516d52011-08-18 03:53:18 +0200115 pid_t *tasks;
116 size_t ntasks;
117 size_t i;
Petr Machata1974dbc2011-08-19 18:58:01 +0200118
Petr Machata3c516d52011-08-18 03:53:18 +0200119 if (process_tasks(pid, &tasks, &ntasks) < 0) {
120 fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n",
121 pid, strerror(errno));
Petr Machatafed1e8d2012-02-07 02:06:29 +0100122 break;
Petr Machata3c516d52011-08-18 03:53:18 +0200123 }
Petr Machata9a5420c2011-07-09 11:21:23 +0200124
Petr Machata3c516d52011-08-18 03:53:18 +0200125 have_all = 1;
126 for (i = 0; i < ntasks; ++i)
127 if (pid2proc(tasks[i]) == NULL
Petr Machata1974dbc2011-08-19 18:58:01 +0200128 && open_one_pid(tasks[i]))
Petr Machata3c516d52011-08-18 03:53:18 +0200129 have_all = 0;
130
Petr Machata9a5420c2011-07-09 11:21:23 +0200131 free(tasks);
Petr Machata3c516d52011-08-18 03:53:18 +0200132
Petr Machata1974dbc2011-08-19 18:58:01 +0200133 if (have_all && old_ntasks == ntasks)
134 break;
135 old_ntasks = ntasks;
136 }
137
138 /* Done. Now initialize breakpoints and then continue
139 * everyone. */
140 Process * leader;
Petr Machata1974dbc2011-08-19 18:58:01 +0200141 leader = pid2proc(pid)->leader;
142 enable_all_breakpoints(leader);
143
144 each_task(pid2proc(pid)->leader, start_one_pid, NULL);
Petr Machata9a5420c2011-07-09 11:21:23 +0200145}
146
Petr Machatacebb8842011-07-09 11:14:11 +0200147static enum pcb_status
148find_proc(Process * proc, void * data)
149{
150 pid_t pid = (pid_t)(uintptr_t)data;
151 return proc->pid == pid ? pcb_stop : pcb_cont;
152}
153
Juan Cespedesa8909f72009-04-28 20:02:41 +0200154Process *
Juan Cespedese74c80d2009-02-11 11:32:31 +0100155pid2proc(pid_t pid) {
Petr Machatacebb8842011-07-09 11:14:11 +0200156 return each_process(NULL, &find_proc, (void *)(uintptr_t)pid);
157}
Juan Cespedese74c80d2009-02-11 11:32:31 +0100158
Petr Machatacebb8842011-07-09 11:14:11 +0200159static Process * list_of_processes = NULL;
160
Petr Machatacbe29c62011-09-27 02:27:58 +0200161static void
162unlist_process(Process * proc)
163{
164 Process *tmp;
165
166 if (list_of_processes == proc) {
167 list_of_processes = list_of_processes->next;
168 return;
169 }
170
171 for (tmp = list_of_processes; ; tmp = tmp->next) {
172 /* If the following assert fails, the process wasn't
173 * in the list. */
174 assert(tmp->next != NULL);
175
176 if (tmp->next == proc) {
177 tmp->next = tmp->next->next;
178 return;
179 }
180 }
181}
182
Petr Machatacebb8842011-07-09 11:14:11 +0200183Process *
184each_process(Process * proc,
185 enum pcb_status (* cb)(Process * proc, void * data),
186 void * data)
187{
188 Process * it = proc ?: list_of_processes;
189 for (; it != NULL; ) {
190 /* Callback might call remove_process. */
191 Process * next = it->next;
192 if ((*cb) (it, data) == pcb_stop)
193 return it;
194 it = next;
195 }
196 return NULL;
197}
Petr Machata9a5420c2011-07-09 11:21:23 +0200198
199Process *
200each_task(Process * it, enum pcb_status (* cb)(Process * proc, void * data),
201 void * data)
202{
203 if (it != NULL) {
204 Process * leader = it->leader;
205 for (; it != NULL && it->leader == leader; ) {
206 /* Callback might call remove_process. */
207 Process * next = it->next;
208 if ((*cb) (it, data) == pcb_stop)
209 return it;
210 it = next;
211 }
212 }
213 return NULL;
214}
215
Petr Machatacebb8842011-07-09 11:14:11 +0200216void
217add_process(Process * proc)
218{
Petr Machata9a5420c2011-07-09 11:21:23 +0200219 Process ** leaderp = &list_of_processes;
220 if (proc->pid) {
221 pid_t tgid = process_leader(proc->pid);
Petr Machata1974dbc2011-08-19 18:58:01 +0200222 if (tgid == 0)
223 /* Must have been terminated before we managed
224 * to fully attach. */
225 return;
Petr Machata9a5420c2011-07-09 11:21:23 +0200226 if (tgid == proc->pid)
227 proc->leader = proc;
228 else {
229 Process * leader = pid2proc(tgid);
230 proc->leader = leader;
231 if (leader != NULL)
Petr Machata9a5420c2011-07-09 11:21:23 +0200232 leaderp = &leader->next;
233 }
234 }
235 proc->next = *leaderp;
236 *leaderp = proc;
237}
238
Petr Machatacbe29c62011-09-27 02:27:58 +0200239void
240change_process_leader(Process * proc, Process * leader)
241{
242 Process ** leaderp = &list_of_processes;
243 if (proc->leader == leader)
244 return;
245
246 assert(leader != NULL);
247 unlist_process(proc);
248 if (proc != leader)
249 leaderp = &leader->next;
250
251 proc->leader = leader;
252 proc->next = *leaderp;
253 *leaderp = proc;
254}
255
Petr Machata9a5420c2011-07-09 11:21:23 +0200256static enum pcb_status
257clear_leader(Process * proc, void * data)
258{
259 debug(DEBUG_FUNCTION, "detach_task %d from leader %d",
260 proc->pid, proc->leader->pid);
261 proc->leader = NULL;
262 return pcb_cont;
Petr Machatacebb8842011-07-09 11:14:11 +0200263}
264
Petr Machata69a03e62011-07-09 11:29:12 +0200265static enum ecb_status
266event_for_proc(Event * event, void * data)
267{
268 if (event->proc == data)
269 return ecb_deque;
270 else
271 return ecb_cont;
272}
273
274static void
275delete_events_for(Process * proc)
276{
277 Event * event;
278 while ((event = each_qd_event(&event_for_proc, proc)) != NULL)
279 free(event);
280}
281
Petr Machatacebb8842011-07-09 11:14:11 +0200282void
283remove_process(Process *proc)
284{
Petr Machatacebb8842011-07-09 11:14:11 +0200285 debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid);
286
Petr Machata9a5420c2011-07-09 11:21:23 +0200287 if (proc->leader == proc)
288 each_task(proc, &clear_leader, NULL);
289
Petr Machatacbe29c62011-09-27 02:27:58 +0200290 unlist_process(proc);
291 delete_events_for(proc);
292 free(proc);
Juan Cespedese74c80d2009-02-11 11:32:31 +0100293}
Petr Machata4007d742011-07-09 11:29:42 +0200294
295void
Petr Machata366c2f42012-02-09 19:34:36 +0100296install_event_handler(Process *proc, struct event_handler *handler)
Petr Machata4007d742011-07-09 11:29:42 +0200297{
Petr Machata75dcf7d2011-10-06 14:30:19 +0200298 debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler);
Petr Machata4007d742011-07-09 11:29:42 +0200299 assert(proc->event_handler == NULL);
300 proc->event_handler = handler;
301}
302
303void
304destroy_event_handler(Process * proc)
305{
Petr Machata366c2f42012-02-09 19:34:36 +0100306 struct event_handler *handler = proc->event_handler;
Petr Machata75dcf7d2011-10-06 14:30:19 +0200307 debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler);
Petr Machata4007d742011-07-09 11:29:42 +0200308 assert(handler != NULL);
Petr Machatacbe29c62011-09-27 02:27:58 +0200309 if (handler->destroy != NULL)
310 handler->destroy(handler);
Petr Machata4007d742011-07-09 11:29:42 +0200311 free(handler);
312 proc->event_handler = NULL;
313}