#include #include #include #include #include #include #include #include #undef SYS_stacktrace_setup #define SYS_stacktrace_setup 472 enum { STACKTRACE_REGISTER_SFRAME = 1, STACKTRACE_UNREGISTER_SFRAME, }; #define stacktrace_setup(op, start_addr, length, text_addr, text_length)\ syscall(SYS_stacktrace_setup, op, start_addr, length, text_addr, text_length) static void usage(const char *name) { printf("usage: %s sframe-offset sframe-length\n" "\n",name); exit(-1); } static unsigned long long get_time(void) { struct timeval tv; unsigned long long time; gettimeofday(&tv, NULL); time = tv.tv_sec * 1000000ULL; time += tv.tv_usec; return time; } void do_spin(void) { unsigned long long start = get_time(); /* 2 seconds */ start += 2 * 1000 * 1000; while (get_time() < start) ; } static int dump_self(unsigned long idx, unsigned long *sframe, unsigned long *text, unsigned long *text_len) { FILE *fp; char *line = NULL; size_t size; unsigned long ptr = 0; *text = 0; fp = fopen("/proc/self/maps", "r"); if (!fp) { perror("self"); exit(-1); } while ((!ptr || !*text) && getline(&line, &size, fp) > 0) { unsigned long start, end; char *file; char *perm; int r; int l; r = sscanf(line, "%lx-%lx %ms %*x %*s %*d %ms\n", &start, &end, &perm, &file); if (r != 4) continue; printf("%s", line); // printf("file=%s\n", file); l = strlen(file); for (l--; l > 0; l--) { if (file[l] == '/') { l++; break; } } // r-xp if (!strncmp(file + l, "libc.so", 7)) { if (!ptr) { ptr = start + idx; printf("found sframe libc.so %lx-%lx (%lx)\n", start, end, ptr); printf("VAL=%lx\n", *(unsigned long*)ptr); } if (!*text && !strcmp(perm, "r-xp")) { *text = start; *text_len = end - start; printf("found text libc.so %lx-%lx (%lx)\n", start, end, ptr); } } free(file); free(perm); } free(line); *sframe = ptr; return ptr && *text; } int main (int argc, char **argv) { unsigned long idx; // 0x001d3fc0; unsigned long len; // 0x303f9; unsigned long ptr; unsigned long text; unsigned long text_len; int ret = 0; if (argc < 3) usage(argv[0]); idx = strtoul(argv[1], NULL, 0); len = strtoul(argv[2], NULL, 0); if (!dump_self(idx, &ptr, &text, &text_len)) { fprintf(stderr, "Could not find data"); exit(-1); } ret = stacktrace_setup(STACKTRACE_REGISTER_SFRAME, ptr, len, text, text_len); if (ret < 0) { perror("Registering stacktrace"); exit(-1); } do_spin(); stacktrace_setup(STACKTRACE_UNREGISTER_SFRAME, ptr, len, text, text_len); do_spin(); return 0; }