From 3ec3b6a878d9ac505a0bddea4900632cbfadc488 Mon Sep 17 00:00:00 2001 From: "Peter D. Barnes, Jr." Date: Fri, 21 Feb 2014 16:27:43 -0800 Subject: [PATCH] [Bug 1862] NS_LOG="Time=*|prefix_time" causes stack overflow --- RELEASE_NOTES | 1 + src/core/model/attribute-accessor-helper.h | 11 ++ src/core/model/log.cc | 31 +++--- src/core/model/log.h | 117 ++++++++++++++++----- src/core/model/time.cc | 2 +- src/core/model/unix-system-mutex.cc | 2 +- 6 files changed, 124 insertions(+), 40 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index fded98b30..82819c2bb 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -46,6 +46,7 @@ Bugs fixed - Bug 1852 - cairo-wideint-private.h error cannot find definitions for fixed-width integral types - Bug 1853 - NS_LOG_FUNCTION broken on OSX 10.9 - Bug 1855 - SixLowPanNetDevice is not correctly indexed +- Bug 1862 - NS_LOG="Time=*|prefix_time" causes stack overflow Release 3.19 ============= diff --git a/src/core/model/attribute-accessor-helper.h b/src/core/model/attribute-accessor-helper.h index 2f0d75b1c..a95a14cf8 100644 --- a/src/core/model/attribute-accessor-helper.h +++ b/src/core/model/attribute-accessor-helper.h @@ -28,6 +28,7 @@ namespace ns3 { * \ingroup AttributeHelper */ template +inline Ptr MakeAccessorHelper (T1 a1); @@ -35,6 +36,7 @@ MakeAccessorHelper (T1 a1); * \ingroup AttributeHelper */ template +inline Ptr MakeAccessorHelper (T1 a1, T2 a2); @@ -94,6 +96,7 @@ private: }; template +inline Ptr DoMakeAccessorHelperOne (U T::*memberVariable) { @@ -132,6 +135,7 @@ private: } template +inline Ptr DoMakeAccessorHelperOne (U (T::*getter)(void) const) { @@ -163,6 +167,7 @@ private: template +inline Ptr DoMakeAccessorHelperOne (void (T::*setter)(U)) { @@ -199,6 +204,7 @@ private: } template +inline Ptr DoMakeAccessorHelperTwo (void (T::*setter)(U), V (T::*getter)(void) const) @@ -240,6 +246,7 @@ private: } template +inline Ptr DoMakeAccessorHelperTwo (V (T::*getter)(void) const, void (T::*setter)(U)) @@ -248,6 +255,7 @@ DoMakeAccessorHelperTwo (V (T::*getter)(void) const, } template +inline Ptr DoMakeAccessorHelperTwo (bool (T::*setter)(U), V (T::*getter)(void) const) @@ -289,6 +297,7 @@ private: } template +inline Ptr DoMakeAccessorHelperTwo (bool (T::*getter)(void) const, void (T::*setter)(U)) @@ -297,6 +306,7 @@ DoMakeAccessorHelperTwo (bool (T::*getter)(void) const, } template +inline Ptr MakeAccessorHelper (T1 a1) { @@ -304,6 +314,7 @@ MakeAccessorHelper (T1 a1) } template +inline Ptr MakeAccessorHelper (T1 a1, T2 a2) { diff --git a/src/core/model/log.cc b/src/core/model/log.cc index 3ef941de0..7d2d518fb 100644 --- a/src/core/model/log.cc +++ b/src/core/model/log.cc @@ -84,10 +84,11 @@ PrintList::PrintList () } -LogComponent::LogComponent (const std::string & name) - : m_levels (0), m_name (name) +LogComponent::LogComponent (const std::string & name, + const enum LogLevel mask /* = 0 */) + : m_levels (0), m_mask (mask), m_name (name) { - EnvVarCheck (name); + EnvVarCheck (); ComponentList *components = GetComponentList (); for (ComponentListI i = components->begin (); @@ -103,7 +104,7 @@ LogComponent::LogComponent (const std::string & name) } void -LogComponent::EnvVarCheck (const std::string & name) +LogComponent::EnvVarCheck (void) { #ifdef HAVE_GETENV char *envVar = getenv ("NS_LOG"); @@ -112,7 +113,6 @@ LogComponent::EnvVarCheck (const std::string & name) return; } std::string env = envVar; - std::string myName = name; std::string::size_type cur = 0; std::string::size_type next = 0; @@ -125,7 +125,7 @@ LogComponent::EnvVarCheck (const std::string & name) if (equal == std::string::npos) { component = tmp; - if (component == myName || component == "*" || component == "***") + if (component == m_name || component == "*" || component == "***") { int level = LOG_LEVEL_ALL | LOG_PREFIX_ALL; Enable ((enum LogLevel)level); @@ -135,7 +135,7 @@ LogComponent::EnvVarCheck (const std::string & name) else { component = tmp.substr (0, equal); - if (component == myName || component == "*") + if (component == m_name || component == "*") { int level = 0; std::string::size_type cur_lev; @@ -242,7 +242,7 @@ LogComponent::EnvVarCheck (const std::string & name) bool -LogComponent::IsEnabled (enum LogLevel level) const +LogComponent::IsEnabled (const enum LogLevel level) const { // LogComponentEnableEnvVar (); return (level & m_levels) ? 1 : 0; @@ -255,13 +255,19 @@ LogComponent::IsNoneEnabled (void) const } void -LogComponent::Enable (enum LogLevel level) +LogComponent::SetMask (const enum LogLevel level) { - m_levels |= level; + m_mask |= level; } void -LogComponent::Disable (enum LogLevel level) +LogComponent::Enable (const enum LogLevel level) +{ + m_levels |= (level & ~m_mask); +} + +void +LogComponent::Disable (const enum LogLevel level) { m_levels &= ~level; } @@ -272,8 +278,9 @@ LogComponent::Name (void) const return m_name.c_str (); } +/* static */ std::string -LogComponent::GetLevelLabel(const enum LogLevel level) const +LogComponent::GetLevelLabel(const enum LogLevel level) { if (level == LOG_ERROR) { diff --git a/src/core/model/log.h b/src/core/model/log.h index eec04be95..bfb2b3e27 100644 --- a/src/core/model/log.h +++ b/src/core/model/log.h @@ -66,34 +66,34 @@ namespace ns3 { * Logging severity classes and levels. */ enum LogLevel { - LOG_NONE = 0x00000000, // no logging + LOG_NONE = 0x00000000, //!< no logging - LOG_ERROR = 0x00000001, // serious error messages only + LOG_ERROR = 0x00000001, //!< serious error messages only LOG_LEVEL_ERROR = 0x00000001, - LOG_WARN = 0x00000002, // warning messages + LOG_WARN = 0x00000002, //!< warning messages LOG_LEVEL_WARN = 0x00000003, - LOG_DEBUG = 0x00000004, // rare ad-hoc debug messages + LOG_DEBUG = 0x00000004, //!< rare ad-hoc debug messages LOG_LEVEL_DEBUG = 0x00000007, - LOG_INFO = 0x00000008, // informational messages (e.g., banners) + LOG_INFO = 0x00000008, //!< informational messages (e.g., banners) LOG_LEVEL_INFO = 0x0000000f, - LOG_FUNCTION = 0x00000010, // function tracing + LOG_FUNCTION = 0x00000010, //!< function tracing LOG_LEVEL_FUNCTION = 0x0000001f, - LOG_LOGIC = 0x00000020, // control flow tracing within functions + LOG_LOGIC = 0x00000020, //!< control flow tracing within functions LOG_LEVEL_LOGIC = 0x0000003f, - LOG_ALL = 0x0fffffff, // print everything + LOG_ALL = 0x0fffffff, //!< print everything LOG_LEVEL_ALL = LOG_ALL, - LOG_PREFIX_FUNC = 0x80000000, // prefix all trace prints with function - LOG_PREFIX_TIME = 0x40000000, // prefix all trace prints with simulation time - LOG_PREFIX_NODE = 0x20000000, // prefix all trace prints with simulation node - LOG_PREFIX_LEVEL = 0x10000000, // prefix all trace prints with log level (severity) - LOG_PREFIX_ALL = 0xf0000000 // all prefixes + LOG_PREFIX_FUNC = 0x80000000, //!< prefix all trace prints with function + LOG_PREFIX_TIME = 0x40000000, //!< prefix all trace prints with simulation time + LOG_PREFIX_NODE = 0x20000000, //!< prefix all trace prints with simulation node + LOG_PREFIX_LEVEL = 0x10000000, //!< prefix all trace prints with log level (severity) + LOG_PREFIX_ALL = 0xf0000000 //!< all prefixes }; /** @@ -146,7 +146,6 @@ void LogComponentDisableAll (enum LogLevel level); /** * \ingroup logging - * \param name a string * * Define a Log component with a specific name. * @@ -166,11 +165,23 @@ void LogComponentDisableAll (enum LogLevel level); * * Note the closing ';' is not on the same line; this prevents * Doxygen from spuriously warning that the macro invocation is undocumented. - + * + * \param name a string */ #define NS_LOG_COMPONENT_DEFINE(name) \ static ns3::LogComponent g_log = ns3::LogComponent (name) +/** + * \ingroup logging + * + * Define a logging component with a default mask. + * + * \param name a string + * \param mask the default mask + */ +#define NS_LOG_COMPONENT_DEFINE_MASK(name, mask) \ + static ns3::LogComponent g_log = ns3::LogComponent (name, mask) + /** * \ingroup logging * Append the simulation time to a log message. @@ -416,22 +427,76 @@ void LogSetNodePrinter (LogNodePrinter); LogNodePrinter LogGetNodePrinter (void); -class LogComponent { +/** + * \ingroup logging + * + * A single log component configuration. + */ +class LogComponent +{ public: - LogComponent (const std::string & name); - void EnvVarCheck (const std::string & name); - bool IsEnabled (enum LogLevel level) const; + /** + * Constructor + * + * \param [in] name the user-visible name for this component. + */ + LogComponent (const std::string & name, const enum LogLevel mask = LOG_NONE); + /** + * Check if this LogComponent is enabled for \pname{level} + * + * \param [in] level the level to check for. + * \return true if \pname{level} is enabled. + */ + bool IsEnabled (const enum LogLevel level) const; + /** + * Check if all levels are disabled. + * + * \return true if all levels are disabled. + */ bool IsNoneEnabled (void) const; - void Enable (enum LogLevel level); - void Disable (enum LogLevel level); + /** + * Enable this LogComponent at \pname{level} + * + * \param [in] level the LogLevel to enable. + */ + void Enable (const enum LogLevel level); + /** + * Disable logging at \pname{level} for this LogComponent. + * + * \param [in] level the LogLevel to disable. + */ + void Disable (const enum LogLevel level); + /** + * Get the name of this LogComponent. + * + * \return the name of this LogComponent. + */ char const *Name (void) const; - std::string GetLevelLabel(const enum LogLevel level) const; + /** + * Get the string label for the given LogLevel. + * + * \param [in] level the LogLevel to get the label for. + * \return the string label for \pname{level} + */ + static std::string GetLevelLabel(const enum LogLevel level); + /** + * Prevent the enabling of a specific LogLevel. + * + * \param level the LogLevel to block + */ + void SetMask (const enum LogLevel level); private: - int32_t m_levels; - std::string m_name; -}; + /** + * Parse the `NS_LOG` environment variable for options relating to this + * LogComponent. + */ + void EnvVarCheck (void); -class ParameterLogger : public std::ostream + int32_t m_levels; //!< Enabled LogLevels + int32_t m_mask; //!< Blocked LogLevels + std::string m_name; //!< LogComponent name + +}; // class LogComponent /** * \ingroup logging diff --git a/src/core/model/time.cc b/src/core/model/time.cc index 95e237e51..64709db21 100644 --- a/src/core/model/time.cc +++ b/src/core/model/time.cc @@ -32,7 +32,7 @@ #include // showpos #include -NS_LOG_COMPONENT_DEFINE ("Time"); +NS_LOG_COMPONENT_DEFINE_MASK ("Time", ns3::LOG_PREFIX_TIME); namespace ns3 { diff --git a/src/core/model/unix-system-mutex.cc b/src/core/model/unix-system-mutex.cc index 1264cd3f3..2d9a7f5bc 100644 --- a/src/core/model/unix-system-mutex.cc +++ b/src/core/model/unix-system-mutex.cc @@ -27,7 +27,7 @@ #include "log.h" -NS_LOG_COMPONENT_DEFINE ("SystemMutex"); +NS_LOG_COMPONENT_DEFINE_MASK ("SystemMutex", ns3::LOG_PREFIX_TIME); namespace ns3 {