From 4ff5fa567bab2f848146386f2b1d1a3dfed9d0e2 Mon Sep 17 00:00:00 2001 From: "Daniel R. Carvalho" Date: Wed, 13 Jan 2021 20:58:47 -0300 Subject: [PATCH] scons: Separate debug flags from debug-format flags Debug flags are flags that aid with debugging by printing relevant information when enabled. Debug-formatting flags define how the debug flags will print the information. Although a viability, this patch does not support declaring compound format flags. As a side effect, now debug flags and debug-formatting flags are printed in different lists, when using --debug-help. Change-Id: Ieae68745276218cf4e9c1d37d7bf3bd1f19709ae Signed-off-by: Daniel R. Carvalho Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/39076 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/SConscript | 21 ++++++++++++++------- src/base/SConscript | 9 +++++---- src/base/debug.hh | 15 ++++++++++++++- src/base/debug.test.cc | 11 +++++++++++ src/python/m5/debug.py | 9 +++++++-- src/python/pybind11/debug.cc | 4 +++- 6 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/SConscript b/src/SConscript index dc5726080..6637b1f14 100644 --- a/src/SConscript +++ b/src/SConscript @@ -618,20 +618,24 @@ Export('GTest') # Debug Flags # debug_flags = {} -def DebugFlag(name, desc=None): +def DebugFlag(name, desc=None, fmt=False): if name in debug_flags: raise AttributeError("Flag {} already specified".format(name)) - debug_flags[name] = (name, (), desc) + debug_flags[name] = (name, (), desc, fmt) def CompoundFlag(name, flags, desc=None): if name in debug_flags: raise AttributeError("Flag {} already specified".format(name)) compound = tuple(flags) - debug_flags[name] = (name, compound, desc) + debug_flags[name] = (name, compound, desc, False) + +def DebugFormatFlag(name, desc=None): + DebugFlag(name, desc, True) Export('DebugFlag') Export('CompoundFlag') +Export('DebugFormatFlag') ######################################################################## # @@ -1109,11 +1113,14 @@ namespace Debug { ''') for name, flag in sorted(source[0].read().items()): - n, compound, desc = flag + n, compound, desc, fmt = flag assert n == name if not compound: - code('SimpleFlag $name("$name", "$desc");') + if fmt: + code('SimpleFlag $name("$name", "$desc", true);') + else: + code('SimpleFlag $name("$name", "$desc", false);') else: comp_code('CompoundFlag $name("$name", "$desc", {') comp_code.indent() @@ -1132,7 +1139,7 @@ def makeDebugFlagHH(target, source, env): assert(len(target) == 1 and len(source) == 1) val = eval(source[0].get_contents()) - name, compound, desc = val + name, compound, desc, fmt = val code = code_formatter() @@ -1168,7 +1175,7 @@ namespace Debug { code.write(str(target[0])) for name,flag in sorted(debug_flags.items()): - n, compound, desc = flag + n, compound, desc, fmt = flag assert n == name hh_file = 'debug/%s.hh' % name diff --git a/src/base/SConscript b/src/base/SConscript index 204ed3cdb..ff32166f8 100644 --- a/src/base/SConscript +++ b/src/base/SConscript @@ -102,10 +102,6 @@ GTest('chunk_generator.test', 'chunk_generator.test.cc') DebugFlag('Annotate', "State machine annotation debugging") DebugFlag('AnnotateQ', "State machine annotation queue debugging") DebugFlag('AnnotateVerbose', "Dump all state machine annotation details") -DebugFlag('FmtFlag', "Show the --debug-flag that enabled each debug message") -DebugFlag('FmtStackTrace', - "Print a stack trace after every debug message") -DebugFlag('FmtTicksOff', "Don't show tick count on debug messages") DebugFlag('GDBAcc', "Remote debugger accesses") DebugFlag('GDBExtra', "Dump extra information on reads and writes") DebugFlag('GDBMisc', "Breakpoints, traps, watchpoints, etc.") @@ -124,3 +120,8 @@ CompoundFlag('GDBAll', CompoundFlag('AnnotateAll', ['Annotate', 'AnnotateQ', 'AnnotateVerbose'], desc="All Annotation flags") +DebugFormatFlag('FmtFlag', + "Show the --debug-flag that enabled each debug message") +DebugFormatFlag('FmtStackTrace', + "Print a stack trace after every debug message") +DebugFormatFlag('FmtTicksOff', "Don't show tick count on debug messages") diff --git a/src/base/debug.hh b/src/base/debug.hh index 2d463814b..be5fa364f 100644 --- a/src/base/debug.hh +++ b/src/base/debug.hh @@ -81,18 +81,31 @@ class Flag class SimpleFlag : public Flag { protected: + /** Whether this flag changes debug formatting. */ + const bool _isFormat = false; + bool _tracing = false; // tracing is enabled and flag is on bool _enabled = false; // flag enablement status void sync() override { _tracing = _globalEnable && _enabled; } public: - SimpleFlag(const char *name, const char *desc) : Flag(name, desc) {} + SimpleFlag(const char *name, const char *desc, bool is_format=false) + : Flag(name, desc), _isFormat(is_format) + {} bool enabled() const override { return _tracing; } void enable() override { _enabled = true; sync(); } void disable() override { _enabled = false; sync(); } + + /** + * Checks whether this flag is a conventional debug flag, or a flag that + * modifies the way debug information is printed. + * + * @return True if this flag is a debug-formatting flag. + */ + bool isFormat() const { return _isFormat; } }; class CompoundFlag : public Flag diff --git a/src/base/debug.test.cc b/src/base/debug.test.cc index 3f7b2f42d..f995a3376 100644 --- a/src/base/debug.test.cc +++ b/src/base/debug.test.cc @@ -60,6 +60,17 @@ TEST(DebugFlagDeathTest, UniqueNames) EXPECT_EQ(expected, actual); } +/** Test format attribute. */ +TEST(DebugFlagTest, IsFormat) +{ + Debug::SimpleFlag flag_a("FlagIsFormatTestA", "", true); + EXPECT_TRUE(flag_a.isFormat()); + Debug::SimpleFlag flag_b("FlagIsFormatTestB", "", false); + EXPECT_FALSE(flag_b.isFormat()); + Debug::SimpleFlag flag_c("FlagIsFormatTestC", ""); + EXPECT_FALSE(flag_c.isFormat()); +} + /** Test enabling and disabling simple flags, as well as the global enabler. */ TEST(DebugSimpleFlagTest, Enabled) { diff --git a/src/python/m5/debug.py b/src/python/m5/debug.py index 10d0980c2..fbcb62487 100644 --- a/src/python/m5/debug.py +++ b/src/python/m5/debug.py @@ -35,8 +35,8 @@ def help(): sorted_flags = sorted(flags.items(), key=lambda kv: kv[0]) print("Base Flags:") - for name, flag in filter(lambda kv: not isinstance(kv[1], CompoundFlag), - sorted_flags): + for name, flag in filter(lambda kv: isinstance(kv[1], SimpleFlag) + and not kv[1].isFormat, sorted_flags): print(" %s: %s" % (name, flag.desc)) print() print("Compound Flags:") @@ -45,6 +45,11 @@ def help(): print(" %s: %s" % (name, flag.desc)) printList([ c.name for c in flag.kids() ], indent=8) print() + print("Formatting Flags:") + for name, flag in filter(lambda kv: isinstance(kv[1], SimpleFlag) + and kv[1].isFormat, sorted_flags): + print(" %s: %s" % (name, flag.desc)) + print() class AllFlags(Mapping): def __init__(self): diff --git a/src/python/pybind11/debug.cc b/src/python/pybind11/debug.cc index 6ee26551b..a2b5406b0 100644 --- a/src/python/pybind11/debug.cc +++ b/src/python/pybind11/debug.cc @@ -110,7 +110,9 @@ pybind_init_debug(py::module_ &m_native) }) ; - py::class_(m_debug, "SimpleFlag", c_flag); + py::class_(m_debug, "SimpleFlag", c_flag) + .def_property_readonly("isFormat", &Debug::SimpleFlag::isFormat) + ; py::class_(m_debug, "CompoundFlag", c_flag) .def("kids", &Debug::CompoundFlag::kids) ; -- 2.30.2