diff options
-rw-r--r-- | tools/klee-replay/file-creator.c | 202 | ||||
-rw-r--r-- | tools/klee-replay/klee-replay.c | 52 |
2 files changed, 125 insertions, 129 deletions
diff --git a/tools/klee-replay/file-creator.c b/tools/klee-replay/file-creator.c index 714a1112..b8f9addd 100644 --- a/tools/klee-replay/file-creator.c +++ b/tools/klee-replay/file-creator.c @@ -9,18 +9,17 @@ #include "klee-replay.h" +#include <assert.h> +#include <errno.h> +#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> -#include <errno.h> -#include <sys/types.h> + #include <sys/stat.h> -#include <fcntl.h> -#include <time.h> #include <sys/wait.h> -#include <sys/time.h> -#include <assert.h> #ifdef HAVE_PTY_H #include <pty.h> @@ -34,19 +33,19 @@ #include <termios.h> #endif -static void create_file(int target_fd, - const char *target_name, +static void create_file(int target_fd, + const char *target_name, exe_disk_file_t *dfile, const char *tmpdir); -static void check_file(int index, exe_disk_file_t *file); +static void check_file(int index, exe_disk_file_t *dfile); static void delete_file(const char *path, int recurse); -#define __STDIN -1 -#define __STDOUT -2 +#define __STDIN (-1) +#define __STDOUT (-2) -static int create_link(const char *fname, - exe_disk_file_t *dfile, +static int create_link(const char *fname, + exe_disk_file_t *dfile, const char *tmpdir) { char buf[64]; struct stat64 *s = dfile->stat; @@ -55,17 +54,17 @@ static int create_link(const char *fname, sprintf(buf, "%s.lnk", fname); s->st_mode = (s->st_mode & ~S_IFMT) | S_IFREG; create_file(-1, buf, dfile, tmpdir); - + int res = symlink(buf, fname); if (res < 0) { perror("symlink"); } - + return open(fname, O_RDWR); } -static int create_dir(const char *fname, exe_disk_file_t *dfile, +static int create_dir(const char *fname, exe_disk_file_t *dfile, const char *tmpdir) { int res = mkdir(fname, dfile->stat->st_mode); if (res < 0) { @@ -78,7 +77,7 @@ static int create_dir(const char *fname, exe_disk_file_t *dfile, double getTime() { struct timeval t; gettimeofday(&t, NULL); - + return (double) t.tv_sec + ((double) t.tv_usec / 1000000.0); } @@ -96,7 +95,7 @@ int wait_for_timeout_or_exit(pid_t pid, const char *name, int *statusp) { if (res==pid) return 1; } - + return 0; } @@ -135,9 +134,9 @@ static int create_char_dev(const char *fname, exe_disk_file_t *dfile, ts->c_cc[14] = '\x17'; ts->c_cc[15] = '\x16'; ts->c_cc[16] = '\xff'; - ts->c_cc[17] = '\x0'; - ts->c_cc[18] = '\x0'; - + ts->c_cc[17] = '\x00'; + ts->c_cc[18] = '\x00'; + { char name[1024]; int amaster, aslave; @@ -146,15 +145,15 @@ static int create_char_dev(const char *fname, exe_disk_file_t *dfile, perror("openpty"); exit(1); } - + if (symlink(name, fname) == -1) { fprintf(stderr, "unable to create sym link to tty\n"); perror("symlink"); } - + // pty will not be world writeable - s->st_mode &= ~02; - + s->st_mode &= ~02; + pid_t pid = fork(); if (pid < 0) { perror("fork failed\n"); @@ -165,7 +164,7 @@ static int create_char_dev(const char *fname, exe_disk_file_t *dfile, fprintf(stderr, "note: pty slave: setting raw mode\n"); { struct termios mode; - + int res = tcgetattr(aslave, &mode); assert(!res); mode.c_iflag = IGNBRK; @@ -187,36 +186,36 @@ static int create_char_dev(const char *fname, exe_disk_file_t *dfile, int status; fprintf(stderr, "note: pty master: starting\n"); close(aslave); - + while (pos < flen) { - int res = write(amaster, &contents[pos], flen - pos); - if (res<0) { - if (errno != EINTR) { - fprintf(stderr, "note: pty master: write error\n"); - perror("errno"); - break; - } - } else if (res) { - fprintf(stderr, "note: pty master: wrote: %d (of %d)\n", res, flen); - pos += res; - } + ssize_t res = write(amaster, &contents[pos], flen - pos); + if (res<0) { + if (errno != EINTR) { + fprintf(stderr, "note: pty master: write error\n"); + perror("errno"); + break; + } + } else if (res) { + fprintf(stderr, "note: pty master: wrote: %zd (of %d)\n", res, flen); + pos += res; + } } if (wait_for_timeout_or_exit(pid, "pty master", &status)) goto pty_exit; - + fprintf(stderr, "note: pty master: closing & waiting\n"); close(amaster); while (1) { - int res = waitpid(pid, &status, 0); - if (res < 0) { - if (errno != EINTR) - break; - } else { - break; - } + pid_t res = waitpid(pid, &status, 0); + if (res < 0) { + if (errno != EINTR) + break; + } else { + break; + } } - + pty_exit: close(amaster); fprintf(stderr, "note: pty master: done\n"); @@ -239,11 +238,11 @@ static int create_pipe(const char *fname, exe_disk_file_t *dfile, perror("pipe"); exit(1); } - + pid = fork(); if (pid < 0) { perror("fork"); - exit(1); + exit(1); } else if (pid == 0) { close(fds[1]); return fds[0]; @@ -252,32 +251,32 @@ static int create_pipe(const char *fname, exe_disk_file_t *dfile, int status; fprintf(stderr, "note: pipe master: starting\n"); close(fds[0]); - + while (pos < flen) { int res = write(fds[1], &contents[pos], flen - pos); if (res<0) { - if (errno != EINTR) - break; + if (errno != EINTR) + break; } else if (res) { - pos += res; + pos += res; } } if (wait_for_timeout_or_exit(pid, "pipe master", &status)) goto pipe_exit; - + fprintf(stderr, "note: pipe master: closing & waiting\n"); - close(fds[1]); + close(fds[1]); while (1) { - int res = waitpid(pid, &status, 0); + pid_t res = waitpid(pid, &status, 0); if (res < 0) { - if (errno != EINTR) - break; + if (errno != EINTR) + break; } else { - break; + break; } } - + pipe_exit: close(fds[1]); fprintf(stderr, "note: pipe master: done\n"); @@ -287,44 +286,43 @@ static int create_pipe(const char *fname, exe_disk_file_t *dfile, static int create_reg_file(const char *fname, exe_disk_file_t *dfile, - const char *tmpdir) { + const char *tmpdir) { struct stat64 *s = dfile->stat; char* contents = dfile->contents; unsigned flen = dfile->size; unsigned mode = s->st_mode & 0777; //fprintf(stderr, "Creating regular file\n"); - + // Open in RDWR just in case we have to end up using this fd. if (__exe_env.version == 0 && mode == 0) mode = 0644; - - + int fd = open(fname, O_CREAT | O_RDWR, mode); // int fd = open(fname, O_CREAT | O_WRONLY, s->st_mode&0777); if (fd < 0) { fprintf(stderr, "Cannot create file %s\n", fname); exit(1); } - - int r = write(fd, contents, flen); + + ssize_t r = write(fd, contents, flen); if (r < 0 || (unsigned) r != flen) { fprintf(stderr, "Cannot write file %s\n", fname); exit(1); } - + struct timeval tv[2]; tv[0].tv_sec = s->st_atime; tv[0].tv_usec = 0; tv[1].tv_sec = s->st_mtime; tv[1].tv_usec = 0; futimes(fd, tv); - + // XXX: Now what we should do is reopen a new fd with the correct modes // as they were given to the process. lseek(fd, 0, SEEK_SET); - + return fd; } @@ -345,7 +343,7 @@ static int delete_dir(const char *path, int recurse) { closedir(d); } } - + if (rmdir(path) == -1) { fprintf(stderr, "Cannot create file %s (exists, is dir, can't remove)\n", path); perror("rmdir"); @@ -367,7 +365,7 @@ static void delete_file(const char *path, int recurse) { } static void create_file(int target_fd, - const char *target_name, + const char *target_name, exe_disk_file_t *dfile, const char *tmpdir) { struct stat64 *s = dfile->stat; @@ -392,13 +390,13 @@ static void create_file(int target_fd, if (S_ISLNK(s->st_mode)) { fd = create_link(target, dfile, tmpdir); - } + } else if (S_ISDIR(s->st_mode)) { fd = create_dir(target, dfile, tmpdir); - } + } else if (S_ISCHR(s->st_mode)) { fd = create_char_dev(target, dfile, tmpdir); - } + } else if (S_ISFIFO(s->st_mode) || (target_fd==0 && (s->st_mode & S_IFMT) == 0)) { // XXX hack fd = create_pipe(target, dfile, tmpdir); @@ -442,8 +440,8 @@ void replay_create_files(exe_file_system_t *exe_fs) { strcat(tmpdir, ".temps"); delete_file(tmpdir, 1); - mkdir(tmpdir, 0755); - + mkdir(tmpdir, 0755); + umask(0); for (k=0; k < exe_fs->n_sym_files; k++) { char name[2]; @@ -462,7 +460,7 @@ void replay_create_files(exe_file_system_t *exe_fs) { if (exe_fs->sym_stdout) check_file(__STDOUT, exe_fs->sym_stdout); - + for (k=0; k<exe_fs->n_sym_files; ++k) check_file(k, &exe_fs->sym_files[k]); } @@ -474,64 +472,64 @@ static void check_file(int index, exe_disk_file_t *dfile) { switch (index) { case __STDIN: - strcpy(name, "stdin"); - res = fstat(0, &s); + strcpy(name, "stdin"); + res = fstat(0, &s); break; - case __STDOUT: + case __STDOUT: strcpy(name, "stdout"); res = fstat(1, &s); break; - default: - name[0] = 'A' + index; - name[1] = '\0'; + default: + name[0] = 'A' + index; + name[1] = '\0'; res = stat(name, &s); break; } - + if (res < 0) { fprintf(stderr, "warning: check_file %d: stat failure\n", index); return; } if (s.st_dev != dfile->stat->st_dev) { - fprintf(stderr, "warning: check_file %s: dev mismatch: %d vs %d\n", - name, (int) s.st_dev, (int) dfile->stat->st_dev); + fprintf(stderr, "warning: check_file %s: dev mismatch: %d vs %d\n", + name, (int) s.st_dev, (int) dfile->stat->st_dev); } /* if (s.st_ino != dfile->stat->st_ino) { */ /* fprintf(stderr, "warning: check_file %s: ino mismatch: %d vs %d\n", */ /* name, (int) s.st_ino, (int) dfile->stat->st_ino); */ /* } */ if (s.st_mode != dfile->stat->st_mode) { - fprintf(stderr, "warning: check_file %s: mode mismatch: %#o vs %#o\n", - name, s.st_mode, dfile->stat->st_mode); + fprintf(stderr, "warning: check_file %s: mode mismatch: %#o vs %#o\n", + name, s.st_mode, dfile->stat->st_mode); } if (s.st_nlink != dfile->stat->st_nlink) { - fprintf(stderr, "warning: check_file %s: nlink mismatch: %d vs %d\n", - name, (int) s.st_nlink, (int) dfile->stat->st_nlink); + fprintf(stderr, "warning: check_file %s: nlink mismatch: %d vs %d\n", + name, (int) s.st_nlink, (int) dfile->stat->st_nlink); } if (s.st_uid != dfile->stat->st_uid) { - fprintf(stderr, "warning: check_file %s: uid mismatch: %d vs %d\n", - name, s.st_uid, dfile->stat->st_uid); + fprintf(stderr, "warning: check_file %s: uid mismatch: %d vs %d\n", + name, s.st_uid, dfile->stat->st_uid); } if (s.st_gid != dfile->stat->st_gid) { - fprintf(stderr, "warning: check_file %s: gid mismatch: %d vs %d\n", - name, s.st_gid, dfile->stat->st_gid); + fprintf(stderr, "warning: check_file %s: gid mismatch: %d vs %d\n", + name, s.st_gid, dfile->stat->st_gid); } if (s.st_rdev != dfile->stat->st_rdev) { - fprintf(stderr, "warning: check_file %s: rdev mismatch: %d vs %d\n", - name, (int) s.st_rdev, (int) dfile->stat->st_rdev); + fprintf(stderr, "warning: check_file %s: rdev mismatch: %d vs %d\n", + name, (int) s.st_rdev, (int) dfile->stat->st_rdev); } if (s.st_size != dfile->stat->st_size) { - fprintf(stderr, "warning: check_file %s: size mismatch: %d vs %d\n", - name, (int) s.st_size, (int) dfile->stat->st_size); + fprintf(stderr, "warning: check_file %s: size mismatch: %d vs %d\n", + name, (int) s.st_size, (int) dfile->stat->st_size); } if (s.st_blksize != dfile->stat->st_blksize) { - fprintf(stderr, "warning: check_file %s: blksize mismatch: %d vs %d\n", - name, (int) s.st_blksize, (int) dfile->stat->st_blksize); + fprintf(stderr, "warning: check_file %s: blksize mismatch: %d vs %d\n", + name, (int) s.st_blksize, (int) dfile->stat->st_blksize); } if (s.st_blocks != dfile->stat->st_blocks) { - fprintf(stderr, "warning: check_file %s: blocks mismatch: %d vs %d\n", - name, (int) s.st_blocks, (int) dfile->stat->st_blocks); + fprintf(stderr, "warning: check_file %s: blocks mismatch: %d vs %d\n", + name, (int) s.st_blocks, (int) dfile->stat->st_blocks); } /* if (s.st_atime != dfile->stat->st_atime) { */ /* fprintf(stderr, "warning: check_file %s: atime mismatch: %d vs %d\n", */ diff --git a/tools/klee-replay/klee-replay.c b/tools/klee-replay/klee-replay.c index 150a82e8..d26b67cd 100644 --- a/tools/klee-replay/klee-replay.c +++ b/tools/klee-replay/klee-replay.c @@ -10,16 +10,14 @@ #include "klee-replay.h" #include "klee/Internal/ADT/KTest.h" -#include "klee/Config/config.h" #include <assert.h> +#include <errno.h> +#include <getopt.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <stdint.h> -#include <getopt.h> - -#include <errno.h> #include <time.h> #include <unistd.h> @@ -43,7 +41,7 @@ static KTest* input; static unsigned obj_index; static const char *progname = 0; -static unsigned monitored_pid = 0; +static unsigned monitored_pid = 0; static unsigned monitored_timeout; static char *rootdir = NULL; @@ -101,7 +99,7 @@ static void stop_monitored(int process) { } static void int_handler(int signal) { - fprintf(stderr, "%s: Received signal %d. Killing monitored process(es)\n", + fprintf(stderr, "%s: Received signal %d. Killing monitored process(es)\n", progname, signal); if (monitored_pid) { stop_monitored(monitored_pid); @@ -114,7 +112,7 @@ static void int_handler(int signal) { } } static void timeout_handler(int signal) { - fprintf(stderr, "%s: EXIT STATUS: TIMED OUT (%d seconds)\n", progname, + fprintf(stderr, "%s: EXIT STATUS: TIMED OUT (%d seconds)\n", progname, monitored_timeout); if (monitored_pid) { stop_monitored(monitored_pid); @@ -161,11 +159,11 @@ static inline char *strip_root_dir(char *executable, char *rootdir) { static void run_monitored(char *executable, int argc, char **argv) { int pid; - const char *t = getenv("KLEE_REPLAY_TIMEOUT"); + const char *t = getenv("KLEE_REPLAY_TIMEOUT"); if (!t) - t = "10000000"; + t = "10000000"; monitored_timeout = atoi(t); - + if (monitored_timeout==0) { fprintf(stderr, "ERROR: invalid timeout (%s)\n", t); _exit(1); @@ -174,7 +172,7 @@ static void run_monitored(char *executable, int argc, char **argv) { /* Kill monitored process(es) on SIGINT and SIGTERM */ signal(SIGINT, int_handler); signal(SIGTERM, int_handler); - + signal(SIGALRM, timeout_handler); pid = fork(); if (pid < 0) { @@ -182,7 +180,7 @@ static void run_monitored(char *executable, int argc, char **argv) { _exit(66); } else if (pid == 0) { /* This process actually executes the target program. - * + * * Create a new process group for pid, and the process tree it may spawn. We * do this, because later on we might want to kill pid _and_ all processes * spawned by it and its descendants. @@ -225,7 +223,7 @@ static void run_monitored(char *executable, int argc, char **argv) { perror("waitpid"); _exit(66); } - + /* Just in case, kill the process group of pid. Since we called setpgrp() for pid, this will not kill us, or any of our ancestors */ kill(-pid, SIGKILL); @@ -265,7 +263,7 @@ static void usage(void) { int main(int argc, char** argv) { int prg_argc; - char ** prg_argv; + char ** prg_argv; progname = argv[0]; @@ -281,9 +279,9 @@ int main(int argc, char** argv) { */ if (argc != 3) usage(); - + char* input_fname = optarg; - + input = kTest_fromFile(input_fname); if (!input) { fprintf(stderr, "%s: error: input file %s not valid.\n", progname, @@ -314,7 +312,7 @@ int main(int argc, char** argv) { if (rootdir) ensure_capsyschroot(progname); #endif - + /* rootdir should be a prefix of executable's path. */ if (rootdir && strstr(executable, rootdir) != executable) { fprintf(stderr, "Error: chroot: root dir should be a parent dir of executable.\n"); @@ -333,14 +331,14 @@ int main(int argc, char** argv) { for (idx = optind + 1; idx != argc; ++idx) { char* input_fname = argv[idx]; unsigned i; - + input = kTest_fromFile(input_fname); if (!input) { - fprintf(stderr, "%s: error: input file %s not valid.\n", progname, + fprintf(stderr, "%s: error: input file %s not valid.\n", progname, input_fname); exit(1); } - + obj_index = 0; prg_argc = input->numArgs; prg_argv = input->args; @@ -354,7 +352,7 @@ int main(int argc, char** argv) { for (i=0; i != (unsigned) prg_argc; ++i) { char *s = prg_argv[i]; if (s[0]=='A' && s[1] && !s[2]) s[1] = '\0'; - fprintf(stderr, "\"%s\" ", prg_argv[i]); + fprintf(stderr, "\"%s\" ", prg_argv[i]); } fprintf(stderr, "\n"); @@ -377,7 +375,7 @@ int main(int argc, char** argv) { do { res = waitpid(pid, &status, 0); } while (res < 0 && errno == EINTR); - + if (res < 0) { perror("waitpid"); _exit(66); @@ -471,19 +469,19 @@ int klee_range(int start, int end, const char* name) { if (start+1 == end) return start; else { - klee_make_symbolic(&r, sizeof r, name); + klee_make_symbolic(&r, sizeof r, name); if (r < start || r >= end) { - fprintf(stderr, "klee_range(%d, %d, %s) returned invalid result: %d\n", + fprintf(stderr, "klee_range(%d, %d, %s) returned invalid result: %d\n", start, end, name, r); exit(1); } - + return r; } } -void klee_report_error(const char *file, int line, +void klee_report_error(const char *file, int line, const char *message, const char *suffix) { __emit_error(message); } |