summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2018-02-18 12:14:32 +0800
committerJohn Hodge <tpg@mutabah.net>2018-02-18 12:14:32 +0800
commit8c93e4b31d4d056458d98f14b3abe84528b1ca0c (patch)
tree4f5e263a95d4573f5df012a067c672fdb42078c0
parent08ab5d99ed8b7622440a8a33fed4a2475e5e714d (diff)
downloadmrust-8c93e4b31d4d056458d98f14b3abe84528b1ca0c.tar.gz
Standalone MIRI - Add a function trace wrapper (with indent)
-rw-r--r--tools/standalone_miri/debug.cpp12
-rw-r--r--tools/standalone_miri/debug.hpp42
2 files changed, 54 insertions, 0 deletions
diff --git a/tools/standalone_miri/debug.cpp b/tools/standalone_miri/debug.cpp
index d2cfb63e..415bc5d5 100644
--- a/tools/standalone_miri/debug.cpp
+++ b/tools/standalone_miri/debug.cpp
@@ -1,5 +1,7 @@
#include "debug.hpp"
+unsigned DebugSink::s_indent = 0;
+
DebugSink::DebugSink(::std::ostream& inner):
m_inner(inner)
{
@@ -14,6 +16,8 @@ bool DebugSink::enabled(const char* fcn_name)
}
DebugSink DebugSink::get(const char* fcn_name, const char* file, unsigned line, DebugLevel lvl)
{
+ for(size_t i = s_indent; i--;)
+ ::std::cout << " ";
switch(lvl)
{
case DebugLevel::Trace:
@@ -39,4 +43,12 @@ DebugSink DebugSink::get(const char* fcn_name, const char* file, unsigned line,
break;
}
return DebugSink(::std::cout);
+}
+void DebugSink::inc_indent()
+{
+ s_indent ++;
+}
+void DebugSink::dec_indent()
+{
+ s_indent --;
} \ No newline at end of file
diff --git a/tools/standalone_miri/debug.hpp b/tools/standalone_miri/debug.hpp
index 6102b014..3a420985 100644
--- a/tools/standalone_miri/debug.hpp
+++ b/tools/standalone_miri/debug.hpp
@@ -4,6 +4,7 @@
#pragma once
#include <iostream>
+#include <functional>
enum class DebugLevel {
Trace,
@@ -17,6 +18,7 @@ enum class DebugLevel {
class DebugSink
{
+ static unsigned s_indent;
::std::ostream& m_inner;
DebugSink(::std::ostream& inner);
public:
@@ -27,8 +29,48 @@ public:
static bool enabled(const char* fcn_name);
static DebugSink get(const char* fcn_name, const char* file, unsigned line, DebugLevel lvl);
+
+ static void inc_indent();
+ static void dec_indent();
+};
+template<typename T, typename U>
+class FunctionTrace
+{
+ const char* m_fname;
+ const char* m_file;
+ unsigned m_line;
+ U m_exit;
+public:
+ FunctionTrace(const char* fname, const char* file, unsigned line, T entry, U exit):
+ m_fname(fname),
+ m_file(file),
+ m_line(line),
+ m_exit(exit)
+ {
+ if( DebugSink::enabled(fname) ) {
+ auto s = DebugSink::get(fname, file, line, DebugLevel::Debug);
+ s << "(";
+ (entry)(s);
+ s << ")";
+ DebugSink::inc_indent();
+ }
+ }
+ ~FunctionTrace() {
+ if( DebugSink::enabled(m_fname) ) {
+ DebugSink::dec_indent();
+ auto s = DebugSink::get(m_fname, m_file, m_line, DebugLevel::Debug);
+ s << "(";
+ m_exit(s);
+ s << ")";
+ }
+ }
};
+template<typename T, typename U>
+FunctionTrace<T,U> FunctionTrace_d(const char* fname, const char* file, unsigned line, T entry, U exit) {
+ return FunctionTrace<T,U>(fname, file, line, entry, exit);
+}
+#define TRACE_FUNCTION_R(entry, exit) auto ftg##__LINE__ = FunctionTrace_d(__FUNCTION__,__FILE__,__LINE__,[&](DebugSink& FunctionTrace_ss){FunctionTrace_ss << entry;}, [&](DebugSink& FunctionTrace_ss) {FunctionTrace_ss << exit;} )
#define LOG_TRACE(strm) do { if(DebugSink::enabled(__FUNCTION__)) DebugSink::get(__FUNCTION__,__FILE__,__LINE__,DebugLevel::Trace) << strm; } while(0)
#define LOG_DEBUG(strm) do { if(DebugSink::enabled(__FUNCTION__)) DebugSink::get(__FUNCTION__,__FILE__,__LINE__,DebugLevel::Debug) << strm; } while(0)
#define LOG_ERROR(strm) do { DebugSink::get(__FUNCTION__,__FILE__,__LINE__,DebugLevel::Error) << strm; exit(1); } while(0)