proc.c revision 6a7997de9eabf9b0c6e32309ca08870198eb864b
1#define _GNU_SOURCE /* For getline. */ 2#include "config.h" 3 4#include <sys/types.h> 5#include <sys/stat.h> 6#include <fcntl.h> 7#include <inttypes.h> 8#include <link.h> 9#include <stdio.h> 10#include <string.h> 11#include <signal.h> 12#include <unistd.h> 13#include <dirent.h> 14#include <ctype.h> 15#include <errno.h> 16#include <sys/syscall.h> 17#include <error.h> 18 19#include "common.h" 20#include "breakpoint.h" 21#include "proc.h" 22#include "library.h" 23 24/* /proc/pid doesn't exist just after the fork, and sometimes `ltrace' 25 * couldn't open it to find the executable. So it may be necessary to 26 * have a bit delay 27 */ 28 29#define MAX_DELAY 100000 /* 100000 microseconds = 0.1 seconds */ 30 31#define PROC_PID_FILE(VAR, FORMAT, PID) \ 32 char VAR[strlen(FORMAT) + 6]; \ 33 sprintf(VAR, FORMAT, PID) 34 35/* 36 * Returns a (malloc'd) file name corresponding to a running pid 37 */ 38char * 39pid2name(pid_t pid) { 40 if (!kill(pid, 0)) { 41 int delay = 0; 42 43 PROC_PID_FILE(proc_exe, "/proc/%d/exe", pid); 44 45 while (delay < MAX_DELAY) { 46 if (!access(proc_exe, F_OK)) { 47 return strdup(proc_exe); 48 } 49 delay += 1000; /* 1 milisecond */ 50 } 51 } 52 return NULL; 53} 54 55static FILE * 56open_status_file(pid_t pid) 57{ 58 PROC_PID_FILE(fn, "/proc/%d/status", pid); 59 /* Don't complain if we fail. This would typically happen 60 when the process is about to terminate, and these files are 61 not available anymore. This function is called from the 62 event loop, and we don't want to clutter the output just 63 because the process terminates. */ 64 return fopen(fn, "r"); 65} 66 67static char * 68find_line_starting(FILE * file, const char * prefix, size_t len) 69{ 70 char * line = NULL; 71 size_t line_len = 0; 72 while (!feof(file)) { 73 if (getline(&line, &line_len, file) < 0) 74 return NULL; 75 if (strncmp(line, prefix, len) == 0) 76 return line; 77 } 78 return NULL; 79} 80 81static void 82each_line_starting(FILE *file, const char *prefix, 83 enum callback_status (*cb)(const char *line, 84 const char *prefix, 85 void *data), 86 void *data) 87{ 88 size_t len = strlen(prefix); 89 char * line; 90 while ((line = find_line_starting(file, prefix, len)) != NULL) { 91 enum callback_status st = (*cb)(line, prefix, data); 92 free (line); 93 if (st == CBS_STOP) 94 return; 95 } 96} 97 98static enum callback_status 99process_leader_cb(const char *line, const char *prefix, void *data) 100{ 101 pid_t * pidp = data; 102 *pidp = atoi(line + strlen(prefix)); 103 return CBS_STOP; 104} 105 106pid_t 107process_leader(pid_t pid) 108{ 109 pid_t tgid = 0; 110 FILE * file = open_status_file(pid); 111 if (file != NULL) { 112 each_line_starting(file, "Tgid:\t", &process_leader_cb, &tgid); 113 fclose(file); 114 } 115 116 return tgid; 117} 118 119static enum callback_status 120process_stopped_cb(const char *line, const char *prefix, void *data) 121{ 122 char c = line[strlen(prefix)]; 123 // t:tracing stop, T:job control stop 124 *(int *)data = (c == 't' || c == 'T'); 125 return CBS_STOP; 126} 127 128int 129process_stopped(pid_t pid) 130{ 131 int is_stopped = -1; 132 FILE * file = open_status_file(pid); 133 if (file != NULL) { 134 each_line_starting(file, "State:\t", &process_stopped_cb, 135 &is_stopped); 136 fclose(file); 137 } 138 return is_stopped; 139} 140 141static enum callback_status 142process_status_cb(const char *line, const char *prefix, void *data) 143{ 144 const char * status = line + strlen(prefix); 145 const char c = *status; 146 147#define RETURN(C) do { \ 148 *(enum process_status *)data = C; \ 149 return CBS_STOP; \ 150 } while (0) 151 152 switch (c) { 153 case 'Z': RETURN(ps_zombie); 154 case 't': RETURN(ps_tracing_stop); 155 case 'T': 156 /* This can be either "T (stopped)" or, for older 157 * kernels, "T (tracing stop)". */ 158 if (!strcmp(status, "T (stopped)\n")) 159 RETURN(ps_stop); 160 else if (!strcmp(status, "T (tracing stop)\n")) 161 RETURN(ps_tracing_stop); 162 else { 163 fprintf(stderr, "Unknown process status: %s", 164 status); 165 RETURN(ps_stop); /* Some sort of stop 166 * anyway. */ 167 } 168 case 'D': 169 case 'S': RETURN(ps_sleeping); 170 } 171 172 RETURN(ps_other); 173#undef RETURN 174} 175 176enum process_status 177process_status(pid_t pid) 178{ 179 enum process_status ret = ps_invalid; 180 FILE * file = open_status_file(pid); 181 if (file != NULL) { 182 each_line_starting(file, "State:\t", &process_status_cb, &ret); 183 fclose(file); 184 if (ret == ps_invalid) 185 error(0, errno, "process_status %d", pid); 186 } else 187 /* If the file is not present, the process presumably 188 * exited already. */ 189 ret = ps_zombie; 190 191 return ret; 192} 193 194static int 195all_digits(const char *str) 196{ 197 while (isdigit(*str)) 198 str++; 199 return !*str; 200} 201 202int 203process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n) 204{ 205 PROC_PID_FILE(fn, "/proc/%d/task", pid); 206 DIR * d = opendir(fn); 207 if (d == NULL) 208 return -1; 209 210 pid_t *tasks = NULL; 211 size_t n = 0; 212 size_t alloc = 0; 213 214 while (1) { 215 struct dirent entry; 216 struct dirent *result; 217 if (readdir_r(d, &entry, &result) != 0) { 218 free(tasks); 219 return -1; 220 } 221 if (result == NULL) 222 break; 223 if (result->d_type == DT_DIR && all_digits(result->d_name)) { 224 pid_t npid = atoi(result->d_name); 225 if (n >= alloc) { 226 alloc = alloc > 0 ? (2 * alloc) : 8; 227 pid_t *ntasks = realloc(tasks, 228 sizeof(*tasks) * alloc); 229 if (ntasks == NULL) { 230 free(tasks); 231 return -1; 232 } 233 tasks = ntasks; 234 } 235 if (n >= alloc) 236 abort(); 237 tasks[n++] = npid; 238 } 239 } 240 241 closedir(d); 242 243 *ret_tasks = tasks; 244 *ret_n = n; 245 return 0; 246} 247 248/* On native 64-bit system, we need to be careful when handling cross 249 * tracing. This select appropriate pointer depending on host and 250 * target architectures. XXX Really we should abstract this into the 251 * ABI object, as theorized about somewhere on pmachata/revamp 252 * branch. */ 253static void * 254select_32_64(struct Process *proc, void *p32, void *p64) 255{ 256 if (sizeof(long) == 4 || proc->mask_32bit) 257 return p32; 258 else 259 return p64; 260} 261 262static int 263fetch_dyn64(struct Process *proc, target_address_t *addr, Elf64_Dyn *ret) 264{ 265 if (umovebytes(proc, *addr, ret, sizeof(*ret)) != sizeof(*ret)) 266 return -1; 267 *addr += sizeof(*ret); 268 return 0; 269} 270 271static int 272fetch_dyn32(struct Process *proc, target_address_t *addr, Elf64_Dyn *ret) 273{ 274 Elf32_Dyn dyn; 275 if (umovebytes(proc, *addr, &dyn, sizeof(dyn)) != sizeof(dyn)) 276 return -1; 277 278 *addr += sizeof(dyn); 279 ret->d_tag = dyn.d_tag; 280 ret->d_un.d_val = dyn.d_un.d_val; 281 282 return 0; 283} 284 285static int (* 286dyn_fetcher(struct Process *proc))(struct Process *, 287 target_address_t *, Elf64_Dyn *) 288{ 289 return select_32_64(proc, fetch_dyn32, fetch_dyn64); 290} 291 292static int 293find_dynamic_entry_addr(struct Process *proc, target_address_t src_addr, 294 int d_tag, target_address_t *ret) 295{ 296 fprintf(stderr, "find_dynamic_entry_addr %d %p %d\n", 297 proc->pid, src_addr, d_tag); 298 299 debug(DEBUG_FUNCTION, "find_dynamic_entry()"); 300 301 if (ret == NULL || src_addr == 0 || d_tag < 0 || d_tag > DT_NUM) 302 return -1; 303 304 int i = 0; 305 while (1) { 306 Elf64_Dyn entry; 307 if (dyn_fetcher(proc)(proc, &src_addr, &entry) < 0 308 || entry.d_tag == DT_NULL 309 || i++ > 100) { /* Arbitrary cut-off so that we 310 * don't loop forever if the 311 * binary is corrupted. */ 312 debug(2, "Couldn't find address for dtag!"); 313 return -1; 314 } 315 316 if (entry.d_tag == d_tag) { 317 fprintf(stderr, " hit\n"); 318 *ret = (target_address_t)entry.d_un.d_val; 319 debug(2, "found address: %p in dtag %d\n", *ret, d_tag); 320 return 0; 321 } 322 } 323} 324 325/* Our own type for representing 32-bit linkmap. We can't rely on the 326 * definition in link.h, because that's only accurate for our host 327 * architecture, not for target architecture (where the traced process 328 * runs). */ 329#define LT_LINK_MAP(BITS) \ 330 { \ 331 Elf##BITS##_Addr l_addr; \ 332 Elf##BITS##_Addr l_name; \ 333 Elf##BITS##_Addr l_ld; \ 334 Elf##BITS##_Addr l_next; \ 335 Elf##BITS##_Addr l_prev; \ 336 } 337struct lt_link_map_32 LT_LINK_MAP(32); 338struct lt_link_map_64 LT_LINK_MAP(64); 339 340static int 341fetch_lm64(struct Process *proc, target_address_t addr, 342 struct lt_link_map_64 *ret) 343{ 344 if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret)) 345 return -1; 346 return 0; 347} 348 349static int 350fetch_lm32(struct Process *proc, target_address_t addr, 351 struct lt_link_map_64 *ret) 352{ 353 struct lt_link_map_32 lm; 354 if (umovebytes(proc, addr, &lm, sizeof(lm)) != sizeof(lm)) 355 return -1; 356 357 ret->l_addr = lm.l_addr; 358 ret->l_name = lm.l_name; 359 ret->l_ld = lm.l_ld; 360 ret->l_next = lm.l_next; 361 ret->l_prev = lm.l_prev; 362 363 return 0; 364} 365 366static int (* 367lm_fetcher(struct Process *proc))(struct Process *, 368 target_address_t, struct lt_link_map_64 *) 369{ 370 return select_32_64(proc, fetch_lm32, fetch_lm64); 371} 372 373/* The same as above holds for struct r_debug. */ 374#define LT_R_DEBUG(BITS) \ 375 { \ 376 int r_version; \ 377 Elf##BITS##_Addr r_map; \ 378 Elf##BITS##_Addr r_brk; \ 379 int r_state; \ 380 Elf##BITS##_Addr r_ldbase; \ 381 } 382 383struct lt_r_debug_32 LT_R_DEBUG(32); 384struct lt_r_debug_64 LT_R_DEBUG(64); 385 386static int 387fetch_rd64(struct Process *proc, target_address_t addr, 388 struct lt_r_debug_64 *ret) 389{ 390 if (umovebytes(proc, addr, ret, sizeof(*ret)) != sizeof(*ret)) 391 return -1; 392 return 0; 393} 394 395static int 396fetch_rd32(struct Process *proc, target_address_t addr, 397 struct lt_r_debug_64 *ret) 398{ 399 struct lt_r_debug_32 rd; 400 if (umovebytes(proc, addr, &rd, sizeof(rd)) != sizeof(rd)) 401 return -1; 402 403 ret->r_version = rd.r_version; 404 ret->r_map = rd.r_map; 405 ret->r_brk = rd.r_brk; 406 ret->r_state = rd.r_state; 407 ret->r_ldbase = rd.r_ldbase; 408 409 return 0; 410} 411 412static int (* 413rdebug_fetcher(struct Process *proc))(struct Process *, 414 target_address_t, struct lt_r_debug_64 *) 415{ 416 return select_32_64(proc, fetch_rd32, fetch_rd64); 417} 418 419enum callback_status 420find_library_addr(struct Process *proc, struct library *lib, void *data) 421{ 422 target_address_t addr = (target_address_t)*(GElf_Addr *)data; 423 return lib->base == addr ? CBS_STOP : CBS_CONT; 424} 425 426static void 427crawl_linkmap(struct Process *proc, struct lt_r_debug_64 *dbg) 428{ 429 debug (DEBUG_FUNCTION, "crawl_linkmap()"); 430 431 if (!dbg || !dbg->r_map) { 432 debug(2, "Debug structure or it's linkmap are NULL!"); 433 return; 434 } 435 436 target_address_t addr = (target_address_t)dbg->r_map; 437 438 while (addr != 0) { 439 struct lt_link_map_64 rlm; 440 if (lm_fetcher(proc)(proc, addr, &rlm) < 0) { 441 debug(2, "Unable to read link map\n"); 442 return; 443 } 444 445 addr = (target_address_t)rlm.l_next; 446 if (rlm.l_name == 0) { 447 debug(2, "Invalid library name referenced in dynamic linker map\n"); 448 return; 449 } 450 451 char lib_name[BUFSIZ]; 452 umovebytes(proc, (target_address_t)rlm.l_name, 453 lib_name, sizeof(lib_name)); 454 455 debug(2, "Dispatching callback for: %s, " 456 "Loaded at 0x%" PRI_ELF_ADDR "\n", 457 lib_name, rlm.l_addr); 458 fprintf(stderr, "DSO addr=%#lx, name='%s'\n", rlm.l_addr, lib_name); 459 460 /* Do we have that library already? */ 461 struct library *lib 462 = proc_each_library(proc, NULL, find_library_addr, 463 &rlm.l_addr); 464 if (lib != NULL) 465 continue; 466 467 if (*lib_name == '\0') { 468 /* VDSO. No associated file, XXX but we might 469 * load it from the address space of the 470 * process. */ 471 continue; 472 } 473 474 lib = ltelf_read_library(proc, lib_name, rlm.l_addr); 475 if (lib == NULL) { 476 error(0, errno, "Couldn't load ELF object %s\n", 477 lib_name); 478 continue; 479 } 480 481 proc_add_library(proc, lib); 482 } 483 return; 484} 485 486static int 487load_debug_struct(struct Process *proc, struct lt_r_debug_64 *ret) 488{ 489 debug(DEBUG_FUNCTION, "load_debug_struct"); 490 491 if (rdebug_fetcher(proc)(proc, proc->debug, ret) < 0) { 492 debug(2, "This process does not have a debug structure!\n"); 493 return -1; 494 } 495 496 return 0; 497} 498 499static void 500rdebug_bp_on_hit(struct breakpoint *bp, struct Process *proc) 501{ 502 fprintf(stderr, "======= HIT\n"); 503 504 debug(DEBUG_FUNCTION, "arch_check_dbg"); 505 506 struct lt_r_debug_64 rdbg; 507 if (load_debug_struct(proc, &rdbg) < 0) { 508 debug(2, "Unable to load debug structure!"); 509 return; 510 } 511 512 if (rdbg.r_state == RT_CONSISTENT) { 513 debug(2, "Linkmap is now consistent"); 514 if (proc->debug_state == RT_ADD) { 515 debug(2, "Adding DSO to linkmap"); 516 //data.proc = proc; 517 crawl_linkmap(proc, &rdbg); 518 //&data); 519 } else if (proc->debug_state == RT_DELETE) { 520 debug(2, "Removing DSO from linkmap"); 521 } else { 522 debug(2, "Unexpected debug state!"); 523 } 524 } 525 526 proc->debug_state = rdbg.r_state; 527} 528 529int 530linkmap_init(struct Process *proc, target_address_t dyn_addr) 531{ 532 target_address_t dbg_addr = NULL; 533 //struct cb_data data; 534 535 debug(DEBUG_FUNCTION, "linkmap_init()"); 536 fprintf(stderr, "linkmap_init dyn_addr=%p\n", dyn_addr); 537 538 if (find_dynamic_entry_addr(proc, dyn_addr, DT_DEBUG, &dbg_addr) == -1) { 539 debug(2, "Couldn't find debug structure!"); 540 return -1; 541 } 542 543 proc->debug = dbg_addr; 544 545 int status; 546 struct lt_r_debug_64 rdbg; 547 if ((status = load_debug_struct(proc, &rdbg)) < 0) { 548 debug(2, "No debug structure or no memory to allocate one!"); 549 return status; 550 } 551 552 //data.lte = lte; 553 554 void *addr; 555 { 556 struct library_symbol libsym; 557 library_symbol_init(&libsym, (target_address_t)rdbg.r_brk, 558 NULL, 0, LS_TOPLT_NONE); 559 addr = sym2addr(proc, &libsym); 560 library_symbol_destroy(&libsym); 561 } 562 struct breakpoint *rdebug_bp = insert_breakpoint(proc, addr, NULL); 563 static struct bp_callbacks rdebug_callbacks = { 564 .on_hit = rdebug_bp_on_hit, 565 }; 566 rdebug_bp->cbs = &rdebug_callbacks; 567 568 crawl_linkmap(proc, &rdbg); 569 570 return 0; 571} 572 573int 574task_kill (pid_t pid, int sig) 575{ 576 // Taken from GDB 577 int ret; 578 579 errno = 0; 580 ret = syscall (__NR_tkill, pid, sig); 581 return ret; 582} 583