Giacomo Travaglini has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/43165 )
Change subject: misc: Add --debug-queue option to redirect DPRINT to socket
......................................................................
misc: Add --debug-queue option to redirect DPRINT to socket
DPRINTFs are gem5 tracepoints.
At the moment a user willing to trace a specific component (a device or
the instruction trace of a cpu) has two options:
1) Trace to stdout/stderr
2) Trace to a file via --debug-file
Both options are valid but they severely slow down simulation.
The usual solution is to provide --debug-start and --debug-end options
to define Tick based regions of interest.
This works fine but a bit of effort is required to understand which is the
starting/ending tick. This could be done (as an example) by running gem5
with gdb and print the curTick() once a reasonable breakpoint is hit.
Moreover the timing could change when something in the simulation
changes (for example small changes in the software stack, or running the
same piece of software with a different cpu model/configuration).
With this patch I am adding a new "on-demand" debug print mechanism:
a --debug-queue option will store debug prints on a circular buffer.
The circular buffer will dump its content when
a) A connection is established with m5term, which will continuously
print to stdout the buffer content
b) Simulation exits unexpectedly (for a SIGINT=Ctrl-C or a panic, but
not for assertions)
The size of the buffer is controlled via the --debug-queue-size option
Change-Id: I9b72572c610a07570642ed2507f9260fe8d9f828
Signed-off-by: Giacomo Travaglini <[email protected]>
---
M src/base/logging.cc
M src/base/trace.cc
M src/base/trace.hh
M src/python/m5/main.py
M src/python/m5/trace.py
M src/python/pybind11/debug.cc
M src/sim/sim_events.cc
7 files changed, 93 insertions(+), 9 deletions(-)
diff --git a/src/base/logging.cc b/src/base/logging.cc
index b8f20f9..921995f 100644
--- a/src/base/logging.cc
+++ b/src/base/logging.cc
@@ -43,6 +43,7 @@
#include <sstream>
#include "base/hostinfo.hh"
+#include "base/trace.hh"
namespace {
@@ -66,7 +67,8 @@
{
std::stringstream ss;
ccprintf(ss, "Memory Usage: %ld KBytes\n", memUsage());
- NormalLogger::log(loc, s + ss.str());
+ NormalLogger::log(loc, s + ss.str() +
+ Trace::CircularOstream::tryDump());
}
};
diff --git a/src/base/trace.cc b/src/base/trace.cc
index eee6a4d..8648ddf 100644
--- a/src/base/trace.cc
+++ b/src/base/trace.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2019 ARM Limited
+ * Copyright (c) 2014, 2019, 2021 Arm Limited
* All rights reserved
*
* Copyright (c) 2001-2006 The Regents of The University of Michigan
@@ -44,6 +44,7 @@
#include "debug/FmtStackTrace.hh"
#include "debug/FmtTicksOff.hh"
#include "sim/backtrace.hh"
+#include "sim/eventq.hh"
const std::string &name()
{
@@ -166,4 +167,34 @@
}
}
+std::string
+CircularOstream::tryDump()
+{
+ auto str = std::string();
+
+ try {
+ auto& ostream_queue = dynamic_cast<CircularOstream&>(
+ Trace::output());
+
+ // Dump the content of the circular queue
+ str = ostream_queue.dump();
+ } catch (std::bad_cast&) {
+ // We are not employing a circular queue ostream
+ }
+
+ return str;
+}
+
+CircularOstream::CircularOstream(ssize_t tx_size)
+ : std::ostream(this),
+ pipe(3456, getEventQueue(0), "ostream", tx_size)
+{}
+
+int
+CircularOstream::overflow(int c)
+{
+ pipe.sendChar(c);
+ return 0;
+}
+
} // namespace Trace
diff --git a/src/base/trace.hh b/src/base/trace.hh
index 86dec09..af48432 100644
--- a/src/base/trace.hh
+++ b/src/base/trace.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2019 ARM Limited
+ * Copyright (c) 2014, 2019, 2021 Arm Limited
* All rights reserved
*
* Copyright (c) 2001-2006 The Regents of The University of Michigan
@@ -36,6 +36,7 @@
#include <string>
#include <sstream>
+#include "base/circular_pipe.hh"
#include "base/compiler.hh"
#include "base/cprintf.hh"
#include "base/debug.hh"
@@ -116,6 +117,35 @@
std::ostream &getOstream() override { return stream; }
};
+/** Circular ostream. We can pass it to the OstreamLogger
+ * which will use it as output stream. Rather than printing
+ * the stream we pipe it via the CircularPipe
+ */
+class CircularOstream : private std::streambuf, public std::ostream
+{
+ public:
+ explicit CircularOstream(ssize_t cq_size);
+ CircularOstream() = delete;
+ CircularOstream(const CircularOstream &rhs) = delete;
+
+ /**
+ * Try to dump the content of the circular pipe. In case a different
+ * debug ostream is used during simulation (e.g. the default
+ * std::ostream) this static method will return an empty string
+ */
+ static std::string tryDump();
+
+ /**
+ * Dump the content of the circular pipe.
+ */
+ std::string dump() { return pipe.txDump(); }
+
+ private: // streambuf interface
+ int overflow(int c) override;
+
+ CircularPipe pipe;
+};
+
/** Get the current global debug logger. This takes ownership of the given
* logger which should be allocated using 'new' */
Logger *getDebugLogger();
diff --git a/src/python/m5/main.py b/src/python/m5/main.py
index 9342ad0..db92db6 100644
--- a/src/python/m5/main.py
+++ b/src/python/m5/main.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016, 2019 Arm Limited
+# Copyright (c) 2016, 2019, 2021 Arm Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@@ -146,6 +146,10 @@
help="Sets the output file for debug [Default: %default]")
option("--debug-ignore", metavar="EXPR", action='append', split=':',
help="Ignore EXPR sim objects")
+ option("--debug-queue", action="store_true", default=False,
+ help="Redirect debug output to internal circular queue")
+ option("--debug-queue-size", type='int', default=2000,
+ help="Capacity (chars) of the debug circular queue")
option("--remote-gdb-port", type='int', default=7000,
help="Remote gdb base port (set to 0 to disable listening)")
@@ -417,7 +421,10 @@
e = event.create(trace.disable, event.Event.Debug_Enable_Pri)
event.mainq.schedule(e, options.debug_end)
- trace.output(options.debug_file)
+ if options.debug_queue:
+ trace.outputQueue(options.debug_queue_size)
+ else:
+ trace.output(options.debug_file)
for ignore in options.debug_ignore:
_check_tracing()
diff --git a/src/python/m5/trace.py b/src/python/m5/trace.py
index 9603914..1dfcdbf 100644
--- a/src/python/m5/trace.py
+++ b/src/python/m5/trace.py
@@ -25,4 +25,4 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Export native methods to Python
-from _m5.trace import output, ignore, disable, enable
+from _m5.trace import output, outputQueue, ignore, disable, enable
diff --git a/src/python/pybind11/debug.cc b/src/python/pybind11/debug.cc
index a2b5406..e1fc857 100644
--- a/src/python/pybind11/debug.cc
+++ b/src/python/pybind11/debug.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2020 ARM Limited
+ * Copyright (c) 2017, 2020-2021 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -68,6 +68,14 @@
}
static void
+outputQueue(ssize_t queue_size)
+{
+ auto circular_ostream = new Trace::CircularOstream(queue_size);
+
+ Trace::setDebugLogger(new Trace::OstreamLogger(*circular_ostream));
+}
+
+static void
ignore(const char *expr)
{
ObjectMatch ignore(expr);
@@ -121,6 +129,7 @@
py::module_ m_trace = m_native.def_submodule("trace");
m_trace
.def("output", &output)
+ .def("outputQueue", &outputQueue)
.def("ignore", &ignore)
.def("enable", &Trace::enable)
.def("disable", &Trace::disable)
diff --git a/src/sim/sim_events.cc b/src/sim/sim_events.cc
index ba2cda2..2d02ccf 100644
--- a/src/sim/sim_events.cc
+++ b/src/sim/sim_events.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 ARM Limited
+ * Copyright (c) 2013, 2021 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -45,6 +45,7 @@
#include <string>
#include "base/callback.hh"
+#include "base/trace.hh"
#include "sim/eventq.hh"
#include "sim/sim_exit.hh"
#include "sim/stats.hh"
@@ -89,7 +90,11 @@
"exitSimLoop called with a delay and auto serialization. This
is "
"currently unsupported.");
- new GlobalSimLoopExitEvent(when + simQuantum, message, exit_code,
repeat);
+ // Debug stream. Empty if we are not using a CircularOstream
+ std::string dstream = Trace::CircularOstream::tryDump();
+
+ new GlobalSimLoopExitEvent(when + simQuantum, message + dstream,
+ exit_code, repeat);
}
void
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/43165
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I9b72572c610a07570642ed2507f9260fe8d9f828
Gerrit-Change-Number: 43165
Gerrit-PatchSet: 1
Gerrit-Owner: Giacomo Travaglini <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s