int main (int argc, char **argv) { if (argc > 1) verbose = 1; if (verbose) printf ("Caching: none\n"); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); doit (); if (verbose) printf ("Caching: global\n"); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); doit (); // UNW_CACHE_PER_THREAD is not yet implemented // if (verbose) // printf ("Caching: per-thread\n"); // unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); // doit (); if (verbose) printf ("SUCCESS\n"); return 0; }
int main (int argc, char **argv) { struct rlimit rlim; rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; setrlimit (RLIMIT_STACK, &rlim); memset (big, 0xaa, sizeof (big)); if (argc > 1) { maxlevel = atol (argv[1]); if (argc > 2) iterations = atol (argv[2]); } measure_init (); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); doit ("no cache "); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); doit ("global cache "); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); doit ("per-thread cache"); return 0; }
int main (int argc, char **argv) { if (argc > 1) verbose = 1; if (verbose) printf ("Caching: none\n"); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); doit (); if (verbose) printf ("Caching: global\n"); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); doit (); if (verbose) printf ("Caching: per-thread\n"); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); doit (); if (nerrors) { fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); exit (-1); } if (verbose) printf ("SUCCESS\n"); return 0; }
struct bt_data *bt_init(pid_t pid) { struct bt_data *btd; btd = malloc(sizeof(struct bt_data)); if (!btd) abort(); btd->as = unw_create_addr_space(&_UPT_accessors, 0); if (!btd->as) abort(); unw_set_caching_policy (btd->as, UNW_CACHE_GLOBAL); btd->ui = _UPT_create(pid); return btd; }
bool trace_init(pid_t pid, ptrace_context *ctx) { ctx->pid = pid; if (!read_cmdline(pid, &ctx->cmdline)) return false; ctx->addr_space = unw_create_addr_space(&_UPT_accessors, __BYTE_ORDER); if (!ctx->addr_space) return false; unw_set_caching_policy(ctx->addr_space, UNW_CACHE_GLOBAL); ctx->unwind_rctx = _UPT_create(ctx->pid); if (!ctx->unwind_rctx) return false; sprintf(ctx->procstat_path, "/proc/%d/stat", pid); return true; }
int main(int argc, char **argv) { int status, pid, pending_sig, optind = 1, state = 1; as = unw_create_addr_space(&_UPT_accessors, 0); if (!as) panic ("unw_create_addr_space() failed"); if (argc == 1) { static char *args[] = {"self", "/bin/ls", "/usr", NULL}; /* automated test case */ argv = args; } else if (argc > 1) while (argv[optind][0] == '-') { if (strcmp(argv[optind], "-v") == 0) ++optind, verbose = 1; else if (strcmp(argv[optind], "-i") == 0) ++optind, trace_mode = INSTRUCTION; /* backtrace at each insn */ else if (strcmp(argv[optind], "-s") == 0) ++optind, trace_mode = SYSCALL; /* backtrace at each syscall */ else if (strcmp(argv[optind], "-t") == 0) /* Execute until raise(SIGUSR1), then backtrace at each insn until raise(SIGUSR2). */ ++optind, trace_mode = TRIGGER; else if (strcmp(argv[optind], "-c") == 0) /* Enable caching of unwind-info. */ ++optind, unw_set_caching_policy(as, UNW_CACHE_GLOBAL); else if (strcmp(argv[optind], "-n") == 0) /* Don't look-up and print symbol names. */ ++optind, print_names = 0; else fprintf(stderr, "unrecognized option: %s\n", argv[optind++]); if (optind >= argc) break; } target_pid = fork(); if (!target_pid) { /* child */ if (!verbose) dup2(open("/dev/null", O_WRONLY), 1); ptrace(PTRACE_TRACEME, 0, 0, 0); if ((argc > 1) && (optind == argc)) { fprintf(stderr, "Need to specify a command line for the child\n"); exit(-1); } execve(argv[optind], argv + optind, environ); _exit(-1); } atexit(target_pid_kill); ui = _UPT_create(target_pid); while (nerrors <= nerrors_max) { pid = wait4(-1, &status, 0, NULL); if (pid == -1) { if (errno == EINTR) continue; panic ("wait4() failed (errno=%d)\n", errno); } pending_sig = 0; if (WIFSIGNALED (status) || WIFEXITED (status) || (WIFSTOPPED (status) && WSTOPSIG (status) != SIGTRAP)) { if (WIFEXITED (status)) { if (WEXITSTATUS (status) != 0) panic ("child's exit status %d\n", WEXITSTATUS(status)); break; } else if (WIFSIGNALED (status)) { if (!killed) panic ("child terminated by signal %d\n", WTERMSIG(status)); break; } else { pending_sig = WSTOPSIG (status); /* Avoid deadlock: */ if (WSTOPSIG (status) == SIGKILL) break; if (trace_mode == TRIGGER) { if (WSTOPSIG (status) == SIGUSR1) state = 0; else if (WSTOPSIG (status) == SIGUSR2) state = 1; } if (WSTOPSIG (status) != SIGUSR1 && WSTOPSIG (status) != SIGUSR2) { static int count = 0; if (count++ > 100) { panic ("Too many child unexpected signals (now %d)\n", WSTOPSIG(status)); killed = 1; } } } } switch (trace_mode) { case TRIGGER: if (state) ptrace(PTRACE_CONT, target_pid, 0, 0); else { do_backtrace(); if (ptrace(PTRACE_SINGLESTEP, target_pid, 0, pending_sig) < 0) { panic ("ptrace(PTRACE_SINGLESTEP) failed (errno=%d)\n", errno); killed = 1; } } break; case SYSCALL: if (!state) do_backtrace(); state ^= 1; ptrace(PTRACE_SYSCALL, target_pid, 0, pending_sig); break; case INSTRUCTION: do_backtrace(); ptrace(PTRACE_SINGLESTEP, target_pid, 0, pending_sig); break; } if (killed) kill(target_pid, SIGKILL); } _UPT_destroy(ui); unw_destroy_addr_space(as); if (nerrors) { printf("FAILURE: detected %d errors\n", nerrors); exit(-1); } if (verbose) printf("SUCCESS\n"); return 0; }