blob: 47086b48a37d1b75ee3422e7e14e2e4da26e658f [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"
Juan Cespedes273ea6d1998-03-14 23:02:40 +010018
Juan Cespedesa8909f72009-04-28 20:02:41 +020019Process *
Petr Machatac7585b62011-07-08 22:58:12 +020020open_program(char *filename, pid_t pid, int enable) {
Juan Cespedesa8909f72009-04-28 20:02:41 +020021 Process *proc;
Petr Machata1b17dbf2011-07-08 19:22:52 +020022 assert(pid != 0);
Juan Cespedesa8909f72009-04-28 20:02:41 +020023 proc = calloc(sizeof(Process), 1);
Juan Cespedes273ea6d1998-03-14 23:02:40 +010024 if (!proc) {
25 perror("malloc");
26 exit(1);
27 }
Petr Machata1974dbc2011-08-19 18:58:01 +020028
Juan Cespedese0660df2009-05-21 18:14:39 +020029 proc->filename = strdup(filename);
Petr Machata1b17dbf2011-07-08 19:22:52 +020030 proc->pid = pid;
Joe Damatoab3b72c2010-10-31 00:21:53 -070031#if defined(HAVE_LIBUNWIND)
Petr Machata1b17dbf2011-07-08 19:22:52 +020032 proc->unwind_priv = _UPT_create(pid);
33 proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0);
Joe Damatoab3b72c2010-10-31 00:21:53 -070034#endif /* defined(HAVE_LIBUNWIND) */
Joe Damatoab3b72c2010-10-31 00:21:53 -070035
Petr Machatacebb8842011-07-09 11:14:11 +020036 add_process(proc);
Petr Machata1974dbc2011-08-19 18:58:01 +020037 if (proc->leader == NULL) {
38 free(proc);
39 return NULL;
40 }
Juan Cespedes273ea6d1998-03-14 23:02:40 +010041
Petr Machata61196a42012-02-07 16:41:03 +010042 if (proc->leader == proc) {
43 trace_set_options(proc, proc->pid);
Petr Machata1974dbc2011-08-19 18:58:01 +020044 if (breakpoints_init(proc, enable)) {
45 fprintf(stderr, "failed to init breakpoints %d\n",
46 proc->pid);
47 remove_process(proc);
48 return NULL;
49 }
Petr Machata61196a42012-02-07 16:41:03 +010050 }
Joe Damatoab3b72c2010-10-31 00:21:53 -070051
Juan Cespedes273ea6d1998-03-14 23:02:40 +010052 return proc;
53}
54
Petr Machata3c516d52011-08-18 03:53:18 +020055static int
Petr Machata9a5420c2011-07-09 11:21:23 +020056open_one_pid(pid_t pid)
57{
Juan Cespedesa8909f72009-04-28 20:02:41 +020058 Process *proc;
Ian Wienand2d45b1a2006-02-20 22:48:07 +010059 char *filename;
Petr Machata9a5420c2011-07-09 11:21:23 +020060 debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid);
61
Petr Machata1974dbc2011-08-19 18:58:01 +020062 /* Get the filename first. Should the trace_pid fail, we can
63 * easily free it, untracing is more work. */
64 if ((filename = pid2name(pid)) == NULL
65 || trace_pid(pid) < 0) {
66 free(filename);
67 return -1;
68 }
Juan Cespedes35d70631998-03-15 14:05:40 +010069
Petr Machata1974dbc2011-08-19 18:58:01 +020070 proc = open_program(filename, pid, 0);
71 if (proc == NULL)
72 return -1;
Petr Machata602330f2011-07-09 11:15:34 +020073 trace_set_options(proc, pid);
Petr Machata3c516d52011-08-18 03:53:18 +020074
Petr Machata1974dbc2011-08-19 18:58:01 +020075 return 0;
76}
77
Petr Machata61196a42012-02-07 16:41:03 +010078static enum pcb_status
Petr Machata1974dbc2011-08-19 18:58:01 +020079start_one_pid(Process * proc, void * data)
80{
81 continue_process(proc->pid);
Petr Machata1974dbc2011-08-19 18:58:01 +020082 return pcb_cont;
Juan Cespedes273ea6d1998-03-14 23:02:40 +010083}
Juan Cespedese74c80d2009-02-11 11:32:31 +010084
Petr Machata9a5420c2011-07-09 11:21:23 +020085void
86open_pid(pid_t pid)
87{
88 debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid);
Petr Machata3c516d52011-08-18 03:53:18 +020089 /* If we are already tracing this guy, we should be seeing all
90 * his children via normal tracing route. */
91 if (pid2proc(pid) != NULL)
92 return;
Petr Machata9a5420c2011-07-09 11:21:23 +020093
Petr Machata3c516d52011-08-18 03:53:18 +020094 /* First, see if we can attach the requested PID itself. */
Petr Machata1974dbc2011-08-19 18:58:01 +020095 if (open_one_pid(pid)) {
Petr Machata3c516d52011-08-18 03:53:18 +020096 fprintf(stderr, "Cannot attach to pid %u: %s\n",
97 pid, strerror(errno));
Petr Machatacec06ec2012-04-10 13:31:55 +020098 trace_fail_warning(pid);
Petr Machata3c516d52011-08-18 03:53:18 +020099 return;
Petr Machata9a5420c2011-07-09 11:21:23 +0200100 }
101
Petr Machata3c516d52011-08-18 03:53:18 +0200102 /* Now attach to all tasks that belong to that PID. There's a
103 * race between process_tasks and open_one_pid. So when we
104 * fail in open_one_pid below, we just do another round.
105 * Chances are that by then that PID will have gone away, and
106 * that's why we have seen the failure. The processes that we
107 * manage to open_one_pid are stopped, so we should eventually
108 * reach a point where process_tasks doesn't give any new
109 * processes (because there's nobody left to produce
110 * them). */
Petr Machata1974dbc2011-08-19 18:58:01 +0200111 size_t old_ntasks = 0;
Petr Machata3c516d52011-08-18 03:53:18 +0200112 int have_all;
Petr Machata1974dbc2011-08-19 18:58:01 +0200113 while (1) {
Petr Machata3c516d52011-08-18 03:53:18 +0200114 pid_t *tasks;
115 size_t ntasks;
116 size_t i;
Petr Machata1974dbc2011-08-19 18:58:01 +0200117
Petr Machata3c516d52011-08-18 03:53:18 +0200118 if (process_tasks(pid, &tasks, &ntasks) < 0) {
119 fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n",
120 pid, strerror(errno));
Petr Machatafed1e8d2012-02-07 02:06:29 +0100121 break;
Petr Machata3c516d52011-08-18 03:53:18 +0200122 }
Petr Machata9a5420c2011-07-09 11:21:23 +0200123
Petr Machata3c516d52011-08-18 03:53:18 +0200124 have_all = 1;
125 for (i = 0; i < ntasks; ++i)
126 if (pid2proc(tasks[i]) == NULL
Petr Machata1974dbc2011-08-19 18:58:01 +0200127 && open_one_pid(tasks[i]))
Petr Machata3c516d52011-08-18 03:53:18 +0200128 have_all = 0;
129
Petr Machata9a5420c2011-07-09 11:21:23 +0200130 free(tasks);
Petr Machata3c516d52011-08-18 03:53:18 +0200131
Petr Machata1974dbc2011-08-19 18:58:01 +0200132 if (have_all && old_ntasks == ntasks)
133 break;
134 old_ntasks = ntasks;
135 }
136
137 /* Done. Now initialize breakpoints and then continue
138 * everyone. */
139 Process * leader;
Petr Machata1974dbc2011-08-19 18:58:01 +0200140 leader = pid2proc(pid)->leader;
141 enable_all_breakpoints(leader);
142
143 each_task(pid2proc(pid)->leader, start_one_pid, NULL);
Petr Machata9a5420c2011-07-09 11:21:23 +0200144}
145
Petr Machatacebb8842011-07-09 11:14:11 +0200146static enum pcb_status
147find_proc(Process * proc, void * data)
148{
149 pid_t pid = (pid_t)(uintptr_t)data;
150 return proc->pid == pid ? pcb_stop : pcb_cont;
151}
152
Juan Cespedesa8909f72009-04-28 20:02:41 +0200153Process *
Juan Cespedese74c80d2009-02-11 11:32:31 +0100154pid2proc(pid_t pid) {
Petr Machatacebb8842011-07-09 11:14:11 +0200155 return each_process(NULL, &find_proc, (void *)(uintptr_t)pid);
156}
Juan Cespedese74c80d2009-02-11 11:32:31 +0100157
Petr Machatacebb8842011-07-09 11:14:11 +0200158static Process * list_of_processes = NULL;
159
Petr Machatacbe29c62011-09-27 02:27:58 +0200160static void
161unlist_process(Process * proc)
162{
163 Process *tmp;
164
165 if (list_of_processes == proc) {
166 list_of_processes = list_of_processes->next;
167 return;
168 }
169
170 for (tmp = list_of_processes; ; tmp = tmp->next) {
171 /* If the following assert fails, the process wasn't
172 * in the list. */
173 assert(tmp->next != NULL);
174
175 if (tmp->next == proc) {
176 tmp->next = tmp->next->next;
177 return;
178 }
179 }
180}
181
Petr Machatacebb8842011-07-09 11:14:11 +0200182Process *
183each_process(Process * proc,
184 enum pcb_status (* cb)(Process * proc, void * data),
185 void * data)
186{
187 Process * it = proc ?: list_of_processes;
188 for (; it != NULL; ) {
189 /* Callback might call remove_process. */
190 Process * next = it->next;
191 if ((*cb) (it, data) == pcb_stop)
192 return it;
193 it = next;
194 }
195 return NULL;
196}
Petr Machata9a5420c2011-07-09 11:21:23 +0200197
198Process *
199each_task(Process * it, enum pcb_status (* cb)(Process * proc, void * data),
200 void * data)
201{
202 if (it != NULL) {
203 Process * leader = it->leader;
204 for (; it != NULL && it->leader == leader; ) {
205 /* Callback might call remove_process. */
206 Process * next = it->next;
207 if ((*cb) (it, data) == pcb_stop)
208 return it;
209 it = next;
210 }
211 }
212 return NULL;
213}
214
Petr Machatacebb8842011-07-09 11:14:11 +0200215void
216add_process(Process * proc)
217{
Petr Machata9a5420c2011-07-09 11:21:23 +0200218 Process ** leaderp = &list_of_processes;
219 if (proc->pid) {
220 pid_t tgid = process_leader(proc->pid);
Petr Machata1974dbc2011-08-19 18:58:01 +0200221 if (tgid == 0)
222 /* Must have been terminated before we managed
223 * to fully attach. */
224 return;
Petr Machata9a5420c2011-07-09 11:21:23 +0200225 if (tgid == proc->pid)
226 proc->leader = proc;
227 else {
228 Process * leader = pid2proc(tgid);
229 proc->leader = leader;
230 if (leader != NULL)
Petr Machata9a5420c2011-07-09 11:21:23 +0200231 leaderp = &leader->next;
232 }
233 }
234 proc->next = *leaderp;
235 *leaderp = proc;
236}
237
Petr Machatacbe29c62011-09-27 02:27:58 +0200238void
239change_process_leader(Process * proc, Process * leader)
240{
241 Process ** leaderp = &list_of_processes;
242 if (proc->leader == leader)
243 return;
244
245 assert(leader != NULL);
246 unlist_process(proc);
247 if (proc != leader)
248 leaderp = &leader->next;
249
250 proc->leader = leader;
251 proc->next = *leaderp;
252 *leaderp = proc;
253}
254
Petr Machata9a5420c2011-07-09 11:21:23 +0200255static enum pcb_status
256clear_leader(Process * proc, void * data)
257{
258 debug(DEBUG_FUNCTION, "detach_task %d from leader %d",
259 proc->pid, proc->leader->pid);
260 proc->leader = NULL;
261 return pcb_cont;
Petr Machatacebb8842011-07-09 11:14:11 +0200262}
263
Petr Machata69a03e62011-07-09 11:29:12 +0200264static enum ecb_status
265event_for_proc(Event * event, void * data)
266{
267 if (event->proc == data)
268 return ecb_deque;
269 else
270 return ecb_cont;
271}
272
273static void
274delete_events_for(Process * proc)
275{
276 Event * event;
277 while ((event = each_qd_event(&event_for_proc, proc)) != NULL)
278 free(event);
279}
280
Petr Machatacebb8842011-07-09 11:14:11 +0200281void
282remove_process(Process *proc)
283{
Petr Machatacebb8842011-07-09 11:14:11 +0200284 debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid);
285
Petr Machata9a5420c2011-07-09 11:21:23 +0200286 if (proc->leader == proc)
287 each_task(proc, &clear_leader, NULL);
288
Petr Machatacbe29c62011-09-27 02:27:58 +0200289 unlist_process(proc);
290 delete_events_for(proc);
291 free(proc);
Juan Cespedese74c80d2009-02-11 11:32:31 +0100292}
Petr Machata4007d742011-07-09 11:29:42 +0200293
294void
295install_event_handler(Process * proc, Event_Handler * handler)
296{
Petr Machata75dcf7d2011-10-06 14:30:19 +0200297 debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler);
Petr Machata4007d742011-07-09 11:29:42 +0200298 assert(proc->event_handler == NULL);
299 proc->event_handler = handler;
300}
301
302void
303destroy_event_handler(Process * proc)
304{
305 Event_Handler * handler = proc->event_handler;
Petr Machata75dcf7d2011-10-06 14:30:19 +0200306 debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler);
Petr Machata4007d742011-07-09 11:29:42 +0200307 assert(handler != NULL);
Petr Machatacbe29c62011-09-27 02:27:58 +0200308 if (handler->destroy != NULL)
309 handler->destroy(handler);
Petr Machata4007d742011-07-09 11:29:42 +0200310 free(handler);
311 proc->event_handler = NULL;
312}