blob: eba030f3278e44b80af87bae79a809a5fa6df4ce [file] [log] [blame]
Petr Machata750ca8c2011-10-06 14:29:34 +02001#define _GNU_SOURCE /* For getline. */
Juan Cespedesd44c6b81998-09-25 14:48:42 +02002#include "config.h"
Juan Cespedesd44c6b81998-09-25 14:48:42 +02003
Juan Cespedes1fe93d51998-03-13 00:29:21 +01004#include <sys/types.h>
Petr Machata9a5420c2011-07-09 11:21:23 +02005#include <sys/stat.h>
6#include <fcntl.h>
Zachary T Welchbfb26c72010-12-06 23:21:00 -08007#include <inttypes.h>
Joe Damato47cae1e2010-11-08 15:47:39 -08008#include <link.h>
Juan Cespedes1fe93d51998-03-13 00:29:21 +01009#include <stdio.h>
10#include <string.h>
11#include <signal.h>
Juan Cespedes273ea6d1998-03-14 23:02:40 +010012#include <unistd.h>
Petr Machata9a5420c2011-07-09 11:21:23 +020013#include <dirent.h>
14#include <ctype.h>
15#include <errno.h>
16#include <sys/syscall.h>
Petr Machata750ca8c2011-10-06 14:29:34 +020017#include <error.h>
Petr Machata9a5420c2011-07-09 11:21:23 +020018
Petr Machataa611fc82012-02-07 13:27:04 +010019#include "common.h"
Petr Machata9294d822012-02-07 12:35:58 +010020#include "breakpoint.h"
Petr Machata366c2f42012-02-09 19:34:36 +010021#include "proc.h"
Juan Cespedes273ea6d1998-03-14 23:02:40 +010022
23/* /proc/pid doesn't exist just after the fork, and sometimes `ltrace'
24 * couldn't open it to find the executable. So it may be necessary to
25 * have a bit delay
26 */
27
Ian Wienand2d45b1a2006-02-20 22:48:07 +010028#define MAX_DELAY 100000 /* 100000 microseconds = 0.1 seconds */
Juan Cespedes1fe93d51998-03-13 00:29:21 +010029
Petr Machata9a5420c2011-07-09 11:21:23 +020030#define PROC_PID_FILE(VAR, FORMAT, PID) \
31 char VAR[strlen(FORMAT) + 6]; \
32 sprintf(VAR, FORMAT, PID)
33
Juan Cespedes1fe93d51998-03-13 00:29:21 +010034/*
Juan Cespedese0660df2009-05-21 18:14:39 +020035 * Returns a (malloc'd) file name corresponding to a running pid
Juan Cespedes1fe93d51998-03-13 00:29:21 +010036 */
Juan Cespedesf1350522008-12-16 18:19:58 +010037char *
38pid2name(pid_t pid) {
Juan Cespedes1fe93d51998-03-13 00:29:21 +010039 if (!kill(pid, 0)) {
Ian Wienand2d45b1a2006-02-20 22:48:07 +010040 int delay = 0;
Juan Cespedes273ea6d1998-03-14 23:02:40 +010041
Petr Machata9a5420c2011-07-09 11:21:23 +020042 PROC_PID_FILE(proc_exe, "/proc/%d/exe", pid);
Juan Cespedes273ea6d1998-03-14 23:02:40 +010043
Ian Wienand2d45b1a2006-02-20 22:48:07 +010044 while (delay < MAX_DELAY) {
Juan Cespedes273ea6d1998-03-14 23:02:40 +010045 if (!access(proc_exe, F_OK)) {
46 return strdup(proc_exe);
47 }
48 delay += 1000; /* 1 milisecond */
49 }
Juan Cespedes1fe93d51998-03-13 00:29:21 +010050 }
Juan Cespedes273ea6d1998-03-14 23:02:40 +010051 return NULL;
Juan Cespedes1fe93d51998-03-13 00:29:21 +010052}
Joe Damato47cae1e2010-11-08 15:47:39 -080053
Petr Machata9a5420c2011-07-09 11:21:23 +020054static FILE *
55open_status_file(pid_t pid)
56{
57 PROC_PID_FILE(fn, "/proc/%d/status", pid);
58 /* Don't complain if we fail. This would typically happen
59 when the process is about to terminate, and these files are
60 not available anymore. This function is called from the
61 event loop, and we don't want to clutter the output just
62 because the process terminates. */
63 return fopen(fn, "r");
64}
65
66static char *
67find_line_starting(FILE * file, const char * prefix, size_t len)
68{
69 char * line = NULL;
70 size_t line_len = 0;
71 while (!feof(file)) {
72 if (getline(&line, &line_len, file) < 0)
73 return NULL;
74 if (strncmp(line, prefix, len) == 0)
75 return line;
76 }
77 return NULL;
78}
79
80static void
81each_line_starting(FILE * file, const char *prefix,
82 enum pcb_status (*cb)(const char * line, const char * prefix,
83 void * data),
84 void * data)
85{
86 size_t len = strlen(prefix);
87 char * line;
88 while ((line = find_line_starting(file, prefix, len)) != NULL) {
89 enum pcb_status st = (*cb)(line, prefix, data);
90 free (line);
91 if (st == pcb_stop)
92 return;
93 }
94}
95
96static enum pcb_status
97process_leader_cb(const char * line, const char * prefix, void * data)
98{
99 pid_t * pidp = data;
100 *pidp = atoi(line + strlen(prefix));
101 return pcb_stop;
102}
103
104pid_t
105process_leader(pid_t pid)
106{
Petr Machata1974dbc2011-08-19 18:58:01 +0200107 pid_t tgid = 0;
Petr Machata9a5420c2011-07-09 11:21:23 +0200108 FILE * file = open_status_file(pid);
109 if (file != NULL) {
110 each_line_starting(file, "Tgid:\t", &process_leader_cb, &tgid);
111 fclose(file);
112 }
113
114 return tgid;
115}
116
117static enum pcb_status
118process_stopped_cb(const char * line, const char * prefix, void * data)
119{
120 char c = line[strlen(prefix)];
121 // t:tracing stop, T:job control stop
122 *(int *)data = (c == 't' || c == 'T');
123 return pcb_stop;
124}
125
126int
127process_stopped(pid_t pid)
128{
129 int is_stopped = -1;
130 FILE * file = open_status_file(pid);
131 if (file != NULL) {
132 each_line_starting(file, "State:\t", &process_stopped_cb,
133 &is_stopped);
134 fclose(file);
135 }
136 return is_stopped;
137}
138
139static enum pcb_status
140process_status_cb(const char * line, const char * prefix, void * data)
141{
Petr Machata617ff0b2011-10-06 14:23:24 +0200142 const char * status = line + strlen(prefix);
143 const char c = *status;
144
145#define RETURN(C) do { \
146 *(enum process_status *)data = C; \
147 return pcb_stop; \
148 } while (0)
149
150 switch (c) {
151 case 'Z': RETURN(ps_zombie);
152 case 't': RETURN(ps_tracing_stop);
Petr Machatacbe29c62011-09-27 02:27:58 +0200153 case 'T':
Petr Machata617ff0b2011-10-06 14:23:24 +0200154 /* This can be either "T (stopped)" or, for older
155 * kernels, "T (tracing stop)". */
156 if (!strcmp(status, "T (stopped)\n"))
157 RETURN(ps_stop);
158 else if (!strcmp(status, "T (tracing stop)\n"))
159 RETURN(ps_tracing_stop);
160 else {
161 fprintf(stderr, "Unknown process status: %s",
162 status);
163 RETURN(ps_stop); /* Some sort of stop
164 * anyway. */
165 }
Petr Machatacbe29c62011-09-27 02:27:58 +0200166 case 'D':
167 case 'S': RETURN(ps_sleeping);
Petr Machata617ff0b2011-10-06 14:23:24 +0200168 }
169
170 RETURN(ps_other);
171#undef RETURN
Petr Machata9a5420c2011-07-09 11:21:23 +0200172}
173
Petr Machata617ff0b2011-10-06 14:23:24 +0200174enum process_status
Petr Machata9a5420c2011-07-09 11:21:23 +0200175process_status(pid_t pid)
176{
Petr Machata617ff0b2011-10-06 14:23:24 +0200177 enum process_status ret = ps_invalid;
Petr Machata9a5420c2011-07-09 11:21:23 +0200178 FILE * file = open_status_file(pid);
179 if (file != NULL) {
180 each_line_starting(file, "State:\t", &process_status_cb, &ret);
181 fclose(file);
Petr Machata750ca8c2011-10-06 14:29:34 +0200182 if (ret == ps_invalid)
183 error(0, errno, "process_status %d", pid);
184 } else
185 /* If the file is not present, the process presumably
186 * exited already. */
187 ret = ps_zombie;
188
Petr Machata9a5420c2011-07-09 11:21:23 +0200189 return ret;
190}
191
192static int
193all_digits(const char *str)
194{
195 while (isdigit(*str))
196 str++;
197 return !*str;
198}
199
200int
201process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n)
202{
203 PROC_PID_FILE(fn, "/proc/%d/task", pid);
204 DIR * d = opendir(fn);
205 if (d == NULL)
206 return -1;
207
Petr Machata9a5420c2011-07-09 11:21:23 +0200208 pid_t *tasks = NULL;
209 size_t n = 0;
210 size_t alloc = 0;
211
212 while (1) {
213 struct dirent entry;
214 struct dirent *result;
215 if (readdir_r(d, &entry, &result) != 0) {
216 free(tasks);
217 return -1;
218 }
219 if (result == NULL)
220 break;
221 if (result->d_type == DT_DIR && all_digits(result->d_name)) {
222 pid_t npid = atoi(result->d_name);
223 if (n >= alloc) {
224 alloc = alloc > 0 ? (2 * alloc) : 8;
225 pid_t *ntasks = realloc(tasks,
226 sizeof(*tasks) * alloc);
227 if (ntasks == NULL) {
228 free(tasks);
229 return -1;
230 }
231 tasks = ntasks;
232 }
233 if (n >= alloc)
234 abort();
235 tasks[n++] = npid;
236 }
237 }
238
239 closedir(d);
240
241 *ret_tasks = tasks;
242 *ret_n = n;
243 return 0;
244}
245
Joe Damato47cae1e2010-11-08 15:47:39 -0800246static int
247find_dynamic_entry_addr(Process *proc, void *pvAddr, int d_tag, void **addr) {
248 int i = 0, done = 0;
249 ElfW(Dyn) entry;
250
251 debug(DEBUG_FUNCTION, "find_dynamic_entry()");
252
253 if (addr == NULL || pvAddr == NULL || d_tag < 0 || d_tag > DT_NUM) {
254 return -1;
255 }
256
257 while ((!done) && (i < ELF_MAX_SEGMENTS) &&
258 (sizeof(entry) == umovebytes(proc, pvAddr, &entry, sizeof(entry))) &&
259 (entry.d_tag != DT_NULL)) {
260 if (entry.d_tag == d_tag) {
261 done = 1;
262 *addr = (void *)entry.d_un.d_val;
263 }
264 pvAddr += sizeof(entry);
265 i++;
266 }
267
268 if (done) {
269 debug(2, "found address: 0x%p in dtag %d\n", *addr, d_tag);
270 return 0;
271 }
272 else {
273 debug(2, "Couldn't address for dtag!\n");
274 return -1;
275 }
276}
Joe Damatof0bd98b2010-11-08 15:47:42 -0800277
278struct cb_data {
279 const char *lib_name;
280 struct ltelf *lte;
281 ElfW(Addr) addr;
282 Process *proc;
283};
284
285static void
286crawl_linkmap(Process *proc, struct r_debug *dbg, void (*callback)(void *), struct cb_data *data) {
287 struct link_map rlm;
288 char lib_name[BUFSIZ];
289 struct link_map *lm = NULL;
290
291 debug (DEBUG_FUNCTION, "crawl_linkmap()");
292
293 if (!dbg || !dbg->r_map) {
294 debug(2, "Debug structure or it's linkmap are NULL!");
295 return;
296 }
297
298 lm = dbg->r_map;
299
300 while (lm) {
301 if (umovebytes(proc, lm, &rlm, sizeof(rlm)) != sizeof(rlm)) {
302 debug(2, "Unable to read link map\n");
303 return;
304 }
305
306 lm = rlm.l_next;
307 if (rlm.l_name == NULL) {
308 debug(2, "Invalid library name referenced in dynamic linker map\n");
309 return;
310 }
311
312 umovebytes(proc, rlm.l_name, lib_name, sizeof(lib_name));
313
314 if (lib_name[0] == '\0') {
315 debug(2, "Library name is an empty string");
316 continue;
317 }
318
319 if (callback) {
Zachary T Welch3ba522f2010-12-14 15:12:47 -0800320 debug(2, "Dispatching callback for: %s, "
321 "Loaded at 0x%" PRI_ELF_ADDR "\n",
322 lib_name, rlm.l_addr);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800323 data->addr = rlm.l_addr;
324 data->lib_name = lib_name;
325 callback(data);
326 }
327 }
328 return;
329}
330
331static struct r_debug *
332load_debug_struct(Process *proc) {
333 struct r_debug *rdbg = NULL;
334
335 debug(DEBUG_FUNCTION, "load_debug_struct");
336
337 rdbg = malloc(sizeof(*rdbg));
338 if (!rdbg) {
339 return NULL;
340 }
341
342 if (umovebytes(proc, proc->debug, rdbg, sizeof(*rdbg)) != sizeof(*rdbg)) {
343 debug(2, "This process does not have a debug structure!\n");
344 free(rdbg);
345 return NULL;
346 }
347
348 return rdbg;
349}
350
351static void
352linkmap_add_cb(void *data) { //const char *lib_name, ElfW(Addr) addr) {
Zachary T Welchba6aca22010-12-08 18:55:09 -0800353 size_t i = 0;
Joe Damatof0bd98b2010-11-08 15:47:42 -0800354 struct cb_data *lm_add = data;
355 struct ltelf lte;
356 struct opt_x_t *xptr;
357
358 debug(DEBUG_FUNCTION, "linkmap_add_cb");
359
360 /*
361 XXX
362 iterate through library[i]'s to see if this lib is in the list.
363 if not, add it
364 */
365 for(;i < library_num;i++) {
366 if (strcmp(library[i], lm_add->lib_name) == 0) {
367 /* found it, so its not new */
368 return;
369 }
370 }
371
372 /* new library linked! */
373 debug(2, "New libdl loaded library found: %s\n", lm_add->lib_name);
374
375 if (library_num < MAX_LIBRARIES) {
376 library[library_num++] = strdup(lm_add->lib_name);
377 memset(&lte, 0, sizeof(struct ltelf));
378 lte.base_addr = lm_add->addr;
379 do_init_elf(&lte, library[library_num-1]);
380 /* add bps */
381 for (xptr = opt_x; xptr; xptr = xptr->next) {
382 if (xptr->found)
383 continue;
384
385 GElf_Sym sym;
386 GElf_Addr addr;
387
388 if (in_load_libraries(xptr->name, &lte, 1, &sym)) {
Zachary T Welchbfb26c72010-12-06 23:21:00 -0800389 debug(2, "found symbol %s @ %#" PRIx64
390 ", adding it.",
391 xptr->name, sym.st_value);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800392 addr = sym.st_value;
393 add_library_symbol(addr, xptr->name, &library_symbols, LS_TOPLT_NONE, 0);
394 xptr->found = 1;
Petr Machata26627682011-07-08 18:15:32 +0200395 insert_breakpoint(lm_add->proc,
396 sym2addr(lm_add->proc,
397 library_symbols),
Petr Machatac7585b62011-07-08 22:58:12 +0200398 library_symbols, 1);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800399 }
400 }
401 do_close_elf(&lte);
402 }
403}
404
405void
406arch_check_dbg(Process *proc) {
407 struct r_debug *dbg = NULL;
408 struct cb_data data;
409
410 debug(DEBUG_FUNCTION, "arch_check_dbg");
411
412 if (!(dbg = load_debug_struct(proc))) {
413 debug(2, "Unable to load debug structure!");
414 return;
415 }
416
417 if (dbg->r_state == RT_CONSISTENT) {
418 debug(2, "Linkmap is now consistent");
419 if (proc->debug_state == RT_ADD) {
420 debug(2, "Adding DSO to linkmap");
421 data.proc = proc;
422 crawl_linkmap(proc, dbg, linkmap_add_cb, &data);
423 } else if (proc->debug_state == RT_DELETE) {
424 debug(2, "Removing DSO from linkmap");
425 } else {
426 debug(2, "Unexpected debug state!");
427 }
428 }
429
430 proc->debug_state = dbg->r_state;
431
432 return;
433}
434
435static void
436hook_libdl_cb(void *data) {
437 struct cb_data *hook_data = data;
438 const char *lib_name = NULL;
439 ElfW(Addr) addr;
440 struct ltelf *lte = NULL;
441
442 debug(DEBUG_FUNCTION, "add_library_cb");
443
444 if (!data) {
445 debug(2, "No callback data");
446 return;
447 }
448
449 lib_name = hook_data->lib_name;
450 addr = hook_data->addr;
451 lte = hook_data->lte;
452
453 if (library_num < MAX_LIBRARIES) {
Joe Damatof0bd98b2010-11-08 15:47:42 -0800454 lte[library_num].base_addr = addr;
Petr Machata08677d02011-05-19 16:09:17 +0200455 library[library_num++] = strdup(lib_name);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800456 }
457 else {
458 fprintf (stderr, "MAX LIBS REACHED\n");
459 exit(EXIT_FAILURE);
460 }
461}
462
463int
464linkmap_init(Process *proc, struct ltelf *lte) {
Zachary T Welch3ba522f2010-12-14 15:12:47 -0800465 void *dbg_addr = NULL, *dyn_addr = GELF_ADDR_CAST(lte->dyn_addr);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800466 struct r_debug *rdbg = NULL;
467 struct cb_data data;
468
469 debug(DEBUG_FUNCTION, "linkmap_init()");
470
Zachary T Welchba6aca22010-12-08 18:55:09 -0800471 if (find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, &dbg_addr) == -1) {
Joe Damatof0bd98b2010-11-08 15:47:42 -0800472 debug(2, "Couldn't find debug structure!");
473 return -1;
474 }
475
476 proc->debug = dbg_addr;
477
478 if (!(rdbg = load_debug_struct(proc))) {
479 debug(2, "No debug structure or no memory to allocate one!");
480 return -1;
481 }
482
483 data.lte = lte;
484
485 add_library_symbol(rdbg->r_brk, "", &library_symbols, LS_TOPLT_NONE, 0);
Petr Machata26627682011-07-08 18:15:32 +0200486 insert_breakpoint(proc, sym2addr(proc, library_symbols),
Petr Machatac7585b62011-07-08 22:58:12 +0200487 library_symbols, 1);
Joe Damatof0bd98b2010-11-08 15:47:42 -0800488
489 crawl_linkmap(proc, rdbg, hook_libdl_cb, &data);
490
491 free(rdbg);
492 return 0;
493}
Petr Machata9a5420c2011-07-09 11:21:23 +0200494
495int
496task_kill (pid_t pid, int sig)
497{
498 // Taken from GDB
499 int ret;
500
501 errno = 0;
502 ret = syscall (__NR_tkill, pid, sig);
503 return ret;
504}