#define MAX_TRACE_LEN 100
-/** @brief Model-checker output stream; default to stdout until redirected */
-FILE *model_out = stdout;
+/** @brief Model-checker output file descriptor; default to stdout until redirected */
+int model_out = STDOUT_FILENO;
#define CONFIG_STACKTRACE
/** Print a backtrace of the current program state. */
model_print("\nDumping stack trace (%d frames):\n", size);
- for (i = 0; i < size; i++)
+ for (i = 0;i < size;i++)
model_print("\t%s\n", strings[i]);
free(strings);
-#endif /* CONFIG_STACKTRACE */
-}
-
-void model_print_summary(void)
-{
- model->print_summary();
+#endif /* CONFIG_STACKTRACE */
}
void assert_hook(void)
if (!expr) {
char msg[100];
sprintf(msg, "Program has hit assertion in file %s at line %d\n",
- file, line);
+ file, line);
model->assert_user_bug(msg);
}
}
#ifndef CONFIG_DEBUG
-static int fd_user_out; /**< @brief File descriptor from which to read user program output */
+static int fd_user_out; /**< @brief File descriptor from which to read user program output */
/**
* @brief Setup output redirecting
*
* Redirects user program's stdout to a pipe so that we can dump it
* selectively, when displaying bugs, etc.
- * Also connects a special file 'model_out' directly to stdout, for printing
+ * Also connects a file descriptor 'model_out' directly to stdout, for printing
* data when needed.
*
* The model-checker can selectively choose to print/hide the user program
*
* This function should only be called once.
*/
+char filename[256];
+
void redirect_output()
{
- int fd;
-
/* Save stdout for later use */
- fd = dup(fileno(stdout));
- model_out = fdopen(fd, "w");
-
- /* Redirect program output to a pipe */
- int pipefd[2];
- if (pipe(pipefd) < 0) {
- perror("pipe");
+ model_out = dup(STDOUT_FILENO);
+ if (model_out < 0) {
+ perror("dup");
+ exit(EXIT_FAILURE);
+ }
+ snprintf_(filename, sizeof(filename), "C11FuzzerTmp%d", getpid());
+ fd_user_out = open(filename, O_CREAT | O_TRUNC| O_RDWR, S_IRWXU);
+ if (dup2(fd_user_out, STDOUT_FILENO) < 0) {
+ perror("dup2");
exit(EXIT_FAILURE);
}
- fd = dup2(pipefd[1], fileno(stdout)); // STDOUT_FILENO
- close(pipefd[1]);
- /* Save the "read" side of the pipe for use later */
- fcntl(pipefd[0], F_SETFL, O_NONBLOCK);
- fd_user_out = pipefd[0];
}
/**
void clear_program_output()
{
fflush(stdout);
- char buf[200];
- while (read_to_buf(fd_user_out, buf, sizeof(buf)));
+ close(fd_user_out);
+ unlink(filename);
}
/** @brief Print out any pending program output */
{
char buf[200];
+ model_print("---- BEGIN PROGRAM OUTPUT ----\n");
+
/* Gather all program output */
fflush(stdout);
+ lseek(fd_user_out, 0, SEEK_SET);
/* Read program output pipe and write to (real) stdout */
- int ret;
+ ssize_t ret;
while (1) {
ret = read_to_buf(fd_user_out, buf, sizeof(buf));
if (!ret)
break;
while (ret > 0) {
- int res = fwrite(buf, 1, ret, model_out);
+ ssize_t res = write(model_out, buf, ret);
if (res < 0) {
- errno = ferror(model_out);
- perror("fwrite");
+ perror("write");
exit(EXIT_FAILURE);
}
ret -= res;
}
}
+
+ close(fd_user_out);
+ unlink(filename);
+
+ model_print("---- END PROGRAM OUTPUT ----\n");
}
-#endif /* ! CONFIG_DEBUG */
+#endif /* ! CONFIG_DEBUG */