aboutsummaryrefslogtreecommitdiff
path: root/riscv/log_file.h
diff options
context:
space:
mode:
authorRupert Swarbrick <rswarbrick@gmail.com>2020-03-27 10:25:20 +0000
committerGitHub <noreply@github.com>2020-03-27 03:25:20 -0700
commitbf296ca0643fa445b83d8bd45eefa3fca02d9921 (patch)
tree69222028c8870f885e7207959cafa8a83e4cbfce /riscv/log_file.h
parent66b44bfbedda562a32e4a2cd0716afbf731b69cd (diff)
downloadspike-bf296ca0643fa445b83d8bd45eefa3fca02d9921.zip
spike-bf296ca0643fa445b83d8bd45eefa3fca02d9921.tar.gz
spike-bf296ca0643fa445b83d8bd45eefa3fca02d9921.tar.bz2
Write execution logs to a named log file (#409)
This patch adds a --log argument to spike. If not given, the behaviour is unchanged: messages logging execution of instructions and (if commit logging is enabled) commits go to stderr. If --log=P is given, Spike now writes these messages to a log file at the path P. This is nice, because they are no longer tangled up with other errors and warnings. The code is mostly plumbing: passing a FILE* object through to the functions that were using stderr. I've written a simple "log_file_t" class, which opens a log file if necessary and yields it or stderr.
Diffstat (limited to 'riscv/log_file.h')
-rw-r--r--riscv/log_file.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/riscv/log_file.h b/riscv/log_file.h
new file mode 100644
index 0000000..d039859
--- /dev/null
+++ b/riscv/log_file.h
@@ -0,0 +1,37 @@
+// See LICENSE for license details.
+#ifndef _RISCV_LOGFILE_H
+#define _RISCV_LOGFILE_H
+
+#include <stdio.h>
+#include <memory>
+#include <sstream>
+#include <stdexcept>
+
+// Header-only class wrapping a log file. When constructed with an
+// actual path, it opens the named file for writing. When constructed
+// with the null path, it wraps stderr.
+class log_file_t
+{
+public:
+ log_file_t(const char *path)
+ : wrapped_file (nullptr, &fclose)
+ {
+ if (!path)
+ return;
+
+ wrapped_file.reset(fopen(path, "w"));
+ if (! wrapped_file) {
+ std::ostringstream oss;
+ oss << "Failed to open log file at `" << path << "': "
+ << strerror (errno);
+ throw std::runtime_error(oss.str());
+ }
+ }
+
+ FILE *get() { return wrapped_file ? wrapped_file.get() : stderr; }
+
+private:
+ std::unique_ptr<FILE, decltype(&fclose)> wrapped_file;
+};
+
+#endif