/** * main replayer method */ static void start(int option, int argc, char* argv[], char** envp) { pid_t pid; int status, fake_argc; if (option == RECORD) { copy_executable(argv[2]); if (access(__executable, X_OK)) { printf("The specified file '%s' does not exist or is not executable\n", __executable); return; } /* create directory for trace files */ setup_trace_dir(0); /* initialize trace files */ open_trace_files(); init_trace_files(); copy_argv(argc, argv); copy_envp(envp); record_argv_envp(argc, __argv, __envp); close_trace_files(); pid = sys_fork(); /* child process */ if (pid == 0) { sys_start_trace(__executable, __argv, __envp); /* parent process */ } else { child = pid; /* make sure that the child process dies when the master process gets interrupted */ install_signal_handler(); /* sync with the child process */ sys_waitpid(pid, &status); /* configure the child process to get a message upon a thread start, fork(), etc. */ sys_ptrace_setup(pid); /* initialize stuff */ init_libpfm(); /* initialize the trace file here -- we need to record argc and envp */ open_trace_files(); /* register thread at the scheduler and start the HPC */ rec_sched_register_thread(0, pid); /* perform the action recording */ fprintf(stderr, "start recording...\n"); start_recording(); fprintf(stderr, "done recording -- cleaning up\n"); /* cleanup all initialized data-structures */ close_trace_files(); close_libpfm(); } /* replayer code comes here */ } else if (option == REPLAY) { init_environment(argv[2], &fake_argc, __argv, __envp); copy_executable(__argv[0]); if (access(__executable, X_OK)) { printf("The specified file '%s' does not exist or is not executable\n", __executable); return; } pid = sys_fork(); //child process if (pid == 0) { sys_start_trace(__executable, __argv, __envp); /* parent process */ } else { child = pid; /* make sure that the child process dies when the master process gets interrupted */ install_signal_handler(); sys_waitpid(pid, &status); sys_ptrace_setup(pid); /* initialize stuff */ init_libpfm(); rep_sched_init(); /* sets the file pointer to the first trace entry */ read_trace_init(argv[2]); pid_t rec_main_thread = get_recorded_main_thread(); rep_sched_register_thread(pid, rec_main_thread); /* main loop */ replay(); /* thread wants to exit*/ close_libpfm(); read_trace_close(); rep_sched_close(); } } }
ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) { char buf[BUFSIZ]; char test[] = { 23, 8, 68 }; char *version; int show_version = 0; int show_funcs = 0; int show_printk = 0; ssize_t size = -1; int file_bigendian; int host_bigendian; int file_long_size; int file_page_size; struct pevent *pevent; int err; *ppevent = NULL; repipe = __repipe; input_fd = fd; if (do_read(buf, 3) < 0) return -1; if (memcmp(buf, test, 3) != 0) { pr_debug("no trace data in the file"); return -1; } if (do_read(buf, 7) < 0) return -1; if (memcmp(buf, "tracing", 7) != 0) { pr_debug("not a trace file (missing 'tracing' tag)"); return -1; } version = read_string(); if (version == NULL) return -1; if (show_version) printf("version = %s\n", version); free(version); if (do_read(buf, 1) < 0) return -1; file_bigendian = buf[0]; host_bigendian = bigendian(); pevent = read_trace_init(file_bigendian, host_bigendian); if (pevent == NULL) { pr_debug("read_trace_init failed"); goto out; } if (do_read(buf, 1) < 0) goto out; file_long_size = buf[0]; file_page_size = read4(pevent); if (!file_page_size) goto out; pevent_set_long_size(pevent, file_long_size); pevent_set_page_size(pevent, file_page_size); err = read_header_files(pevent); if (err) goto out; err = read_ftrace_files(pevent); if (err) goto out; err = read_event_files(pevent); if (err) goto out; err = read_proc_kallsyms(pevent); if (err) goto out; err = read_ftrace_printk(pevent); if (err) goto out; size = trace_data_size; repipe = false; if (show_funcs) { pevent_print_funcs(pevent); } else if (show_printk) { pevent_print_printk(pevent); } *ppevent = pevent; pevent = NULL; out: if (pevent) pevent_free(pevent); return size; }