int main(int argc, char **argv) { const char *appdir = fs_appdir(); if (!fs_mkdir(appdir)) { LOG_FATAL("Failed to create app directory %s", appdir); } // load base options from config char config[PATH_MAX] = {0}; snprintf(config, sizeof(config), "%s" PATH_SEPARATOR "config", appdir); options_read(config); // override options from the command line options_parse(&argc, &argv); if (OPTION_help) { options_print_help(); return EXIT_SUCCESS; } if (!exception_handler_install()) { LOG_WARNING("Failed to initialize exception handler"); return EXIT_FAILURE; } struct window *window = win_create(); if (!window) { LOG_WARNING("Failed to initialize window"); return EXIT_FAILURE; } const char *load = argc > 1 ? argv[1] : NULL; if (load && strstr(load, ".trace")) { struct tracer *tracer = tracer_create(window); tracer_run(tracer, load); tracer_destroy(tracer); } else { struct emu *emu = emu_create(window); emu_run(emu, load); emu_destroy(emu); } win_destroy(window); exception_handler_uninstall(); // persist options for next run options_write(config); return EXIT_SUCCESS; }
int main (int argc, char *argv[]) { pid_t pid; int status = 1; struct tracer *tracer = NULL; struct process *process = NULL; if (argc < 2) return 1; pid = fork (); if (pid < 0) { perror ("fork"); return 2; } if (pid == 0) fork_and_trace_child (argv); if (wait_for_stopped (pid, false, &status)) { fprintf (stderr, "child process unexpectedly dead\n"); return 3; } /* When delivering syscall traps, set bit 7 in the signal number (i.e., deliver SIGTRAP | 0x80). This makes it easy for the tracer to tell the difference between normal traps and those caused by a syscall. (PTRACE_O_TRACESYSGOOD may not work on all architectures.) */ if (ptrace (PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) == -1) return 5; status = 1; if (!(tracer = tracer_alloc ())) { fprintf (stderr, "Can not allocate tracer\n"); goto end; } if (!(process = process_alloc (pid))) { fprintf (stderr, "Can not allocate process\n"); goto end; } if (tracer_add_process (tracer, process) == -1) { fprintf (stderr, "Cannot add process to tracer\n"); goto end; } /* process = NULL should be here (!) */ for (;;) { struct user_regs_struct state1; struct user_regs_struct state2; if (wait_for_break (pid, &state1, &status)) break; if (wait_for_break (pid, &state2, &status)) break; trace_syscall (process, &state1, &state2); } process = NULL; status &= 0xff; end: if (process) process_destroy (process); if (tracer) tracer_destroy (tracer); return status; }