blob: 16347648785d3093c753955421bea2951056832e [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
Petr Machata3d0c91c2012-04-14 02:37:38 +020020static void add_process(struct Process *proc, int was_exec);
Petr Machata44965c72012-04-06 19:59:20 +020021
Petr Machata2b46cfc2012-02-18 11:17:29 +010022static int
Petr Machata3d0c91c2012-04-14 02:37:38 +020023process_bare_init(struct Process *proc, const char *filename,
24 pid_t pid, int was_exec)
Petr Machata2b46cfc2012-02-18 11:17:29 +010025{
Petr Machata3d0c91c2012-04-14 02:37:38 +020026 if (!was_exec) {
27 memset(proc, 0, sizeof(*proc));
Petr Machata1974dbc2011-08-19 18:58:01 +020028
Petr Machata3d0c91c2012-04-14 02:37:38 +020029 proc->filename = strdup(filename);
30 if (proc->filename == NULL) {
31 fail:
32 free(proc->filename);
33 if (proc->breakpoints != NULL)
34 dict_clear(proc->breakpoints);
35 return -1;
36 }
Petr Machata2b46cfc2012-02-18 11:17:29 +010037 }
38
39 /* Add process so that we know who the leader is. */
Petr Machata1b17dbf2011-07-08 19:22:52 +020040 proc->pid = pid;
Petr Machata3d0c91c2012-04-14 02:37:38 +020041 add_process(proc, was_exec);
Petr Machata2b46cfc2012-02-18 11:17:29 +010042 if (proc->leader == NULL)
43 goto fail;
44
45 if (proc->leader == proc) {
Petr Machataecb082f2012-04-05 02:10:10 +020046 proc->breakpoints = dict_init(target_address_hash,
47 target_address_cmp);
Petr Machata2b46cfc2012-02-18 11:17:29 +010048 if (proc->breakpoints == NULL)
49 goto fail;
50 } else {
51 proc->breakpoints = NULL;
52 }
53
Joe Damatoab3b72c2010-10-31 00:21:53 -070054#if defined(HAVE_LIBUNWIND)
Petr Machata1b17dbf2011-07-08 19:22:52 +020055 proc->unwind_priv = _UPT_create(pid);
56 proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0);
Joe Damatoab3b72c2010-10-31 00:21:53 -070057#endif /* defined(HAVE_LIBUNWIND) */
Joe Damatoab3b72c2010-10-31 00:21:53 -070058
Petr Machata2b46cfc2012-02-18 11:17:29 +010059 return 0;
60}
61
62static void
Petr Machata3d0c91c2012-04-14 02:37:38 +020063process_bare_destroy(struct Process *proc, int was_exec)
Petr Machata2b46cfc2012-02-18 11:17:29 +010064{
Petr Machata2b46cfc2012-02-18 11:17:29 +010065 dict_clear(proc->breakpoints);
Petr Machata3d0c91c2012-04-14 02:37:38 +020066 if (!was_exec) {
67 free(proc->filename);
68 remove_process(proc);
69 }
Petr Machata2b46cfc2012-02-18 11:17:29 +010070}
71
Petr Machata3d0c91c2012-04-14 02:37:38 +020072static int
73process_init_main(struct Process *proc)
Petr Machata2b46cfc2012-02-18 11:17:29 +010074{
Petr Machata18bd8ff2012-04-10 04:32:39 +020075 target_address_t entry;
76 target_address_t interp_bias;
77 if (process_get_entry(proc, &entry, &interp_bias) < 0) {
78 fprintf(stderr, "Couldn't get entry points of process %d\n",
Petr Machata2b46cfc2012-02-18 11:17:29 +010079 proc->pid);
Petr Machata18bd8ff2012-04-10 04:32:39 +020080 fail:
Petr Machata3d0c91c2012-04-14 02:37:38 +020081 process_bare_destroy(proc, 0);
Petr Machata2b46cfc2012-02-18 11:17:29 +010082 return -1;
83 }
84
Petr Machata3d0c91c2012-04-14 02:37:38 +020085 if (breakpoints_init(proc) < 0) {
Petr Machata18bd8ff2012-04-10 04:32:39 +020086 fprintf(stderr, "failed to init breakpoints %d\n",
87 proc->pid);
88 goto fail;
89 }
90
Petr Machata2b46cfc2012-02-18 11:17:29 +010091 return 0;
92}
93
Petr Machata3d0c91c2012-04-14 02:37:38 +020094int
95process_init(struct Process *proc, const char *filename, pid_t pid)
96{
97 if (process_bare_init(proc, filename, pid, 0) < 0) {
98 error(0, errno, "init process %d", pid);
99 return -1;
100 }
101
102 if (proc->leader == proc)
103 return process_init_main(proc);
104 else
105 return 0;
106}
107
108static void
109destroy_breakpoint_cb(void *key, void *value, void *data)
110{
111 struct breakpoint *bp = value;
112 breakpoint_destroy(bp);
113 free(bp);
114}
115
116static void
117private_process_destroy(struct Process *proc, int keep_filename)
118{
119 if (!keep_filename)
120 free(proc->filename);
121
122 /* Libraries and symbols. */
123 struct library *lib;
124 for (lib = proc->libraries; lib != NULL; ) {
125 struct library *next = lib->next;
126 library_destroy(lib);
127 free(lib);
128 lib = next;
129 }
130 proc->libraries = NULL;
131
132 /* Breakpoints. */
133 dict_apply_to_all(proc->breakpoints, destroy_breakpoint_cb, NULL);
134 dict_clear(proc->breakpoints);
135 proc->breakpoints = NULL;
136}
137
138void
139process_destroy(struct Process *proc)
140{
141 private_process_destroy(proc, 0);
142}
143
144int
145process_exec(struct Process *proc)
146{
147 private_process_destroy(proc, 1);
148 if (process_bare_init(proc, NULL, proc->pid, 1) < 0)
149 return -1;
150 if (process_init_main(proc) < 0) {
151 process_bare_destroy(proc, 1);
152 return -1;
153 }
154 return 0;
155}
156
Petr Machata2b46cfc2012-02-18 11:17:29 +0100157struct Process *
Petr Machata75934ad2012-04-14 02:28:03 +0200158open_program(const char *filename, pid_t pid)
Petr Machata2b46cfc2012-02-18 11:17:29 +0100159{
Petr Machata2b46cfc2012-02-18 11:17:29 +0100160 assert(pid != 0);
161 struct Process *proc = malloc(sizeof(*proc));
Petr Machata75934ad2012-04-14 02:28:03 +0200162 if (proc == NULL || process_init(proc, filename, pid) < 0) {
Petr Machata1974dbc2011-08-19 18:58:01 +0200163 free(proc);
164 return NULL;
165 }
Petr Machata2b46cfc2012-02-18 11:17:29 +0100166 return proc;
167}
Juan Cespedes273ea6d1998-03-14 23:02:40 +0100168
Petr Machata2b46cfc2012-02-18 11:17:29 +0100169struct clone_single_bp_data {
170 struct Process *old_proc;
171 struct Process *new_proc;
172 int error;
173};
174
Petr Machata2b46cfc2012-02-18 11:17:29 +0100175static void
176clone_single_bp(void *key, void *value, void *u)
177{
Petr Machata2b46cfc2012-02-18 11:17:29 +0100178 struct breakpoint *bp = value;
179 struct clone_single_bp_data *data = u;
180
Petr Machatad3cc9882012-04-13 21:40:23 +0200181 data->error = 0;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100182 struct breakpoint *clone = malloc(sizeof(*clone));
183 if (clone == NULL
Petr Machatad3cc9882012-04-13 21:40:23 +0200184 || breakpoint_clone(clone, data->new_proc,
185 bp, data->old_proc) < 0) {
186 fail:
187 free(clone);
Petr Machata2b46cfc2012-02-18 11:17:29 +0100188 data->error = -1;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100189 }
Petr Machatad3cc9882012-04-13 21:40:23 +0200190 if (proc_add_breakpoint(data->new_proc->leader, clone) < 0) {
191 breakpoint_destroy(clone);
192 goto fail;
193 }
Petr Machata2b46cfc2012-02-18 11:17:29 +0100194}
195
196int
197process_clone(struct Process *retp, struct Process *proc, pid_t pid)
198{
Petr Machata3d0c91c2012-04-14 02:37:38 +0200199 if (process_bare_init(retp, proc->filename, pid, 0) < 0) {
Petr Machata2b46cfc2012-02-18 11:17:29 +0100200 fail:
201 error(0, errno, "clone process %d->%d", proc->pid, pid);
202 return -1;
203 }
204
Petr Machatacf1679a2012-04-06 19:56:17 +0200205 retp->tracesysgood = proc->tracesysgood;
206
Petr Machata2b46cfc2012-02-18 11:17:29 +0100207 /* For non-leader processes, that's all we need to do. */
Petr Machatad3cc9882012-04-13 21:40:23 +0200208 if (retp->leader != retp)
Petr Machata2b46cfc2012-02-18 11:17:29 +0100209 return 0;
210
211 /* Clone symbols first so that we can clone and relink
212 * breakpoints. */
213 struct library *lib;
214 struct library **nlibp = &retp->libraries;
215 for (lib = proc->libraries; lib != NULL; lib = lib->next) {
216 *nlibp = malloc(sizeof(**nlibp));
217 if (*nlibp == NULL
218 || library_clone(*nlibp, lib) < 0) {
219 fail2:
Petr Machata3d0c91c2012-04-14 02:37:38 +0200220 process_bare_destroy(retp, 0);
Petr Machata2b46cfc2012-02-18 11:17:29 +0100221
222 /* Error when cloning. Unroll what was done. */
223 for (lib = retp->libraries; lib != NULL; ) {
224 struct library *next = lib->next;
225 library_destroy(lib);
226 free(lib);
227 lib = next;
228 }
229 goto fail;
230 }
231
232 nlibp = &(*nlibp)->next;
233 }
234
235 /* Now clone breakpoints. Symbol relinking is done in
236 * clone_single_bp. */
237 struct clone_single_bp_data data = {
238 .old_proc = proc,
239 .new_proc = retp,
240 .error = 0,
241 };
242 dict_apply_to_all(proc->breakpoints, &clone_single_bp, &data);
243
Petr Machataded6f972012-04-13 23:15:48 +0200244 /* And finally the call stack. */
245 memcpy(retp->callstack, proc->callstack, sizeof(retp->callstack));
246 retp->callstack_depth = proc->callstack_depth;
247
Petr Machata2b46cfc2012-02-18 11:17:29 +0100248 if (data.error < 0)
249 goto fail2;
250
251 return 0;
Juan Cespedes273ea6d1998-03-14 23:02:40 +0100252}
253
Petr Machata3c516d52011-08-18 03:53:18 +0200254static int
Petr Machata9a5420c2011-07-09 11:21:23 +0200255open_one_pid(pid_t pid)
256{
Juan Cespedesa8909f72009-04-28 20:02:41 +0200257 Process *proc;
Ian Wienand2d45b1a2006-02-20 22:48:07 +0100258 char *filename;
Petr Machata9a5420c2011-07-09 11:21:23 +0200259 debug(DEBUG_PROCESS, "open_one_pid(pid=%d)", pid);
260
Petr Machata1974dbc2011-08-19 18:58:01 +0200261 /* Get the filename first. Should the trace_pid fail, we can
262 * easily free it, untracing is more work. */
263 if ((filename = pid2name(pid)) == NULL
264 || trace_pid(pid) < 0) {
265 free(filename);
266 return -1;
267 }
Juan Cespedes35d70631998-03-15 14:05:40 +0100268
Petr Machata75934ad2012-04-14 02:28:03 +0200269 proc = open_program(filename, pid);
Petr Machata1974dbc2011-08-19 18:58:01 +0200270 if (proc == NULL)
271 return -1;
Petr Machata3ed2a422012-04-06 17:18:55 +0200272 trace_set_options(proc);
Petr Machata3c516d52011-08-18 03:53:18 +0200273
Petr Machata1974dbc2011-08-19 18:58:01 +0200274 return 0;
275}
276
Petr Machata2b46cfc2012-02-18 11:17:29 +0100277static enum callback_status
Petr Machata1974dbc2011-08-19 18:58:01 +0200278start_one_pid(Process * proc, void * data)
279{
280 continue_process(proc->pid);
Petr Machata2b46cfc2012-02-18 11:17:29 +0100281 return CBS_CONT;
Juan Cespedes273ea6d1998-03-14 23:02:40 +0100282}
Juan Cespedese74c80d2009-02-11 11:32:31 +0100283
Petr Machata9a5420c2011-07-09 11:21:23 +0200284void
285open_pid(pid_t pid)
286{
287 debug(DEBUG_PROCESS, "open_pid(pid=%d)", pid);
Petr Machata3c516d52011-08-18 03:53:18 +0200288 /* If we are already tracing this guy, we should be seeing all
289 * his children via normal tracing route. */
290 if (pid2proc(pid) != NULL)
291 return;
Petr Machata9a5420c2011-07-09 11:21:23 +0200292
Petr Machata3c516d52011-08-18 03:53:18 +0200293 /* First, see if we can attach the requested PID itself. */
Petr Machata1974dbc2011-08-19 18:58:01 +0200294 if (open_one_pid(pid)) {
Petr Machata3c516d52011-08-18 03:53:18 +0200295 fprintf(stderr, "Cannot attach to pid %u: %s\n",
296 pid, strerror(errno));
Petr Machatacec06ec2012-04-10 13:31:55 +0200297 trace_fail_warning(pid);
Petr Machata3c516d52011-08-18 03:53:18 +0200298 return;
Petr Machata9a5420c2011-07-09 11:21:23 +0200299 }
300
Petr Machata3c516d52011-08-18 03:53:18 +0200301 /* Now attach to all tasks that belong to that PID. There's a
302 * race between process_tasks and open_one_pid. So when we
303 * fail in open_one_pid below, we just do another round.
304 * Chances are that by then that PID will have gone away, and
305 * that's why we have seen the failure. The processes that we
306 * manage to open_one_pid are stopped, so we should eventually
307 * reach a point where process_tasks doesn't give any new
308 * processes (because there's nobody left to produce
309 * them). */
Petr Machata1974dbc2011-08-19 18:58:01 +0200310 size_t old_ntasks = 0;
Petr Machata3c516d52011-08-18 03:53:18 +0200311 int have_all;
Petr Machata1974dbc2011-08-19 18:58:01 +0200312 while (1) {
Petr Machata3c516d52011-08-18 03:53:18 +0200313 pid_t *tasks;
314 size_t ntasks;
315 size_t i;
Petr Machata1974dbc2011-08-19 18:58:01 +0200316
Petr Machata3c516d52011-08-18 03:53:18 +0200317 if (process_tasks(pid, &tasks, &ntasks) < 0) {
318 fprintf(stderr, "Cannot obtain tasks of pid %u: %s\n",
319 pid, strerror(errno));
Petr Machatafed1e8d2012-02-07 02:06:29 +0100320 break;
Petr Machata3c516d52011-08-18 03:53:18 +0200321 }
Petr Machata9a5420c2011-07-09 11:21:23 +0200322
Petr Machata3c516d52011-08-18 03:53:18 +0200323 have_all = 1;
324 for (i = 0; i < ntasks; ++i)
325 if (pid2proc(tasks[i]) == NULL
Petr Machata1974dbc2011-08-19 18:58:01 +0200326 && open_one_pid(tasks[i]))
Petr Machata3c516d52011-08-18 03:53:18 +0200327 have_all = 0;
328
Petr Machata9a5420c2011-07-09 11:21:23 +0200329 free(tasks);
Petr Machata3c516d52011-08-18 03:53:18 +0200330
Petr Machata1974dbc2011-08-19 18:58:01 +0200331 if (have_all && old_ntasks == ntasks)
332 break;
333 old_ntasks = ntasks;
334 }
335
336 /* Done. Now initialize breakpoints and then continue
337 * everyone. */
338 Process * leader;
Petr Machata1974dbc2011-08-19 18:58:01 +0200339 leader = pid2proc(pid)->leader;
340 enable_all_breakpoints(leader);
341
Petr Machata74132a42012-03-16 02:46:18 +0100342 each_task(pid2proc(pid)->leader, NULL, start_one_pid, NULL);
Petr Machata9a5420c2011-07-09 11:21:23 +0200343}
344
Petr Machata2b46cfc2012-02-18 11:17:29 +0100345static enum callback_status
Petr Machatacebb8842011-07-09 11:14:11 +0200346find_proc(Process * proc, void * data)
347{
348 pid_t pid = (pid_t)(uintptr_t)data;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100349 return proc->pid == pid ? CBS_STOP : CBS_CONT;
Petr Machatacebb8842011-07-09 11:14:11 +0200350}
351
Juan Cespedesa8909f72009-04-28 20:02:41 +0200352Process *
Juan Cespedese74c80d2009-02-11 11:32:31 +0100353pid2proc(pid_t pid) {
Petr Machatacebb8842011-07-09 11:14:11 +0200354 return each_process(NULL, &find_proc, (void *)(uintptr_t)pid);
355}
Juan Cespedese74c80d2009-02-11 11:32:31 +0100356
Petr Machatacebb8842011-07-09 11:14:11 +0200357static Process * list_of_processes = NULL;
358
Petr Machatacbe29c62011-09-27 02:27:58 +0200359static void
360unlist_process(Process * proc)
361{
362 Process *tmp;
363
364 if (list_of_processes == proc) {
365 list_of_processes = list_of_processes->next;
366 return;
367 }
368
369 for (tmp = list_of_processes; ; tmp = tmp->next) {
370 /* If the following assert fails, the process wasn't
371 * in the list. */
372 assert(tmp->next != NULL);
373
374 if (tmp->next == proc) {
375 tmp->next = tmp->next->next;
376 return;
377 }
378 }
379}
380
Petr Machata2b46cfc2012-02-18 11:17:29 +0100381struct Process *
Petr Machata74132a42012-03-16 02:46:18 +0100382each_process(struct Process *start_after,
Petr Machata2b46cfc2012-02-18 11:17:29 +0100383 enum callback_status(*cb)(struct Process *proc, void *data),
384 void *data)
Petr Machatacebb8842011-07-09 11:14:11 +0200385{
Petr Machata74132a42012-03-16 02:46:18 +0100386 struct Process *it = start_after == NULL ? list_of_processes
387 : start_after->next;
388
389 while (it != NULL) {
Petr Machatacebb8842011-07-09 11:14:11 +0200390 /* Callback might call remove_process. */
Petr Machata74132a42012-03-16 02:46:18 +0100391 struct Process *next = it->next;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100392 switch ((*cb)(it, data)) {
Petr Machataef7fa372012-03-28 02:05:36 +0200393 case CBS_FAIL:
394 /* XXX handle me */
Petr Machata2b46cfc2012-02-18 11:17:29 +0100395 case CBS_STOP:
Petr Machatacebb8842011-07-09 11:14:11 +0200396 return it;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100397 case CBS_CONT:
398 break;
399 }
Petr Machatacebb8842011-07-09 11:14:11 +0200400 it = next;
401 }
402 return NULL;
403}
Petr Machata9a5420c2011-07-09 11:21:23 +0200404
405Process *
Petr Machata74132a42012-03-16 02:46:18 +0100406each_task(struct Process *proc, struct Process *start_after,
Petr Machata2b46cfc2012-02-18 11:17:29 +0100407 enum callback_status(*cb)(struct Process *proc, void *data),
408 void *data)
Petr Machata9a5420c2011-07-09 11:21:23 +0200409{
Petr Machata74132a42012-03-16 02:46:18 +0100410 assert(proc != NULL);
411 struct Process *it = start_after == NULL ? proc->leader
412 : start_after->next;
413
Petr Machata9a5420c2011-07-09 11:21:23 +0200414 if (it != NULL) {
Petr Machata74132a42012-03-16 02:46:18 +0100415 struct Process *leader = it->leader;
416 while (it != NULL && it->leader == leader) {
Petr Machata9a5420c2011-07-09 11:21:23 +0200417 /* Callback might call remove_process. */
Petr Machata74132a42012-03-16 02:46:18 +0100418 struct Process *next = it->next;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100419 switch ((*cb)(it, data)) {
Petr Machataef7fa372012-03-28 02:05:36 +0200420 case CBS_FAIL:
421 /* XXX handle me */
Petr Machata2b46cfc2012-02-18 11:17:29 +0100422 case CBS_STOP:
Petr Machata9a5420c2011-07-09 11:21:23 +0200423 return it;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100424 case CBS_CONT:
425 break;
426 }
Petr Machata9a5420c2011-07-09 11:21:23 +0200427 it = next;
428 }
429 }
430 return NULL;
431}
432
Petr Machata44965c72012-04-06 19:59:20 +0200433static void
Petr Machata3d0c91c2012-04-14 02:37:38 +0200434add_process(struct Process *proc, int was_exec)
Petr Machatacebb8842011-07-09 11:14:11 +0200435{
Petr Machata9a5420c2011-07-09 11:21:23 +0200436 Process ** leaderp = &list_of_processes;
437 if (proc->pid) {
438 pid_t tgid = process_leader(proc->pid);
Petr Machata1974dbc2011-08-19 18:58:01 +0200439 if (tgid == 0)
440 /* Must have been terminated before we managed
441 * to fully attach. */
442 return;
Petr Machata9a5420c2011-07-09 11:21:23 +0200443 if (tgid == proc->pid)
444 proc->leader = proc;
445 else {
446 Process * leader = pid2proc(tgid);
447 proc->leader = leader;
448 if (leader != NULL)
Petr Machata9a5420c2011-07-09 11:21:23 +0200449 leaderp = &leader->next;
450 }
451 }
Petr Machata3d0c91c2012-04-14 02:37:38 +0200452
453 if (!was_exec) {
454 proc->next = *leaderp;
455 *leaderp = proc;
456 }
Petr Machata9a5420c2011-07-09 11:21:23 +0200457}
458
Petr Machatacbe29c62011-09-27 02:27:58 +0200459void
460change_process_leader(Process * proc, Process * leader)
461{
462 Process ** leaderp = &list_of_processes;
463 if (proc->leader == leader)
464 return;
465
466 assert(leader != NULL);
467 unlist_process(proc);
468 if (proc != leader)
469 leaderp = &leader->next;
470
471 proc->leader = leader;
472 proc->next = *leaderp;
473 *leaderp = proc;
474}
475
Petr Machata2b46cfc2012-02-18 11:17:29 +0100476static enum callback_status
477clear_leader(struct Process *proc, void *data)
Petr Machata9a5420c2011-07-09 11:21:23 +0200478{
479 debug(DEBUG_FUNCTION, "detach_task %d from leader %d",
480 proc->pid, proc->leader->pid);
481 proc->leader = NULL;
Petr Machata2b46cfc2012-02-18 11:17:29 +0100482 return CBS_CONT;
Petr Machatacebb8842011-07-09 11:14:11 +0200483}
484
Petr Machata69a03e62011-07-09 11:29:12 +0200485static enum ecb_status
486event_for_proc(Event * event, void * data)
487{
488 if (event->proc == data)
489 return ecb_deque;
490 else
491 return ecb_cont;
492}
493
494static void
495delete_events_for(Process * proc)
496{
497 Event * event;
498 while ((event = each_qd_event(&event_for_proc, proc)) != NULL)
499 free(event);
500}
501
Petr Machatacebb8842011-07-09 11:14:11 +0200502void
503remove_process(Process *proc)
504{
Petr Machatacebb8842011-07-09 11:14:11 +0200505 debug(DEBUG_FUNCTION, "remove_proc(pid=%d)", proc->pid);
506
Petr Machata9a5420c2011-07-09 11:21:23 +0200507 if (proc->leader == proc)
Petr Machata74132a42012-03-16 02:46:18 +0100508 each_task(proc, NULL, &clear_leader, NULL);
Petr Machata9a5420c2011-07-09 11:21:23 +0200509
Petr Machatacbe29c62011-09-27 02:27:58 +0200510 unlist_process(proc);
511 delete_events_for(proc);
Juan Cespedese74c80d2009-02-11 11:32:31 +0100512}
Petr Machata4007d742011-07-09 11:29:42 +0200513
514void
Petr Machata366c2f42012-02-09 19:34:36 +0100515install_event_handler(Process *proc, struct event_handler *handler)
Petr Machata4007d742011-07-09 11:29:42 +0200516{
Petr Machata75dcf7d2011-10-06 14:30:19 +0200517 debug(DEBUG_FUNCTION, "install_event_handler(pid=%d, %p)", proc->pid, handler);
Petr Machata4007d742011-07-09 11:29:42 +0200518 assert(proc->event_handler == NULL);
519 proc->event_handler = handler;
520}
521
522void
523destroy_event_handler(Process * proc)
524{
Petr Machata366c2f42012-02-09 19:34:36 +0100525 struct event_handler *handler = proc->event_handler;
Petr Machata75dcf7d2011-10-06 14:30:19 +0200526 debug(DEBUG_FUNCTION, "destroy_event_handler(pid=%d, %p)", proc->pid, handler);
Petr Machata4007d742011-07-09 11:29:42 +0200527 assert(handler != NULL);
Petr Machatacbe29c62011-09-27 02:27:58 +0200528 if (handler->destroy != NULL)
529 handler->destroy(handler);
Petr Machata4007d742011-07-09 11:29:42 +0200530 free(handler);
531 proc->event_handler = NULL;
532}
Petr Machata2b46cfc2012-02-18 11:17:29 +0100533
534static enum callback_status
535breakpoint_for_symbol(struct library_symbol *libsym, void *data)
536{
537 struct Process *proc = data;
Petr Machatad5e85562012-04-05 15:18:38 +0200538 assert(proc->leader == proc);
Petr Machata2b46cfc2012-02-18 11:17:29 +0100539
Petr Machatad5e85562012-04-05 15:18:38 +0200540 /* If there is an artificial breakpoint on the same address,
541 * its libsym will be NULL, and we can smuggle our libsym
542 * there. That artificial breakpoint is there presumably for
543 * the callbacks, which we don't touch. If there is a real
544 * breakpoint, then this is a bug. ltrace-elf.c should filter
Petr Machataa2416362012-04-06 02:43:34 +0200545 * symbols and ignore extra symbol aliases.
546 *
547 * The other direction is more complicated and currently not
548 * supported. If a breakpoint has custom callbacks, it might
549 * be also custom-allocated, and we would really need to swap
550 * the two: delete the one now in the dictionary, swap values
551 * around, and put the new breakpoint back in. */
Petr Machatad5e85562012-04-05 15:18:38 +0200552 struct breakpoint *bp = dict_find_entry(proc->breakpoints,
553 libsym->enter_addr);
554 if (bp != NULL) {
555 assert(bp->libsym == NULL);
556 bp->libsym = libsym;
557 return CBS_CONT;
558 }
559
560 bp = malloc(sizeof(*bp));
Petr Machata3fd099b2012-04-03 02:25:42 +0200561 if (bp == NULL
562 || breakpoint_init(bp, proc, libsym->enter_addr, libsym) < 0) {
563 fail:
564 free(bp);
565 return CBS_FAIL;
566 }
567 if (proc_add_breakpoint(proc, bp) < 0) {
568 breakpoint_destroy(bp);
569 goto fail;
570 }
Petr Machata2b46cfc2012-02-18 11:17:29 +0100571
Petr Machatafa0c5702012-04-13 18:43:40 +0200572 if (breakpoint_turn_on(bp, proc) < 0) {
Petr Machata76dd9292012-04-03 13:02:06 +0200573 proc_remove_breakpoint(proc, bp);
574 breakpoint_destroy(bp);
575 goto fail;
576 }
577
Petr Machata2b46cfc2012-02-18 11:17:29 +0100578 return CBS_CONT;
579}
580
581void
582proc_add_library(struct Process *proc, struct library *lib)
583{
584 assert(lib->next == NULL);
585 lib->next = proc->libraries;
586 proc->libraries = lib;
Petr Machata8b00d5b2012-04-06 16:05:10 +0200587 debug(DEBUG_PROCESS, "added library %s@%p (%s) to %d",
588 lib->soname, lib->base, lib->pathname, proc->pid);
Petr Machata2b46cfc2012-02-18 11:17:29 +0100589
590 struct library_symbol *libsym = NULL;
591 while ((libsym = library_each_symbol(lib, libsym, breakpoint_for_symbol,
Petr Machata74132a42012-03-16 02:46:18 +0100592 proc)) != NULL)
Petr Machata2b46cfc2012-02-18 11:17:29 +0100593 error(0, errno, "insert breakpoint for %s", libsym->name);
Petr Machata2b46cfc2012-02-18 11:17:29 +0100594}
595
596int
597proc_remove_library(struct Process *proc, struct library *lib)
598{
599 struct library **libp;
600 for (libp = &proc->libraries; *libp != NULL; libp = &(*libp)->next)
601 if (*libp == lib) {
602 *libp = lib->next;
603 return 0;
604 }
605 return -1;
606}
607
608struct library *
609proc_each_library(struct Process *proc, struct library *it,
610 enum callback_status (*cb)(struct Process *proc,
611 struct library *lib, void *data),
612 void *data)
613{
614 if (it == NULL)
615 it = proc->libraries;
616
617 while (it != NULL) {
618 struct library *next = it->next;
619
620 switch (cb(proc, it, data)) {
Petr Machataef7fa372012-03-28 02:05:36 +0200621 case CBS_FAIL:
622 /* XXX handle me */
Petr Machata2b46cfc2012-02-18 11:17:29 +0100623 case CBS_STOP:
624 return it;
625 case CBS_CONT:
626 break;
627 }
628
629 it = next;
630 }
631
632 return NULL;
633}
Petr Machata52dbfb12012-03-29 16:38:26 +0200634
635int
636proc_add_breakpoint(struct Process *proc, struct breakpoint *bp)
637{
Petr Machata52dbfb12012-03-29 16:38:26 +0200638 /* Only the group leader should be getting the breakpoints and
639 * thus have ->breakpoint initialized. */
Petr Machatafa0c5702012-04-13 18:43:40 +0200640 assert(proc->leader != NULL);
641 assert(proc->leader == proc);
642 assert(proc->breakpoints != NULL);
Petr Machata52dbfb12012-03-29 16:38:26 +0200643
Petr Machatafa0c5702012-04-13 18:43:40 +0200644 debug(DEBUG_FUNCTION, "proc_add_breakpoint(pid=%d, %s@%p)",
Petr Machata52dbfb12012-03-29 16:38:26 +0200645 proc->pid, breakpoint_name(bp), bp->addr);
646
Petr Machataa2416362012-04-06 02:43:34 +0200647 /* XXX We might merge bp->libsym instead of the following
Petr Machata00928202012-04-07 01:14:24 +0200648 * assert, but that's not necessary right now. Read the
649 * comment in breakpoint_for_symbol. */
Petr Machatafa0c5702012-04-13 18:43:40 +0200650 assert(dict_find_entry(proc->breakpoints, bp->addr) == NULL);
Petr Machataa2416362012-04-06 02:43:34 +0200651
Petr Machatafa0c5702012-04-13 18:43:40 +0200652 if (dict_enter(proc->breakpoints, bp->addr, bp) < 0) {
Petr Machata52dbfb12012-03-29 16:38:26 +0200653 error(0, errno, "couldn't enter breakpoint %s@%p to dictionary",
654 breakpoint_name(bp), bp->addr);
655 return -1;
656 }
657
Petr Machata52dbfb12012-03-29 16:38:26 +0200658 return 0;
659}
660
661int
662proc_remove_breakpoint(struct Process *proc, struct breakpoint *bp)
663{
664 /* XXX We can't, really. We are missing dict_remove. */
665 assert(!"Not yet implemented!");
666 abort();
667}
Petr Machatad3cc9882012-04-13 21:40:23 +0200668
669/* Dict doesn't support iteration restarts, so here's this contraption
670 * for now. XXX add restarts to dict. */
671struct each_breakpoint_data
672{
673 void *start;
674 void *end;
675 struct Process *proc;
676 enum callback_status (*cb)(struct Process *proc,
677 struct breakpoint *bp,
678 void *data);
679 void *cb_data;
680};
681
682static void
683each_breakpoint_cb(void *key, void *value, void *d)
684{
685 struct each_breakpoint_data *data = d;
686 if (data->end != NULL)
687 return;
688 if (data->start == key)
689 data->start = NULL;
690
691 if (data->start == NULL) {
692 switch (data->cb(data->proc, value, data->cb_data)) {
693 case CBS_FAIL:
694 /* XXX handle me */
695 case CBS_STOP:
696 data->end = key;
697 case CBS_CONT:
698 return;
699 }
700 }
701}
702
703void *
704proc_each_breakpoint(struct Process *proc, void *start,
705 enum callback_status (*cb)(struct Process *proc,
706 struct breakpoint *bp,
707 void *data), void *data)
708{
709 struct each_breakpoint_data dd = {
710 .start = start,
711 .proc = proc,
712 .cb = cb,
713 .cb_data = data,
714 };
715 dict_apply_to_all(proc->breakpoints, &each_breakpoint_cb, &dd);
716 return dd.end;
717}